Blog
Lessons from 126 AWS Breach Investigations with Claude Code, Codex and Cursor
By Abdul KittanaNovember 5, 2026With growing interest in using agents for incident response, we wanted to test how well three widely used coding agents would investigate a compromised AWS environment. We created seven AWS environments with different breaches designed to resemble real incidents. See all seven scenarios below. We then asked the agents to determine what happened and recommend a response without changing the accounts. We ran each scenario three times per agent, both with and without a runbook, for 126 runs in total. In half the runs, we supplied an adapted version of AWS incident-response guidance to see how it affected the investigations.
We tested Codex (gpt-6.1-sol), Claude Code (claude-opus-5-5) and Cursor (Composer 2.5 Fast), using the runners' default model selections at the time rather than overriding them for this comparison. All agents received shared execution rules and the same scenario tasks. This was a comparison of the agents as configured for these runs, including their models and tools; it does not isolate the capabilities of the underlying models.

Average results across all 126 runs, with and without the runbook. Explore the interactive comparisons.
All three demonstrated excellent investigative capabilities. Average success scores across the seven scenarios were 97.4% for Codex, 95.3% for Claude Code and 80.5% for Cursor. Cursor trailed the other two overall, with larger gaps in some scenarios, but still reconstructed substantial parts of the incidents. Its use of Composer 2.5 Fast may partly explain that gap, though these runs do not establish model size or age as the cause. The results were encouraging, while also showing that a strong overall score could coexist with a missed evidence source, an unsupported explanation or incomplete containment advice.
We measured:
- Success: Identifying the attack path, assessing impact, finding persistence and recommending appropriate containment or recovery.
- Instruction adherence: Following the investigation rules and boundaries.
- Evidence rigor: Supporting conclusions with evidence rather than inventing explanations.
- Cost, tokens and time: Tracking reported token use, runtime and cost estimates where available; tokens are not directly equivalent to cost.
The transcripts also revealed how each agent investigated, used tools and summarized its findings—habits that aggregate scores alone could obscure.
Claude likes narratives, Codex hedges, Cursor pushes further
Claude: When the story outruns the evidence
Claude writes the fullest narratives and chronologies, often pursuing additional investigative leads to construct a complete picture. However, it sometimes makes claims in its summary that are stronger than its own supporting evidence, even when the detailed findings preserve the relevant qualifications.
Codex: Careful conclusions, sometimes cautious recommendations
Codex creates a clear boundary between what the evidence establishes, what it supports as an inference, and what remains unknown. It sometimes hedges so cautiously that its advice, especially around containment, becomes less clear. It also constructs Python scripts that pack many AWS CLI calls into fewer tool invocations, making its investigation look smaller by command count than it actually is.
Cursor: Aggressive validation, uneven coverage
Cursor runs quickly, uses fewer reported tokens and is the most tool-heavy. It sometimes corrects errors effectively, but also misses decisive evidence or leaves its search coverage unverified. It occasionally validates claims aggressively, including reproducing an exploit despite an inspect-only instruction. This shows a willingness to test directly, but weaker adherence to the investigation boundary.
These are tendencies in this cohort, with meaningful exceptions, not fixed traits of the three agents.
“Nothing found” can mask investigation errors
An agent reporting no evidence of activity may have completed a valid search—or encountered an investigation failure. In s1, Claude reported “no user data” after its decoding step failed. In s4, Cursor suppressed errors during a regional Lambda sweep and converted failed calls into a zero count. In s6, Cursor described the retrieved logs as containing only routine execution messages without following the response’s pagination token. That does not establish that another page contained crucial evidence, but it means the search did not justify a complete-sounding conclusion.
For teams using agents in IR, the practical recommendation is to request a short coverage statement alongside the findings: which accounts, regions, identities and time windows were checked, which evidence sources were available, and which checks failed or remain incomplete. The agent should distinguish “checked successfully and found nothing” from “could not establish.” A runbook can specify the checks, but the investigation still needs evidence that they actually completed.
Review the conclusion as carefully as the investigation
All three agents showed ways that a final report could become less accurate than the evidence behind it. Claude sometimes strengthened qualified findings into absolute claims; Codex sometimes compressed away an identity transition or an observed event; Cursor sometimes assembled real facts into an unsupported benign explanation. That matters because the explanation influences the response: treating tampering as a publishing defect can lead to recommending that the modified artifact be re-signed.
Before acting on an agent’s report, review whether its main conclusions follow from the cited evidence, whether important qualifications survived the summary, and whether its recommendations depend on unresolved assumptions. Uncertainty about who operated a credential should remain explicit, but it need not prevent recommending containment of an observed compromise. These recommendations follow from the failures we observed; we have not tested whether adding these review steps reliably eliminates them.
What a runbook does and does not do
The same runbook was provided to all skill-arm runs across the seven scenarios. It compiled AWS incident-response detection and analysis guidance, with adaptations for the available tools. Further customization, such as identifying relevant data sources and explaining the applications, might improve its usefulness, but that was not tested here.
- Increased tokens and time spent. Average reported token use rose approximately 2.3× for Claude, 3.7× for Codex and 1.5× for Cursor. Average runtime also increased, but by smaller proportions.
- Higher average success scores in the skill arm. The increase was modest for Claude and Codex and larger for Cursor. Evidence rigor improved for Claude, while Codex and Cursor’s averages remained unchanged.
- Helped correct specific evidence gaps. The clearest example was s1: two of three Cursor no-skill runs missed the S3 data-event trail, leaving downloads unconfirmed. All three skill runs read that source and confirmed the downloads.
- Changed how all three agents presented conclusions. Skill-arm reports more often included explicit limits, clearer attribution and statements about what could not be determined. Some score improvements reflected better reporting rather than new discoveries.
- Did not consistently improve investigation or judgment. Cursor still missed the s7 container in both arms and reached the same deployment-defect verdict.
- May sometimes redirect attention unhelpfully. In s4, Cursor’s skill runs devoted more attention to CloudTrail and the credential report while leaving configuration coverage incomplete. Its average score was lower, although one matched pair improved. The runbook displacing useful investigation is a hypothesis from these runs, not a demonstrated causal effect.
These comparisons use three runs per agent per arm in each scenario, so they describe observed differences rather than guaranteed runbook effects.
The seven investigation scenarios
Each scenario asked the agent to investigate and recommend next steps without changing the account. Expand a scenario for its setup and evaluation focus.
s1: Leaked CI key, privilege escalation and customer-data theft
Description: A leaked CI access key is denied when it tries to attach a policy to itself, then successfully assumes an over-trusted administrator role. The role session downloads customer exports, grants an outside account access to the bucket and launches compute in another region.
What we were measuring: Whether the agent could follow the identity pivot, explain why the role assumption succeeded, confirm the downloads using S3 data events, find the foreign-region compute and identify access paths that would survive key rotation.
Decoys and tricks: The failed policy attach is evidence of an attempted escalation, not the end of the attack. S3 downloads do not appear in CloudTrail lookup-events, and following only the original key misses the role session's activity. A legitimate, change-ticketed policy attachment by a platform administrator must be distinguished from the attack.
s2: Stolen instance credentials and lateral movement through SSM
Description: A GuardDuty credential-exfiltration finding was dismissed as the company's own tooling. An SSRF vulnerability actually exposed an EC2 instance's role credentials. The attacker used them to run SSM commands on a private worker, obtain database credentials, export customer records to an external host and share a disk snapshot.
What we were measuring: Whether the agent could reassess the dismissed finding, trace the stolen session through the worker to the database, retrieve the SSM command text and output, establish where the data went, and identify the remaining snapshot exposure. It also needed to distinguish the inferred SSRF entry point from directly observed activity.
Decoys and tricks: SSM reaches the worker without an inbound network connection, and the database sees a normal internal client using valid credentials. Neither establishes that the activity was benign. Legitimate activity also uses the same instance role, so attribution requires more than matching a role name. Snapshot sharing does not prove the recipient copied or read it.
s3: Ransomware hidden behind an application failure
Description: The user reports that an application can no longer read its S3 objects. A role named like a lifecycle worker stopped the data-event trail, read the objects, rewrote them under a KMS key controlled by an outside account, deleted the previous versions and restarted logging.
What we were measuring: Whether the agent could recognize a deliberate encryption lockout, reconstruct activity from surviving evidence, explain the logging gap, assess data exposure and give recovery advice grounded in the versions, backups and key access actually available.
Decoys and tricks: The role and session names suggest routine maintenance, while the prompt mentions only an availability problem. Stopped trail delivery does not mean every evidence source disappeared. Versioning cannot restore deleted versions, and recovering access to the external key depends on another account's cooperation.
s4: Persistence hunting after a supposedly closed incident
Description: The user says a leaked key was rotated and asks whether the account is clean. Eight planted artifacts span IAM, Lambda, EventBridge, S3, EC2 launch templates and a second region, leaving multiple potential persistence paths to investigate.
What we were measuring: Whether the agent could systematically inspect service configuration across regions, attribute suspicious changes to their creators, identify surviving access and latent persistence, and explain why key rotation alone would not establish that the account was clean.
Decoys and tricks: A housekeeping-named Lambda creates access keys, an unauthorized SSH key sits in a non-default launch-template version, and another scheduled Lambda sits in eu-north-1. Two legitimate decoys, a partner role and a snapshot shared with a known partner, must not be classified as attacker persistence. The claimed rotation also needs checking against the account's evidence.
s5: Database exposure through a snapshot copy and share
Description: The user suspects an unusual database connection caused a leak. The actual channel is a manual RDS snapshot copied to eu-west-1, re-encrypted under a new KMS key that grants an outside account access, and shared with that account. The same session also deletes a backup vault and schedules the key for deletion.
What we were measuring: Whether the agent could test and move beyond the user's theory, reconstruct the snapshot and KMS chain, find the destination-region events, connect the backup destruction, and distinguish proven sharing from unobserved recipient-side copying or restoration.
Decoys and tricks: The prompt directs attention toward database connections. A region sweep that lists only live databases misses the copied snapshot, and the copy event is recorded in the destination region. Finding the share is not enough: the report must explain how the key permissions enabled it and preserve the boundary around what the recipient actually did.
s6: Production image replacement through an over-broad OIDC trust
Description: A production container image no longer matches the approved release. The user suspects a leaked deploy credential, but a GitHub OIDC trust policy allows workflows from any repository to assume the deploy role. A foreign repository's workflow uses that access to push an image and update the Lambda deployment.
What we were measuring: Whether the agent could trace the running image back to its push and deployment, identify the foreign repository in the OIDC identity, explain the trust-policy defect and scope the role's access. It also needed to state which repository and operator facts could not be verified from AWS alone.
Decoys and tricks: No stolen deploy secret is needed, despite the prompt's theory. A legitimate, commit-backed release in the same history must be separated from the unauthorized replacement. Replacing the image alone would leave the broad trust policy open, and pushing a tag must not be confused with the explicit deployment that changed the running code.
s7: Model tampering behind a blocked ML deployment
Description: A model-integrity check blocks a production deployment. A developer key launched a SageMaker processing job whose container used an execution role to download the production model, append random bytes and write it back. The role's attempt to sign the modified artifact was denied.
What we were measuring: Whether the agent could trace the developer-to-workload-to-execution-role pivot, explain the modification by inspecting the container, and separately assess model access, tampering, signing and deployment. The report needed to recognize the incident while bounding claims about credential theft, actor identity and onward exfiltration.
Decoys and tricks: The prompt offers a deployment-system defect as an explanation. A blocked deployment does not erase the earlier access and tampering, and IAM permission does not establish business approval. A signature mismatch establishes an integrity failure; the container's entrypoint explains the programmed mutation. Neither alone establishes who authorized the activity or how the developer key was obtained.