Security Incident Response skill for Codex
Contain fast, keep the evidence, mind the clock. Codex helps responders run a breach the way NIST SP 800-61r3 describes: a UTC timeline from minute one, evidence exported and hashed before anything is rotated or rebuilt, and containment options weighed by trade-off with each step confirmed by a human. It drafts status updates and the post-incident review, and flags regulatory clocks for counsel without making legal calls.
curl -fsSL codexskills.dev/install.sh \ | sh -s -- incident-response Installs to ~/.agents/skills/incident-response/ for every project on this machine.
curl -fsSL codexskills.dev/cli.mjs -o codex-skills.mjsnode codex-skills.mjs install incident-response The CLI also searches, updates and removes skills. Run it with no arguments to pick from a list. Needs Node 20.12+.
curl -fsSL codexskills.dev/install.sh \ | sh -s -- --project incident-response Installs to .agents/skills/incident-response/ in the current repository. Commit it and everyone who runs Codex there gets it.
curl -fsSLO codexskills.dev/downloads/incident-response.zipunzip -o incident-response.zip -d ~/.agents/skills/ The archive holds the skill folder with its generated agents/openai.yaml. Unzip into .agents/skills/ to scope it to a repo.
& ([scriptblock]::Create((irm codexskills.dev/install.ps1))) incident-response PowerShell 5.1 or 7. Installs to %USERPROFILE%\.agents\skills\. Add -Project for the current repo.
104-line POSIX script. No sudo, no telemetry. Read install.sh
Use it in Codex
Start a prompt with $incident-response, or pick it from /skills.
You can also just describe the task: Codex reads the description below and loads the playbook when your request matches.
What Codex reads before loading it
Runs a security incident from first alert to closure following NIST SP 800-61r3 - triage and severity, evidence preservation before changes, containment options with explicit approval, credential rotation, eradication, recovery, stakeholder and regulator communication timelines, and a blameless post-incident review. Use when there is a suspected breach, leaked credential, compromised account or server, malicious dependency, ransomware or data exposure, or when writing an incident response plan or playbook.
Use it when
- A breach, compromised account or leaked credential is suspected
- Malware, ransomware or a malicious dependency was found
- Customer or personal data may have been exposed
- Writing incident response plans, playbooks or tabletop exercises
Use something else when
- The outage has no security cause: use incident-command
- You need to dig through specific logs for attacker activity: use log-forensics
How to check the result
The incident record has a UTC timeline with every action and owner, evidence hashes logged before containment, every exposed secret listed as rotated, and post-incident action items with owners and dates.
The mistake it prevents
Wiping or rebuilding a compromised host, or rotating keys, before exporting the logs and snapshots needed to learn what the attacker did.
Done well means: the attacker’s access is cut off quickly without destroying the evidence needed to know what they did, every action is logged with a timestamp and an owner, the right people (including legal) hear about it in time for any regulatory clock, and the same root cause cannot recur.
Codex supports the responders: it builds the timeline, drafts commands and messages, and analyses logs. Humans decide containment and communications. Every action that changes production, revokes access or contacts anyone outside the team needs explicit user confirmation first.
First 30 minutes
- [ ] Open an incident record (doc or channel) with a UTC timeline; log every action from now on
- [ ] Name an incident lead and a scribe; keep the circle small (need to know)
- [ ] Capture what triggered the alert: source, time, raw evidence
- [ ] Assign an initial severity (table below); revisit hourly
- [ ] Preserve volatile evidence before containment changes it (next section)
- [ ] Decide first containment step with the incident lead
- [ ] Notify legal/privacy contact if personal data or customer data might be involved
- [ ] Use an out-of-band channel if the attacker may read email, Slack or the ticketing system
Severity
| Severity | Examples | Response |
|---|---|---|
| SEV1 | Confirmed access to customer data or production secrets; active attacker; ransomware | All hands, exec + legal informed within the hour, regulator clocks may start |
| SEV2 | Compromised employee account or server, leaked production credential, malicious dependency installed in CI | Dedicated responders, same-day containment |
| SEV3 | Leaked low-privilege or test credential, blocked intrusion attempt, phishing with no clicks | Business hours, track to closure |
| SEV4 | Suspicious but unconfirmed signal | Investigate; escalate on evidence |
When in doubt, start one level higher and downgrade with evidence.
Preserve evidence
Before rotating, wiping or restarting anything, capture what will be lost:
| Asset | Capture |
|---|---|
| Cloud logs | Export CloudTrail / Cloud Audit Logs / Entra sign-in logs for the window to a separate, write-protected account or bucket; extend retention |
| VM / server | Disk snapshot (EBS snapshot, GCP snapshot); memory capture if the team has the tooling; ps, ss -tupan, logged-in users, crontabs |
| Container / pod | kubectl logs --previous, pod spec, image digest; copy files with kubectl cp before deletion |
| SaaS (GitHub, Google Workspace, Okta) | Audit log export for the window |
| Application | Relevant DB rows (read-only query), app logs, WAF/CDN logs |
Record SHA-256 hashes of exported files in the timeline. Do not run cleanup scripts or
antivirus “remove” actions on affected hosts before snapshotting. Analysis of exported
logs: $log-forensics.
Containment options
Pick the least destructive option that stops the attacker; confirm each with the user.
| Situation | Containment | Trade-off |
|---|---|---|
| Leaked API key / cloud access key | Revoke or deactivate key, issue new one | Breaks consumers of the old key |
| Compromised user account | Revoke sessions and tokens, reset password, reset MFA, check new MFA devices and OAuth grants | User downtime |
| Compromised server | Isolate network (security group / firewall to forensics-only), keep it running for memory | Service capacity |
| Compromised container | Scale replacement from a known-good image, cordon and keep the bad pod for analysis | |
| Malicious dependency | Pin known-good version, block the package in the registry proxy, rotate secrets present on any machine that installed it | |
| Data exposed via public bucket or link | Remove public access, keep access logs | |
| Attacker persistence suspected | Contain all footholds at once, not one by one, to avoid tipping them off | Coordination time |
AWS key compromise quick path (confirm before running):
aws iam update-access-key --user-name <user> --access-key-id <AKIA...> --status Inactive
aws iam list-access-keys --user-name <user>
aws cloudtrail lookup-events --lookup-attributes AttributeKey=AccessKeyId,AttributeValue=<AKIA...> \
--start-time <iso8601> --max-results 50
Deactivate first (reversible), delete later once the investigation no longer needs the key ID live.
Eradication and recovery
- [ ] Root cause identified (initial access vector), not just the symptom
- [ ] All attacker-created artifacts removed: users, keys, OAuth apps, SSH keys, cron jobs,
CI workflows, webhooks, Lambda functions, IAM roles and policies
- [ ] Every secret the attacker could have read is rotated (list them explicitly)
- [ ] Rebuild compromised hosts from known-good images rather than cleaning them
- [ ] Vulnerability fixed and deployed; fix verified
- [ ] Heightened monitoring for the same indicators for at least 30 days
- [ ] Service restored and confirmed healthy
Communication
Draft messages for review; never send them without the user’s approval.
Internal update (every 1-2 hours for SEV1/2):
**[SEV2] <short name> - update <n> (<time UTC>)**
Status: investigating | contained | eradicated | recovering | closed
Known: <facts with confidence>
Unknown: <open questions>
Actions since last update: <list>
Next update: <time>
Regulatory and contractual clocks: a qualified professional must make these calls; flag them early so they can.
| Regime | Clock (summary, verify with counsel) |
|---|---|
| GDPR | Supervisory authority within 72 hours of becoming aware of a personal data breach likely to pose risk |
| SEC (US public companies) | Form 8-K within 4 business days of determining a cybersecurity incident is material |
| US state breach laws, HIPAA, PCI DSS, NIS2, sector rules | Varies by state, sector and data type |
| Customer contracts / DPAs | Often 24-72 hours to notify customers |
Codex must not decide whether notification is legally required; it prepares the facts (what data, how many subjects, which jurisdictions, timeline) for counsel.
Post-incident review
Within 5 business days of closure, hold a blameless review:
# Incident <id>: <title>
Severity: <> | Duration: detection <t0> -> containment <t1> -> closure <t2>
## Summary
## Impact (data, customers, systems, money)
## Timeline (UTC)
## Root cause and contributing factors
## What went well / what was hard
## Action items (owner, due date, ticket)
- Prevent: ...
- Detect sooner: ...
- Respond faster: ...
Track mean time to detect and to contain across incidents. Polishing the write-up for a
wider audience: $postmortem-writing.
Preparing before an incident
- Contact sheet: incident lead rotation, legal, privacy, PR, cloud provider support, cyber insurer hotline (insurers often require their panel firms).
- Log retention long enough to investigate (90 days hot, a year archived is common).
- Break-glass accounts tested; MFA recovery for admins documented.
- Playbooks for the top scenarios: leaked key, compromised account, malicious dependency, public bucket, ransomware.
- A tabletop exercise each quarter using one playbook.
Gotchas
- Rotating a credential before exporting logs that reference it can make correlation harder; snapshot first, then rotate quickly.
- Attackers often hold several footholds. Revoking one key while their OAuth app or extra IAM user survives just announces the response.
- Discussing the incident in a compromised Slack or email tenant tells the attacker what you know.
- “No evidence of access” is not “evidence of no access” when logging was off; say which logs existed.
- For operational outages without a security cause, use
$incident-commandinstead.
What the zip contains
SKILL.md plus the interface file below. Nothing runs on install.
agents/openai.yaml
Gives the Codex app a display name, a one-line description and a starter prompt for this skill.
interface:
display_name: "Security Incident Response"
short_description: "Contain fast, keep the evidence, mind the clock"
default_prompt: "$incident-response We think an AWS access key was leaked — walk us through the response" About this skill
Written and maintained by the Codex Skills editors to the same editorial standard as every skill here: a selective description, a real workflow, known pitfalls and a way to verify the work. First published , last updated . MIT licensed. Something wrong or out of date? Tell us.