An infrastructure as code platform holds the credentials that create, change and destroy your cloud estate, so whoever controls it can rewrite production while every change looks like a normal deployment. This guide is an incident response playbook for the class of tool that plans and applies infrastructure code: the orchestration service or self-hosted controller, its runners or workers, the state backend, the module and provider sources it pulls, and the cloud roles it assumes. It is vendor-neutral and written for cloud security, platform engineering and incident response teams. It covers how the compromise shows up, the first triage questions, containment in priority order, credential rotation, a clean rebuild and the evidence to keep. Hardening the platform before an incident is covered in Securing the infrastructure as code platform itself; this page starts when something has already gone wrong.
Key takeaways
- Assume every credential the platform could reach is exposed. That means cloud deployment roles, provider tokens, variables marked sensitive, the state backend key, version control tokens and any secrets written into state.
- State is both evidence and loot. State files record the real shape of your estate and often hold secret values in plain text, so copy them for forensics before anyone runs another plan or apply.
- Freeze applies before you rotate. If runs keep executing while you rotate credentials, the attacker's pipeline may simply pick up the new ones.
- Drift is your best detector. A full plan against a known-good commit, run from a clean environment, shows what was changed outside the code, and cloud audit logs show who did it.
- Rebuild trust, not just servers. Recreate runners from clean images, re-establish federation trust with narrower conditions, pin modules and providers to verified versions, and only then lift the freeze.
Why an IaC platform compromise is different
An infrastructure as code platform is a privileged non-human identity hub. It typically assumes one or more cloud roles with rights to create networks, identities and data stores, reads and writes a state backend, pulls code from version control, downloads modules and provider plugins from registries, and runs that code on runners that may sit inside your network. NSA and CISA, in Defending Continuous Integration/Continuous Delivery (CI/CD) Environments, list injected infrastructure as code as one way an attacker can poison the pipeline, alongside modified pipeline configuration and malicious dependencies, and warn against hardcoding secrets in IaC templates. The OWASP Top 10 CI/CD Security Risks describe the same pattern from the defender's side: code that runs in a pipeline gets the full permissions of that pipeline stage (CICD-SEC-5, Insufficient Pipeline-Based Access Controls).
Three properties make the incident hard. First, malicious changes arrive through the same identity and change path as legitimate ones, so cloud logs show the deployment role doing what it always does. Second, a single apply can touch hundreds of resources across accounts, and a destroy can remove them. Third, the state file is a map of the estate: resource IDs, endpoints, and in many tools the values of generated passwords, keys and connection strings. See the Infrastructure as Code Security Guide for the wider control set.
How the compromise shows up
Most incidents are spotted through one of the signals below. Each maps to ATT&CK techniques that help you search for related activity.
| Signal | What it usually means | ATT&CK |
|---|---|---|
| Applies or runs outside normal change windows, or triggered from an unexpected branch, workspace or user | Stolen platform user or API token, or a poisoned repository | T1078.004 Cloud Accounts |
| New identities, access keys or role trust entries created by the deployment role | Attacker adding persistence through the pipeline | T1098.001 Additional Cloud Credentials, T1136.003 Cloud Account |
| Unexpected compute, often large instance types in unused regions | Cryptomining using the platform's rights | T1496 Resource Hijacking, T1578 Modify Cloud Compute Infrastructure |
| State backend read from an unknown principal or network, or state downloaded through the platform API | Harvesting secrets and estate layout | T1530 Data from Cloud Storage, T1552.001 Credentials In Files |
| Security groups, firewall rules, logging or storage policies loosened in a change no one recognises | Opening a path in or switching off visibility | T1578 Modify Cloud Compute Infrastructure |
| Module or provider source changed, or a new version pulled outside the normal update process | Supply chain injection into the IaC code path | T1199 Trusted Relationship |
| Snapshot sharing or data copied to an external account | Exfiltration using deployment rights | T1537 Transfer Data to Cloud Account |
| Mass resource deletion through a destroy or a changed resource count | Sabotage or extortion | T1485 Data Destruction |
| Vendor advisory that the hosted platform itself was breached | Provider-side compromise; every stored secret must be treated as read | T1199 Trusted Relationship |
Triage: the first hour
NIST SP 800-61 Rev. 3 frames incident response as part of risk management under CSF 2.0, with incident analysis (RS.AN) and mitigation (RS.MI) running in parallel. For this tool class, answer these questions before you change anything:
- Which entry point? A platform user account, a platform API token, a version control token, a runner host, a module or provider source, or the hosted service itself. The answer decides what you rotate first.
- Which cloud roles and accounts could the platform assume? List every role, subscription, project and account linked to any workspace, including roles used only for rare jobs such as account bootstrapping.
- What did runs actually do? Export the run history, plan outputs and apply logs for the exposure window. Compare each apply with a reviewed commit.
- Who read the state? Pull the state backend's access logs and the platform's audit log for state downloads and version history.
- Are runners shared? If runners serve several teams or sensitivity levels, the blast radius includes every workspace those runners executed.
- Is the change still running? Look for scheduled or queued runs and webhooks that will trigger new applies.
Decision: the incident lead sets severity. Treat it as critical if any production apply was not traceable to a reviewed commit, if new identities were created, or if state containing secrets was read by an unknown principal.
Containment in priority order
- Preserve evidence first, quickly. Copy every state version for affected workspaces, the run and plan logs, the platform audit log, runner disks or images, and the cloud audit logs for the deployment roles. Hash them and store them read-only outside the affected accounts. See the Evidence Handling and Chain of Custody Guide.
- Freeze runs. Disable auto-apply, pause or lock workspaces, cancel queued runs, and disable version control webhooks or triggers so a push cannot start a new apply. On self-hosted controllers, stop the scheduler.
- Cut the cloud trust. At the cloud side, not in the platform, suspend or narrow the trust policy that lets the platform assume deployment roles, and revoke active role sessions. Disable any long-lived access keys the platform held. Doing this in the cloud works even if the platform is fully attacker-controlled.
- Isolate runners. Take self-hosted runners off the network, keep their disks, and block their egress except to your evidence store. Hosted runners: disable the pool or agent registration tokens.
- Lock platform accounts and tokens. Revoke all user, team and organisation API tokens, end sessions, and require phishing-resistant MFA before anyone gets access back.
- Protect the state backend. Restrict the bucket or database to break-glass principals, turn on object versioning if it was off, and enable deletion protection so an attacker cannot roll state back or remove it.
- Look for attacker persistence in the cloud. Search for identities, keys, role trust changes, federation providers and cross-account shares created during the window. The Cloud Credential Compromise Playbook covers this cloud-side hunt in depth.
Credential rotation: what to rotate and in what order
The OWASP CI/CD Top 10 (CICD-SEC-6, Insufficient Credential Hygiene) notes that pipeline credentials such as deploy keys are often left unrotated for years because teams fear breaking deployments. That fear becomes the main delay in an incident, so agree the order in advance.
| Order | Credential | Action | Check afterwards |
|---|---|---|---|
| 1 | Cloud deployment roles and keys | Revoke sessions; delete static keys; re-create federation trust with tighter subject conditions (organisation, workspace, run phase) | Role assumptions from anything other than the rebuilt platform |
| 2 | Secrets found in state | Rotate every database password, generated key, certificate private key and connection string that state held, at the issuing system | Use of old values in each system's own logs |
| 3 | Sensitive workspace variables | Rotate at source; never just re-enter the same value | Variables still holding static cloud keys |
| 4 | Version control tokens and deploy keys | Revoke and reissue with read-only scope where the platform only needs to read | Pushes or new keys created with the old token |
| 5 | Platform API and agent tokens | Revoke all; reissue per team with expiry | API calls using revoked tokens |
| 6 | State backend encryption keys and access | Rotate keys; re-encrypt state; restrict readers to the platform role and break-glass | State reads by other principals |
| 7 | Private module and provider registry tokens and signing keys | Rotate; re-sign trusted versions | Publishes during the window |
Rotating secrets found in state is the step most often missed, because nobody owns them as "platform credentials". The Codecov breach showed the cost of a tool that could read pipeline environment variables: every customer had to work out which secrets their builds had exposed. See Credential Rotation at Scale for running rotation across many owners.
Eradication and clean rebuild
- Establish a known-good commit. For each affected repository, find the last commit that was reviewed before the exposure window. Diff everything after it, including module sources, provider version constraints, lock files and pipeline definitions.
- Rebuild the platform's trust anchors. Recreate runners from clean, current images; re-register them with new tokens; give each sensitivity level its own runner pool, as CICD-SEC-5 recommends.
- Pin and verify dependencies. Pin modules to commit hashes or verified versions and keep dependency lock files with checksums under review, so a changed upstream cannot slip in.
- Reconcile the estate. From the rebuilt platform, run a plan against the known-good commit for every workspace. Investigate every difference: some will be attacker changes, some will be legitimate emergency fixes made by hand.
- Repair, then import. Remove attacker resources through code where possible. For resources changed outside code, decide per item whether to revert, re-import or destroy. Never accept a plan that destroys data stores without a recorded decision.
- Check the cloud from outside the platform. A rebuilt platform only sees what is in state. Use cloud inventory and the audit logs to find resources the attacker created outside state.
Rollback: keep the preserved state versions. If reconciliation goes wrong, you can restore the last trusted state version to the backend and replan, rather than guessing what existed.
Recovery and lifting the freeze
Lift the freeze in rings. Start with non-production workspaces, then low-risk production, then identity, network and data workspaces. Require a second reviewer on every apply until the post-incident review closes, matching the NSA and CISA two-person review recommendation. Watch for role assumptions, state reads and applies that do not match an approved run.
| Option | When to choose it | Trade-off |
|---|---|---|
| Rebuild the same platform in place | Entry was a token or account; no evidence of controller or provider-side compromise | Fastest; relies on your confidence in the controller host |
| Rebuild on a new controller, migrate state | Self-hosted controller or runner hosts were accessed | Slower; removes host-level persistence |
| Temporary manual change process | Hosted provider breach with unclear scope | High toil and drift risk; keep it short and logged |
| Move to short-lived federation only | Static cloud keys were stored in the platform | Needs cloud-side trust work; removes the most valuable loot for next time |
Small organisations with one platform and a handful of workspaces can often rebuild in place in a day. Large organisations with many tenants should rebuild per business unit and prioritise workspaces that manage identity and network foundations. The CircleCI breach shows the hosted-provider case: the provider told customers to rotate every secret stored on the platform, which is only quick if you already know what those secrets are.
Evidence to preserve and notification triggers
- Platform: audit log, run and plan history, workspace variable change history (values excluded), token creation and use, webhook configuration.
- State: every state version and the backend's access and object version logs.
- Cloud: control plane audit logs for all deployment roles, federation trust policy history, and identity creation events. See the Cloud Forensics Guide.
- Runners: disk images, process and network telemetry, cached modules and plugins.
- Version control: commit, review and force-push history for IaC repositories.
Notification depends on what the attacker reached. If personal data was accessed or exposed, GDPR Article 33 requires the controller to notify the supervisory authority without undue delay and, where feasible, within 72 hours of becoming aware, unless the breach is unlikely to result in a risk to individuals; Article 34 requires telling individuals when the risk is likely to be high. Entities in scope of NIS2 must send an early warning within 24 hours and an incident notification within 72 hours of becoming aware of a significant incident (Article 23(4)). Use the Data Breach Notification Checklist for other regimes.
Detection and measurement after the incident
- Alert on: role assumptions by the deployment role from any source other than the platform's expected identity; applies without a linked reviewed commit; state reads by any principal other than the platform role; new token creation; module source or provider version changes outside dependency updates.
- Metrics: percentage of workspaces using short-lived federation instead of static keys (target 100); number of secret values present in state (target falling to zero); median time to freeze all runs during an exercise; percentage of applies with a second reviewer; drift findings per month; age of the oldest platform token.
Common failure patterns
- Rotating before freezing. New credentials land in a platform the attacker still controls, and the next run picks them up.
- Forgetting state secrets. Teams rotate the deployment role but leave database passwords and keys that sat in state for years.
- Trusting the platform to report on itself. Run history from a compromised controller can be edited; cloud audit logs and backend access logs are the independent record.
- Re-creating the same broad trust. Rebuilding federation with the old wide subject conditions invites a repeat. See IaC identity policy checks.
- Accepting a destructive plan to "get back to code". Reconciliation that deletes data stores without a decision turns an intrusion into data loss.
- Shared runners. One poisoned workspace on a shared runner exposes every workspace that ran there.
Framework mapping
| Activity | NIST CSF 2.0 | NIST SP 800-53 Rev. 5 |
|---|---|---|
| Declare, triage and manage the incident | RS.MA Incident Management, RS.AN Incident Analysis | IR-4 Incident Handling, IR-5 Incident Monitoring |
| Freeze runs, cut trust, rotate credentials | RS.MI Incident Mitigation | IA-5 Authenticator Management, AC-6 Least Privilege |
| Reconcile against known-good code | RC.RP Incident Recovery Plan Execution | CM-2 Baseline Configuration, CM-3 Configuration Change Control, CP-10 System Recovery and Reconstitution |
| Restrict who can change the platform | PR.AA Identity Management, Authentication, and Access Control | CM-5 Access Restrictions for Change |
| Protect and review logs | DE.CM Continuous Monitoring | AU-6 Audit Record Review, Analysis, and Reporting, AU-9 Protection of Audit Information |
| Verify modules and providers | ID.AM Asset Management | SI-7 Software, Firmware, and Information Integrity |
| Report the incident | RS.MA Incident Management | IR-6 Incident Reporting |
Practitioner checklist
- Keep a current list of every cloud role, account and secret each workspace can reach.
- Document the exact steps to freeze all runs and test them in an exercise.
- Make sure you can cut the platform's cloud trust from the cloud side without the platform.
- Ship platform audit logs and state backend access logs to a store the platform cannot write to.
- Find and remove secret values from state, and plan rotation for those that must stay.
- Replace static cloud keys in the platform with short-lived federation and narrow subject conditions.
- Separate runners by sensitivity and rebuild them from clean images on a schedule.
- Pin modules and providers and review lock file changes like code.
- Rehearse a reconciliation plan against a known-good commit at least once a year.
Standards and references
- NIST: SP 800-61 Rev. 3, Incident Response Recommendations and Considerations for Cybersecurity Risk Management
- NSA and CISA: Defending Continuous Integration/Continuous Delivery (CI/CD) Environments
- NIST: SP 800-204D, Strategies for the Integration of Software Supply Chain Security in DevSecOps CI/CD Pipelines
- OWASP: Top 10 CI/CD Security Risks
- NIST: SP 800-53 Rev. 5
- NIST: Cybersecurity Framework 2.0
- EUR-Lex: Regulation (EU) 2016/679 (GDPR)
- EUR-Lex: Directive (EU) 2022/2555 (NIS2)
Related NHI Mgmt Group resources: Securing the infrastructure as code platform itself · CI/CD Pipeline Compromise Playbook · Cloud Credential Compromise Playbook · Top 10 Infrastructure as Code Misconfigurations · Infrastructure as code platform health check