Threat Modeling skill for Codex
STRIDE threats tied to real data flows. This skill builds a STRIDE threat model the team can act on: it scopes to one feature, draws a data flow diagram with trust boundaries, enumerates threats per element, and records a response and owner for each. It ties every threat to a concrete DFD element so the model produces tickets, not vague worries.
curl -fsSL codexskills.dev/install.sh \ | sh -s -- threat-modeling Installs to ~/.agents/skills/threat-modeling/ for every project on this machine.
curl -fsSL codexskills.dev/cli.mjs -o codex-skills.mjsnode codex-skills.mjs install threat-modeling 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 threat-modeling Installs to .agents/skills/threat-modeling/ in the current repository. Commit it and everyone who runs Codex there gets it.
curl -fsSLO codexskills.dev/downloads/threat-modeling.zipunzip -o threat-modeling.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))) threat-modeling 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 $threat-modeling, 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
Builds a STRIDE threat model from a data flow diagram — decompose the system, map trust boundaries, enumerate threats per element, and record ranked mitigations and assumptions. Use when designing or changing a feature that handles sensitive data or auth, when asked to "threat model this", or before a security review of a new design. Produces a reviewable model, not a scan.
Use it when
- Designing or changing a feature that handles auth, money or PII
- A change adds an integration, data store or external input
- You want a reviewable model before a security review
Use something else when
- The code already exists and you want it reviewed for bugs: use secure-code-review
- You want coverage of a running app against known classes: use owasp-top-10-review
- You need to test a deployed system with authorization: use pentest-methodology
How to check the result
Every row of the threat table names a specific DFD element and a chosen response; High-risk threats have an owner and become tracked work, and accepted risks are signed off.
The mistake it prevents
Producing a generic STRIDE checklist with no diagram, so threats aren't anchored to real flows and nobody can tell which ones actually apply.
A threat model answers four questions: what are we building, what can go wrong, what are we doing about it, and did we do a good enough job. The output is a living document a team can argue with and act on — a DFD, a per-element threat list, and ranked mitigations with owners. Model the design, not an abstract system.
When to model
- A new feature touching auth, payments, PII, or crossing a trust boundary.
- A design change that adds an integration, data store, or external input.
- Before a security review, so the reviewer knows where to look hardest.
Keep scope tight: one feature or flow per model is more useful than a whole-system model that no one finishes.
Workflow
- [ ] 1. Define scope and assets (what we protect, what "bad" means)
- [ ] 2. Draw the data flow diagram with trust boundaries
- [ ] 3. Enumerate threats per element with STRIDE
- [ ] 4. Decide a response for each (mitigate / accept / transfer / eliminate)
- [ ] 5. Rank by risk and assign owners
- [ ] 6. Record assumptions and revisit triggers
1. Scope and assets
Read AGENTS.md and the design doc. List the assets worth protecting (user data,
credentials, money, availability, integrity of records) and what an attacker would want.
Name the actors: end users, admins, other tenants, the service’s own components,
third-party integrations, and the anonymous internet.
2. Data flow diagram
Draw the system as elements and flows. Use four node types and mark every trust boundary (where data crosses from less-trusted to more-trusted, e.g. internet → API, app → DB, tenant A → tenant B). Trust boundaries are where threats concentrate.
[External Entity] --request--> (Process) --query--> [Data Store]
| trust boundary: internet | service | | trust boundary: service | DB |
- External entities: users, third-party services (no control over them).
- Processes: your services, functions, handlers.
- Data stores: DBs, caches, queues, files, secrets.
- Data flows: the arrows, each labeled with protocol and what it carries.
A simple Mermaid flowchart with subgraph for each trust zone is enough; keep it legible.
3. STRIDE per element
For each element and flow, walk STRIDE. Not every threat applies to every element — the table says which to focus on.
| STRIDE | Property violated | Applies most to | Example |
|---|---|---|---|
| Spoofing | Authentication | Entities, processes | Forged token passes as another user |
| Tampering | Integrity | Flows, stores, processes | Request body modified; DB row altered |
| Repudiation | Non-repudiation | Processes, stores | Action with no audit trail, deniable |
| Information disclosure | Confidentiality | Flows, stores | PII over HTTP; error leaks internals |
| Denial of service | Availability | Processes, flows | Unbounded request exhausts the service |
| Elevation of privilege | Authorization | Processes | User reaches admin function |
Write each threat as a concrete sentence tied to the DFD element: “A standard user calls the admin export endpoint (Process P2) because the role check is only in the UI (EoP).”
4. Response per threat
For each threat pick one: mitigate (add a control), eliminate (remove the feature/ flow), transfer (push to a provider/contract), or accept (document the residual risk and who signed off). Prefer eliminating unnecessary attack surface over bolting on controls. Map each mitigation to a concrete control:
- Spoofing → strong auth, MFA, signed/verified tokens.
- Tampering → TLS, integrity checks, parameterized queries, authorization.
- Repudiation → audit logging with user + action + timestamp.
- Info disclosure → encryption in transit/at rest, least-privilege, careful errors.
- DoS → rate limits, quotas, timeouts, input size caps.
- EoP → server-side authorization on every privileged path, least privilege.
5. Rank and own
Rank by likelihood × impact (High/Medium/Low is enough; use DREAD only if the team wants numbers). Assign each mitigation an owner and a target. The model is only useful if the High items become tickets.
Output contract
## Threat model — <feature> (<date>, <authors>)
Scope: <what's in>. Out of scope: <what's not>. Assets: <list>.
### Data flow diagram
<diagram + trust boundaries listed>
### Threats
| ID | Element | STRIDE | Threat | Risk | Response | Mitigation | Owner |
|----|---------|--------|--------|------|----------|-----------|-------|
| T1 | P2 export | EoP | user reaches admin export | High | mitigate | server-side role check | @x |
### Assumptions
- <e.g. TLS terminates at the LB; DB not reachable from internet>
### Revisit when
- <new integration added / data classification changes / before GA>
Hard rules
- Tie every threat to a specific DFD element; “SQL injection is possible” without a flow is not a threat, it is a worry.
- Do not list threats you have no intention of resolving without an explicit accept + owner.
- A model with no diagram is a checklist, not a threat model. Draw the boundaries.
- Keep it updated: a stale model that claims coverage is worse than none. Record revisit triggers.
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: "Threat Modeling"
short_description: "STRIDE threats tied to real data flows"
default_prompt: "$threat-modeling Threat model the new file-sharing feature before we build it" 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.