.justappsec is an open, readable format. It lives next to your code, commits to git, and is designed so any AI can create, read, and update it.
Ask your AI
Tell Copilot, Claude, or Cursor: "create a threat model for this codebase." Point it at the schema below.
Commit the file
The AI outputs a .justappsec file. Save it next to your code. Commit it. It becomes part of your security context.
Triage here
Open the file in this tool to visualise the architecture, triage threats, and mark mitigations — no account needed.
Add one of these to your AI assistant so it always knows how to produce threat model files.
# Threat modeling When asked to create or update a threat model, produce a `.justappsec` file following the JustAppSec v1 schema at https://justappsec.com/threat-model/schema The file lives next to the code it describes (e.g. `threat-model.justappsec`). Open it at https://justappsec.com/threat-model to review and triage threats visually. Output only raw JSON — no markdown fences, no explanation.
# Threat modeling When I ask you to create a threat model, output a .justappsec file following the JustAppSec v1 schema at https://justappsec.com/threat-model/schema - Output ONLY raw JSON — no markdown fences, no explanation - Place the file at the root of the repository (e.g. threat-model.justappsec) - Generate 15-25 threats total, technology-specific — no generic filler - Use consistent component names across all threats - After generating: remind me to open it at https://justappsec.com/threat-model
You produce JustAppSec v1 threat models as .justappsec files when asked.
Schema reference: https://justappsec.com/threat-model/schema
Key rules:
- Output only raw JSON — no markdown fences, no explanation
- Use the v1 format: { version: "1", meta: {...}, threats: [...] }
- threats is a flat array — each threat has id, title, description, severity, status, path
- path is an ordered array of component names the attack traverses
- Use consistent component names across all threats
- Add technology-specific threats; no generic filler text
- Most threats status "open"; mark proven mitigations as "closed" with closeReason "mitigated"Want a full, one-shot prompt?
The threat model editor has a built-in prompt you can copy and paste into any AI agent to generate a complete, importable threat model file.
The full structure of a .justappsec v1 file.
| Field | Type | Notes |
|---|---|---|
| version | "1" | Always the string "1". |
| meta | MetaObject | Name and timestamps. |
| threats | ThreatObject[] | Flat list of all identified threats. |
| Field | Type | Notes |
|---|---|---|
| name | string | Human-readable model name. e.g. "My SaaS Platform" |
| created | ISO 8601 string | Creation timestamp. |
| modified | ISO 8601 string | Last-modified timestamp. |
| Field | Type | Notes |
|---|---|---|
| id | string | Unique within the file. e.g. "t1", "t2abc" |
| title | string | Concise, action-based threat name. Max ~60 chars. |
| description | string | Specific attack scenario — name the exact vulnerability, entry point, and impact. |
| severity | "critical" | "high" | "medium" | "low" | "info" | Reflects realistic CVSS estimate. |
| status | "open" | "in-progress" | "closed" | "open" for unaddressed threats. |
| path | string[] | Ordered attack chain. First = entry point, last = target. e.g. ["Attacker","API Server","PostgreSQL"] |
| category | string (optional) | STRIDE or custom tag. e.g. "Injection", "Spoofing", "SSRF" |
| owner | string | null (optional) | Team or person. e.g. "@backend-team" |
| closeReason | "mitigated" | "accepted" | "ignored" | "wont-fix" | null (optional) | Required when status is "closed". |
| ticketUrl | string (optional) | Link to Jira, GitHub Issue, Linear, etc. |
Three threats with attack paths. Save this as threat-model.justappsec and open it in the editor.
{
"version": "1",
"meta": {
"name": "My API",
"created": "2026-01-01T00:00:00.000Z",
"modified": "2026-01-01T00:00:00.000Z"
},
"threats": [
{
"id": "t1",
"title": "SQL injection via search endpoint",
"description": "The GET /api/products?q= parameter is concatenated into a raw SQL query without parameterisation. An attacker can exfiltrate the entire users table or escalate to DBA via stacked queries on PostgreSQL.",
"severity": "critical",
"status": "open",
"path": ["Attacker", "API Server", "PostgreSQL"],
"category": "Injection",
"owner": null
},
{
"id": "t2",
"title": "JWT algorithm confusion (RS256 → HS256)",
"description": "The auth service trusts the 'alg' JWT header field without allowlisting RS256. An attacker signing a forged token with HS256 using the public key as the HMAC secret can impersonate any account.",
"severity": "critical",
"status": "open",
"path": ["Attacker", "Auth Service", "All Protected APIs"],
"category": "Spoofing",
"owner": null
},
{
"id": "t3",
"title": "Missing HTTPS on internal service mesh",
"description": "Traffic between the API Server and internal microservices uses plain HTTP. A compromised container in the same network namespace can intercept or tamper with requests.",
"severity": "medium",
"status": "closed",
"closeReason": "mitigated",
"path": ["API Server", "Auth Service"],
"category": "Info Disclosure",
"owner": "@platform-team"
}
]
}Open the editor, generate a threat model for your system, and commit it — all in under five minutes.