Projects
Each write-up covers the problem, what I built, how I tested it and what I learned. Most of them include something I got wrong.
Professional work
Case studies from my jobs. Employers and internal details are left out.
The lab
Everything runs on one mini PC at home. The story is a fake shoe company that gets attacked. My detections should catch the attack, and the agent helps me investigate it. The agent can read data and suggest what to do. It has no tools that change anything; actions that would need my approval are designed but not built yet.
Done so far:
- An Okta directory for the fake company, with 30 users in 8 departments and 13 groups, all managed in Terraform.
- Okta's audit log streams into Elastic. Every hour a separate check confirms each event arrived, matching by event ID.
- Detections written as code, with test cases that run on every pull request: failed Okta sign-ins, SSH failures and sudo as another user are live. An MFA push fatigue rule is written and tested, but not turned on yet.
- Nightly snapshots of the SIEM, with a daily check that emails me if a backup fails or the check stops reporting.
- An AI triage agent that checks for new alerts every 5 minutes, investigates with read-only tools and posts a verdict to Slack. It's capped at 15 tool calls per run. Its tests assume the model obeys injected text, then check that code rejects what it asks for.
- IP addresses, places and outside email addresses leave the agent's tools as stand-ins. A separate check emails me if the agent stops, a run fails or a key is about to expire.
Write-ups
-
From identity attack to investigated alert
One password-guessing test followed end to end: Okta, Elastic, a detection, AI triage with personal data kept out, and a verdict in Slack. Six steps ran live; the approval step is designed, not built.
-
Keeping personal data out of an AI triage agent
The agent sends log data to a hosted model and to Slack. A deny list leaked twice, so every address, place and outside email now leaves its tools as a stand-in.
-
An MFA fatigue detection, and the test data I guessed wrong
A Sigma rule, an Elastic threshold rule and test cases that run in CI. A real push showed Okta logs a denial under a different event than my test data used.
-
Knowing when the triage agent stops
A separate read-only check that catches a stopped timer, a failed run and a key about to expire, with an outside dead man's switch for when nothing reports at all.
-
Okta in Terraform, and a detection I tested both ways
A fake company's Okta directory in Terraform, its audit log in Elastic, and a failed sign-in rule written in Sigma. I tested when it fires and when it stays quiet.
-
Missing logs that weren't missing
A log line said security events were being dropped. I built a check to measure it, and the results disproved my own root cause.
-
Read-only monitoring and backup alerts
A monitoring role tested by what it's refused, and backup checks that email me on a failure or when they stop reporting.