Frontend Labs
⋯

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)

  1. 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 debug to attach an ephemeral container for live triage — all without deleting the original pod.
  2. 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.
  3. Practice EBS/disk snapshotting an instance without stopping it; verify the snapshot is usable for offline analysis.
  4. 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.
  5. 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

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

  1. 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?
  2. Why can't you simply "reset the password" to contain a compromised cloud identity, and what's the practical alternative?
  3. What does encryption context let you determine during a KMS-related incident that you couldn't determine otherwise?
  4. When is fully-automated containment appropriate, and when should a human stay in the loop?
  5. Why rebuild from known-good IaC/images rather than clean and reuse a compromised instance or container?
  6. 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.

Generated from real-life-security-guide-v1.md · 8 Oct 2026 16:36