JustAppSec
JustAppSec Threat Model

Your threat model, for AI.

.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.

Three steps

1

Ask your AI

Tell Copilot, Claude, or Cursor: "create a threat model for this codebase." Point it at the schema below.

2

Commit the file

The AI outputs a .justappsec file. Save it next to your code. Commit it. It becomes part of your security context.

3

Triage here

Open the file in this tool to visualise the architecture, triage threats, and mark mitigations — no account needed.

AI setup

Add one of these to your AI assistant so it always knows how to produce threat model files.

GitHub CopilotAdd to .github/copilot-instructions.md in your repo
# 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.
CursorAdd to .cursor/rules or Settings → Rules for AI
# 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
Claude / ChatGPTPaste as a system prompt or in a custom GPT / Project
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.

Schema reference

The full structure of a .justappsec v1 file.

Root object
FieldTypeNotes
version"1"Always the string "1".
metaMetaObjectName and timestamps.
threatsThreatObject[]Flat list of all identified threats.
MetaObject
FieldTypeNotes
namestringHuman-readable model name. e.g. "My SaaS Platform"
createdISO 8601 stringCreation timestamp.
modifiedISO 8601 stringLast-modified timestamp.
ThreatObject
FieldTypeNotes
idstringUnique within the file. e.g. "t1", "t2abc"
titlestringConcise, action-based threat name. Max ~60 chars.
descriptionstringSpecific 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.
pathstring[]Ordered attack chain. First = entry point, last = target. e.g. ["Attacker","API Server","PostgreSQL"]
categorystring (optional)STRIDE or custom tag. e.g. "Injection", "Spoofing", "SSRF"
ownerstring | null (optional)Team or person. e.g. "@backend-team"
closeReason"mitigated" | "accepted" | "ignored" | "wont-fix" | null (optional)Required when status is "closed".
ticketUrlstring (optional)Link to Jira, GitHub Issue, Linear, etc.

Minimal example

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"
    }
  ]
}

Ready to build?

Open the editor, generate a threat model for your system, and commit it — all in under five minutes.

Threat modelling is in betaReport an issue here
Need help?Get in touch.