Ekene Eche
← All projects
Completed

Cloud Detection Pipeline

An AWS threat detection pipeline that turns CloudTrail logs into queryable data, runs six MITRE ATT&CK detections every 15 minutes, alerts in Slack, and attacks itself on a schedule to prove the detections still work.

View on GitHub

Goal

Build the kind of detection pipeline a cloud security team runs in production: collect every account action, make it searchable, alert on risky behavior quickly, and continuously prove the alerts still fire.

Architecture in four layers: collect and process, detect and respond, validate and monitor, build and deploy.
Four layers: collect and process, detect and respond, validate and monitor, and build and deploy.

Results

Collect and process

A dedicated CloudTrail trail records management events from every region into an encrypted, versioned, private S3 bucket with signed hourly digests. Each new log file triggers a Lambda that validates events, quarantines bad records, removes duplicates, converts times to UTC, and writes Parquet partitioned by day and region. Failures land in an SQS queue. Glue and Athena make the data queryable with SQL under a 10 MiB scan cap per query.

Detect and respond

Every 15 minutes a scheduled Lambda runs all six rules in Athena and posts each new finding to Slack exactly once, with severity, MITRE technique, and a runbook link. A DynamoDB table records what was already sent, so overlapping runs never duplicate an alert, and a failed Slack post is retried on the next run. The Slack webhook lives in an encrypted SSM parameter and never enters code or Terraform state.

A read only findings API (API Gateway and Lambda) requires signed IAM credentials on every route and passes user input to Athena only as query parameters.

Validate and monitor

Every six hours an attack simulator performs one harmless, reversible action on canary resources (a user with no permissions, an empty bucket, or a brief pause of the trail) and always restores the original setting. Those actions land in CloudTrail like real ones, and a daily scorecard reports what was caught, missed, and how fast. Eight CloudWatch alarms watch the pipeline itself for errors, stuck queues, and silence.

Slack alert for a simulated CloudTrail StopLogging event, with the account ID redacted.
A simulated StopLogging event reached Slack about 10 minutes after it happened. Account ID redacted.
Slack messages from the pipeline health alarms.
Pipeline health alarms reporting to the same channel after deployment.

Build and deploy

All infrastructure is defined in ten Terraform modules with remote state and locking in S3. Pull requests run tests and a read only Terraform plan. Pushes to main plan again, wait for my approval in a protected environment, then apply only if the changes match the plan I approved. GitHub gets one hour AWS credentials through OIDC, trusted only for this repository by its numeric IDs, so no AWS keys are stored anywhere.

What I learned