Chapter 55 — Incident response for cloud and containers
In one sentence
Cloud and container incident response inherits G1's lifecycle but changes the mechanics entirely: evidence lives in ephemeral systems that must be captured before they vanish, containment means revoking a credential's blast radius rather than resetting one password, and automation is often necessary because the environment moves faster than a human can.
Where we are
G1 Ch 51 gave you the IR lifecycle, containment trade-offs, and forensic basics. This chapter is what changes when "the compromised system" is a pod that will be rescheduled in minutes, or a role session with no single "password" to reset.
How it works
"Isolate, don't terminate" — the central adjustment for ephemeral compute:
The instinct to "kill it" is usually WRONG in cloud/container IR,
because it destroys evidence AND doesn't stop a credential's blast
radius (below). The pattern:
CLOUD INSTANCE: don't terminate. Instead: detach it from the load
balancer/auto-scaling group (so it stops serving traffic and
won't be auto-replaced mid-investigation), snapshot the EBS
volume(s) WITHOUT stopping the instance where your platform
supports it, attempt memory acquisition if feasible (a LiME
capture on Linux, or a hypervisor-level memory snapshot if your
platform offers one), tag it clearly as "under investigation" so
automation doesn't reap it, THEN isolate its network access
(a quarantine security group allowing only your forensics
tooling).
KUBERNETES POD: `kubectl cordon` the NODE (stops new pods scheduling
there, doesn't touch the running one). Do NOT delete the pod.
Apply a QUARANTINE NetworkPolicy (deny all except a forensics
egress) via a label selector rather than deleting/recreating.
Extract logs and, where your CRI/kernel supports checkpointing
(CRIU-based), a CONTAINER CHECKPOINT before any termination.
`kubectl debug` can attach an ephemeral debug container sharing
the target pod's process namespace for LIVE triage without
modifying the compromised container itself.
ONLY AFTER evidence capture: terminate/delete and REBUILD from a
known-good image (Part 3's paved-road pipeline) rather than
"cleaning" the compromised instance/container in place -- you
cannot be confident you found every persistence mechanism by
inspection alone (G1 Ch 51's eradication principle, doubly true
here where rebuild is cheap and fast).
Credential blast-radius containment — the cloud-specific version of "reset the password":
A traditional IR reflex ("reset the compromised account's password")
doesn't map cleanly to cloud identity, because:
- an ACTIVE STS SESSION (Part 2 Ch 5) keeps working until it expires
on its own -- there is no direct "kill this session" API in most
clouds. The practical response: attach an EXPLICIT DENY inline
policy to the underlying role/user IMMEDIATELY (Part 2 Ch 6's
policy-evaluation rule: an explicit deny wins over everything,
instantly, for all NEW calls even mid-session) while you
investigate; this doesn't retroactively undo anything already
done, but it stops FURTHER action within seconds, faster than
waiting for a full credential rotation to propagate.
- a WORKLOAD IDENTITY (IRSA/Workload Identity/SPIFFE SVID, Part 4
Ch 20 / Part 5 Ch 23) is short-lived by design (a genuine security
win from those chapters) -- but if the underlying TRUST (the OIDC
provider config, the SPIRE registration entry) is what's
compromised rather than one session, you must revoke/rotate the
TRUST relationship itself, not just wait for one token to expire.
- a SINGLE SSRF or RCE can expose a role usable against DOZENS of
resources (Part 2's attack-path chapters) -- credential
containment in cloud IR is therefore often BROADER in blast-radius
terms than a traditional single-account compromise, and the
explicit-deny-first, investigate-second pattern exists specifically
because full, careful remediation takes longer than the exposure
window can safely tolerate.
AFTER containment: fully rotate/replace the underlying credential
material, review and fix the trust/permission misconfiguration that
allowed the exposure (Part 2 Ch 6, Part 3 Ch 12), and only then remove
the emergency deny policy.
Cloud-native forensic evidence sources (recap and prioritise):
PRIMARY TIMELINE: CloudTrail / Cloud Audit Logs / Kubernetes audit
logs (Ch 52) -- usually your fastest, richest source, IF retention
was adequate (Ch 52's dwell-time argument, made concrete: this is
exactly the evidence that ages out if retention is too short).
ENCRYPTION CONTEXT on KMS Decrypt calls (Part 7 Ch 44's worked
example) -- lets you scope EXACTLY which records were accessed
during a compromise window, not just "the key was used."
RUNTIME TELEMETRY: Falco/Tetragon event history (Part 4 Ch 20) for
container-level process/syscall evidence.
VPC FLOW LOGS: network-level corroboration of what a compromised
workload actually connected to, cross-referenced against the
control-plane timeline.
IMMUTABLE SNAPSHOTS: EBS/disk snapshots taken during isolation
(above), hashed and stored with chain-of-custody records exactly as
G1 Ch 51 describes, just applied to cloud storage objects instead of
physical drives.
IR automation / SOAR — necessary because cloud/container compromise moves faster than a human on-call can react to manually:
Security Orchestration, Automation and Response platforms (Tines, Torq,
Palo Alto XSOAR) or cloud-native automation (a high-confidence
GuardDuty/Security Hub finding triggering a Lambda/Cloud Function that
automatically attaches the quarantine policy, cordons the node, or
snapshots the volume) let CONTAINMENT happen in seconds instead of
whatever your on-call's pager-to-keyboard latency is.
THE TRADE-OFF: gate fully-automated, DESTRUCTIVE or DISRUPTIVE actions
(isolating a production credential, cordoning a node serving live
traffic) behind HIGH-CONFIDENCE detections only (Ch 51's precision
metric matters enormously here -- a false positive that auto-isolates
a production payment role is itself an incident). For ambiguous or
lower-confidence findings, automate the INVESTIGATION step (gather
evidence, open a ticket, page someone) but keep a human in the loop
for the containment DECISION.
Cross-account/cross-cluster coordination: Part 2 Ch 7's multi-account
structure puts your IR tooling and centralised, tamper-resistant logs in the
dedicated security account — investigations that span multiple workload
accounts or clusters are coordinated FROM there, which is exactly why that
account's own access (Ch 49) must be the most tightly governed of all.
Worked example
A compromised CI role, from detection through rebuild.
Ch 51's worked-example detection fires: `ci-deployer`'s session
credentials were used from a source IP outside any known CI runner
range.
ISOLATE (minutes, not hours):
1. Attach an inline explicit-deny policy to `ci-deployer`
IMMEDIATELY -- all further API calls with that identity fail
instantly, regardless of the active session's remaining TTL
(Part 2 Ch 6's policy-evaluation rule, applied defensively here).
2. Pull CloudTrail for every call made by `ci-deployer` in the
suspected compromise window; the ENCRYPTION CONTEXT (Part 7
Ch 44) on any KMS calls scopes exactly what data, if any, was
actually decrypted -- not just "a key was used."
3. If the compromise traces to a specific CI RUNNER instance
(Part 3 Ch 12's OIDC trust scenario, realised): detach it from
the runner pool, snapshot its disk, do NOT terminate yet.
INVESTIGATE: the timeline shows the exposure came from an OIDC
trust-policy misconfiguration (Part 3 Ch 12's exact failure mode) --
`sub` was scoped to the whole org rather than one repo+environment,
and a fork PR's workflow run was able to assume the role.
ERADICATE:
- fix the trust policy (the actual root cause) -- pin `sub` correctly.
- fully rotate any credential material `ci-deployer` could have
exposed beyond the session itself (any long-lived secrets it had
access to, per G1 Ch 49's rotation runbook).
- REBUILD the CI runner from the known-good, IaC-defined image
(Part 3) rather than reusing the snapshotted instance -- the
snapshot is evidence, not a recovery source.
- remove the emergency deny policy once the trust fix is verified
and the role's normal, least-privilege operation is confirmed.
RECOVER: heightened monitoring on `ci-deployer` and the OIDC trust
configuration specifically for the following two weeks (attackers
often probe whether a fix actually held); confirm the pipeline's
normal deploys succeed post-fix.
POST-INCIDENT: the blameless review (G1 Ch 51) traces this to the
trust-policy pattern from Part 3 Ch 12 not being enforced by
POLICY-AS-CODE (Part 3 Ch 11) at the time -- the action item is a
Kyverno/OPA rule that would have BLOCKED the overly-broad trust policy
from ever being deployed, closing the gap architecturally rather than
relying on this detection catching every future recurrence.
Practice (75 min)
- Simulate the "isolate, don't terminate" pattern in your kind cluster: cordon
a node, apply a quarantine NetworkPolicy to a specific pod by label, extract
its logs, and use
kubectl debugto attach an ephemeral container for live triage — all without deleting the original pod. - In your cloud sandbox, practice the explicit-deny containment pattern: attach an inline deny policy to a test role/user and confirm an ACTIVE session (obtained before the deny was applied) immediately fails on its next call.
- Practice EBS/disk snapshotting an instance without stopping it; verify the snapshot is usable for offline analysis.
- Build a minimal automated response: a high-confidence detection (from Ch 51's lifecycle) triggers a function that automatically attaches the quarantine/ deny policy — then deliberately test it against a KNOWN-BENIGN pattern to confirm your precision is high enough that you're comfortable with the automation being irreversible/disruptive.
- Run the full worked-example scenario end to end in your lab: detect, isolate, investigate using encryption context and CloudTrail, eradicate, rebuild from IaC, and write the blameless post-incident review with an architectural (policy-as-code) action item.
Across the series
- Running the incident: roles, an evidence bundle, ring-buffer packet capture, and blameless postmortems in the TCP/IP guide, Chapter 60; preserving volatile host evidence before restarting in the Linux guide, Chapter 72; and the layer-by-layer debugging playbook in the OSI guide, Part 14.
Common mistakes
- Terminating a compromised instance/pod immediately. Destroys evidence and doesn't address the credential's blast radius, which persists until explicitly revoked.
- Waiting for a full credential rotation before containing. The explicit-deny-first pattern exists because rotation takes longer to propagate than an active session can safely be left running.
- "Cleaning" a compromised instance/container in place instead of rebuilding from known-good IaC/images. You cannot be confident you found every persistence mechanism by inspection.
- Fully automating destructive containment on low-confidence detections. A false positive that auto-isolates production is itself an incident; gate automation by detection confidence (Ch 51's precision metric).
- Not using encryption context to scope a KMS-related compromise. Without it, "was this specific record accessed" is unanswerable, forcing worst-case notification scoping.
- Fixing the immediate incident without an architectural (policy-as-code) follow-up. The same misconfiguration class recurs elsewhere if the underlying gap isn't closed structurally.
Check yourself
- Why is "isolate, don't terminate" the right default for ephemeral cloud/ container compute, and what does isolation actually involve for a pod versus an EC2 instance?
- Why can't you simply "reset the password" to contain a compromised cloud identity, and what's the practical alternative?
- What does encryption context let you determine during a KMS-related incident that you couldn't determine otherwise?
- When is fully-automated containment appropriate, and when should a human stay in the loop?
- Why rebuild from known-good IaC/images rather than clean and reuse a compromised instance or container?
- Why does IR for a multi-account cloud structure centralise around the dedicated security account?
Further reading
- Docs: AWS "Incident Response" whitepaper (the "isolate, don't terminate" and EBS-snapshot-without-stopping guidance in detail); the "AWS Customer Playbook Framework" repo (revisit from G1/Part 2 with the containment mechanics now in mind).
- Kubernetes:
kubectl debug(ephemeral containers) documentation; CRIU project docs for container checkpointing. - SOAR: Tines, Torq, and Palo Alto XSOAR product documentation for automated-playbook design patterns and the confidence-gating trade-off.
- Book: Incident Response & Computer Forensics (3rd ed., G1 reference) — the cloud-forensics chapter specifically; Cloud Forensics research from SANS FOR509/FOR518-adjacent course material for deeper technique detail.