AWS Keys Leaked to GitHub: The First 60 Minutes and the Clean-Up
A developer accidentally committed long-lived AWS access keys to a public repo. This case walks through the detection, containment, and the permanent fix: short-lived credentials via IAM roles and automated secret scanning.
Security · beginner · 12 min read · 2216 words · By Sandip Das · Published
What this covers
- The Situation
- The Problem
- Constraints
- Options Considered
- The Solution
- Implementation
- Results
- What Went Wrong Along the Way
- Lessons Learned
- Apply It Yourself
Key numbers
| Metric | Before | After |
|---|---|---|
| Long-lived IAM keys in CI pipelines | 23 keys across 18 repos | 0 keys |
| Credential exposure window if leaked | Indefinite until manual rotation | Max 1 hour (STS token TTL) |
| Mean time to detect exposed key | 17 minutes (Trusted Advisor lag) | Under 2 minutes (Gitleaks blocks push) |
| IAM permission scope for CI | AdministratorAccess | 6 specific actions on named ARNs |
| Engineering-hours per key rotation cycle | ~2 hours per key, quarterly | 0 (no keys to rotate) |
Key components
- GitHub OIDC Federation — Replaces long-lived IAM access keys with short-lived STS tokens scoped to a specific repo and branch, eliminating the entire class of leaked-credential risk in CI.
- Gitleaks in CI — Scans every git diff on push and pull request for credential patterns, blocking the pipeline before a secret can reach the remote.
- AWS GuardDuty with EventBridge routing — Provides continuous anomaly detection on CloudTrail and VPC Flow Logs, with findings routed to PagerDuty so they are actually acted on.
- AWS CloudTrail and Athena — Provides the authoritative audit trail for blast-radius analysis during and after an incident.
- Least-Privilege IAM Role Policy — Constrains the deployment role to exactly the six API actions needed — ECR push, ECS update, and specific Secrets Manager ARNs — limiting damage if the role is ever abused.
- Revocation Runbook — A documented, tested checklist that lets any on-call engineer execute the first 30 minutes of response without waiting for the security team.
The Situation
The organisation is a 120-engineer B2B SaaS company running a multi-tenant analytics platform on AWS. The backend is a set of ECS-hosted microservices written in Python and Go, deploying roughly 40 times a week via GitHub Actions. Infrastructure is managed with Terraform. The security team is two people — a security engineer and a part-time compliance lead — neither of whom is embedded in the product squads. The platform processes financial data for mid-market customers, which puts it squarely inside SOC 2 Type II scope.
Like many companies that grew fast, the deployment pipeline had accumulated technical debt. One of the oldest CI workflows still authenticated to AWS using a long-lived IAM access key stored as a GitHub Actions secret. That key had AdministratorAccess. Nobody remembered who created it or why it was that broad.
The rest of this case study — the trade-offs, the scaling numbers and the build prompt — is available to LearnXops members. Create an account or see membership.
Topics: aws, security, iam, secrets-management, github, incident-response
Related case studies
- How a 120-Engineer SaaS Company Replaced Its Corporate VPN with Zero-Trust Access
- How a B2B SaaS Team Contained Prompt Injection Across an AI Agent With Live Tool Access
- How a B2B SaaS Team Cut Supply-Chain Risk by Enforcing SBOMs, Sigstore Signing, and OPA Admission Policies
- How a B2B SaaS Team Eliminated Plaintext Secrets and Cut Credential Exposure Risk by 94%