TTX-03 · Scenario card
Cloud Access Key Leak Tabletop: Public Repo to Billing Spike
A cloud security tabletop exercise: a long-lived access key pushed to a public repository, cryptomining, storage enumeration and a race to rotate. 8 injects.
Leaked cloud credentials are one of the most common ways cloud environments are compromised. A developer commits a configuration file with a long-lived access key, pushes it to a public repository, and within a short time automated scanners run by attackers find it and start using it. The first visible symptom is often not a security alert but a billing anomaly.
This scenario tests your cloud incident-response readiness: how fast you can rotate credentials, whether your logs tell you what the key did, how you scope the blast radius, and whether engineering, security and leadership coordinate. It is aimed at cloud platform, DevOps and security teams, with a short executive segment.
Scenario at a glance
| Threat | Leaked long-lived cloud access key abused for resource hijacking and data access |
| Difficulty | Intermediate |
| Duration | 2.5 hours including a 20-minute hotwash |
| Audience | Cloud/DevOps engineering and security |
| Recommended participants | Cloud platform lead, DevOps/SRE, security/IR lead, the owning application team lead, CISO or head of engineering, privacy/legal (for Module 3), finance contact (optional) |
| Prerequisites | Cloud account structure, IAM policy overview, audit logging configuration (e.g. CloudTrail or equivalent), secrets-management approach |
| MITRE ATT&CK techniques | T1552.001 Credentials In Files, T1078.004 Valid Accounts: Cloud Accounts, T1496 Resource Hijacking, T1530 Data from Cloud Storage |
Exercise objectives
- Demonstrate that the team can identify, deactivate and rotate a leaked credential within a defined time, and knows who is authorised to do it.
- Confirm that audit logs needed to reconstruct the key's activity exist, are retained long enough and can be queried by the responders.
- Scope the blast radius: which permissions the key had, what was accessed or created, and whether persistence was established.
- Decide whether data access constitutes a personal-data breach and who makes that call.
- Identify the preventive controls that failed (secret scanning, long-lived keys, least privilege) and owners for fixing them.
Starting situation
Read this aloud to players:
It is Wednesday, 14:00. Your company runs its customer-facing application in a public cloud, across a production account and several development accounts. Most workloads use roles, but a handful of legacy integrations still use long-lived IAM user access keys.
Last night, a developer on the data team pushed a personal side project to a public code-hosting repository. They were working late to meet a sprint deadline.
Injects timeline
| # | Time | Inject | Delivered to | What players should address |
|---|---|---|---|---|
| 1 | T+00:00 | Cloud provider notification: an access key belonging to IAM user svc-data-export appears to be publicly exposed | Cloud platform lead | Triage, key ownership, immediate action |
| 2 | T+00:15 | Billing alert: projected monthly spend in a rarely used region is many times the normal level | Finance / platform lead | Correlation, severity |
| 3 | T+00:30 | Audit logs show dozens of large GPU instances launched in two regions from an unfamiliar IP range | Security / IR lead | Resource hijacking, containment |
| 4 | T+00:50 | The key belongs to a legacy export job; rotating it will break a nightly customer data export | Application team lead | Business impact vs containment |
| 5 | T+01:30 | Logs show ListBuckets and GetObject calls against a bucket containing customer export files | Security / IR lead | Data access, scope |
| 6 | T+02:30 | A new IAM user with an attached administrator policy was created using the leaked key | Security / platform | Persistence, full scope |
| 7 | T+04:00 | Legal asks: "Did they take customer data? I need a yes or no today." | IR lead → legal / privacy | Evidence, uncertainty, notification decision |
| 8 | T+24:00 | Head of engineering asks for a plan to make sure this cannot happen again | Engineering leadership | Root cause, preventive controls |
Module 1 — Exposure and first response (T+00:00 to T+00:50)
Inject 1. An automated notification arrives from the cloud provider: an access key for IAM user svc-data-export in the production account has been found in a public repository. The notification includes a link to the commit. The key ID shown is AKIAIOSFODNN7EXAMPLE (fictional).
Inject 2. A budget alert fires: forecast spend in a region you do not normally use has jumped far above the monthly budget in the last few hours.
Inject 3. The audit logs show RunInstances calls from an IP range you don't recognise, launching dozens of large GPU instances in two regions. Several have a user-data script that downloads a cryptocurrency miner.
Inject 4. The application team lead says: "That key is used by the nightly customer export. If you rotate it without updating the job, customers don't get their files tomorrow and we breach an SLA."
Discussion questions:
- Who owns
svc-data-export, and how do you find out quickly? Is there an inventory of long-lived keys? - Who is authorised to deactivate a production credential without waiting for the owning team?
- Deactivate, rotate or delete? What are the consequences of each for the investigation and the export job?
- How do you stop the running instances? Do you terminate them or snapshot first for evidence?
- At what point is this a security incident rather than an operational issue? Who declares it?
Module 2 — Scoping the blast radius (T+01:30 to T+02:30)
Inject 5. Further log review shows the key was used to list buckets and read objects from a storage bucket holding customer export files: CSV files with names, email addresses and order histories.
Inject 6. The logs also show CreateUser, AttachUserPolicy (administrator access) and CreateAccessKey calls. A new IAM user named to look like a monitoring service now exists.
Discussion questions:
- Do you have data-event logging (object-level reads) enabled for that bucket? If not, what can you still prove?
- What else might an attacker with administrator access have done? Where do you look: new roles, trust policies, access keys, compute, functions, network changes?
- Should you consider the whole account compromised? What does that mean for containment?
- How do you check whether the same key, or the new admin user, was used against other accounts in your organisation?
- Who talks to the cloud provider's support, and what can they help with?
Module 3 — Data, disclosure and prevention (T+04:00 to T+24:00)
Inject 7. General counsel joins: "I need to know today whether customer personal data was taken. If yes, we may have notification obligations."
Inject 8. The next day, the head of engineering asks the platform and security leads for a plan so this "cannot happen again", to present to the executive team.
Discussion questions:
- How do you express uncertainty to legal? What is the difference between "accessed", "exfiltrated" and "no evidence either way"?
- Which regulatory or contractual clocks might apply? (See the data breach notification scenario.)
- Do you tell the developer? How do you handle the human side without blame?
- Which preventive controls would have stopped this: secret scanning and push protection, no long-lived keys, least-privilege policies, alerts on unusual regions or services?
- How do you handle the cloud bill for the mining activity? Who contacts the provider?
Discussion questions
- Speed: How long, in exercise time, from notification to key deactivation? What slowed it?
- Authority: Can security deactivate a production credential over an application team's objection?
- Visibility: Which log sources were missing or not retained long enough?
- Scope: How do you gain confidence that all attacker persistence has been removed?
- Prevention: Which long-lived credentials remain in your environment today, and who owns retiring them?
Curveballs / optional injects
- The developer's repository was forked before it was made private: the key is still out there even after the repository is deleted.
- The provider temporarily restricts your account because of suspected abuse, affecting production.
- A second key from the same repository gives access to a SaaS analytics platform.
Facilitator notes
Expected decisions. Deactivate the key immediately, accepting the export job impact and communicating it; terminate or quarantine attacker compute after capturing what is needed; treat the account as potentially fully compromised once the admin user appears; hunt for persistence systematically; give legal a clear statement of what is known, unknown and being done to find out.
Common pitfalls.
- Delaying deactivation to avoid breaking the export job.
- Deleting the leaked key and the attacker's user before capturing evidence of what they did.
- Assuming the incident is only about cost, missing the storage access and persistence.
- Focusing on the developer's mistake instead of the systemic issue: long-lived keys with broad permissions and no secret scanning.
- Only rotating the leaked key and forgetting the access key the attacker created.
Adapting the audience. For executives, compress Modules 1 and 2 into a briefing and focus on inject 7 and on funding the preventive plan. For engineers, add hands-on style prompts: which exact queries you would run against your logs, and how you would verify every IAM change in the window.
Evaluating the exercise
| Capability | What good looks like | Red flags |
|---|---|---|
| Credential response | Key deactivated within minutes by an authorised responder; rotation plan for dependent job | Waiting for owner approval; key left active |
| Logging and visibility | Management and data events available and queried quickly | Object-level logs off; short retention |
| Scoping | Systematic review of IAM changes, compute, storage, other accounts | Scope limited to the obvious |
| Persistence removal | Attacker user, keys and any roles removed and verified | Attacker-created key missed |
| Legal interface | Clear known/unknown statement; decision owner for notification | "We think it's fine" without evidence |
| Prevention | Owners and dates for secret scanning, key retirement, least privilege | Fix limited to "train developers" |
Related
Frequently asked questions
Is this scenario specific to AWS?
The artifacts use AWS terminology because long-lived IAM user access keys are a well-known risk there, but the scenario applies to any cloud: Azure service principal secrets, Google Cloud service account keys and API tokens for SaaS platforms follow the same pattern. Replace the service names and log sources with your provider's equivalents.
What is the first thing to do when a cloud access key is leaked?
Deactivate or rotate the key immediately, then investigate. Deactivating stops further abuse; investigation uses the provider's audit logs, which remain available. Deleting the key outright can make some investigations harder, so many teams deactivate first, then delete once the review is done.
How do we prevent access key leaks in the first place?
Avoid long-lived keys: use short-lived credentials through workload identity, federation and role assumption. Add secret scanning to repositories and CI pipelines, enable push protection where available, and alert on key usage from unexpected locations or services.