threat-modeling.sgit.ai / practice / .security.json

.security.json — a reusable per-file schema

Against every source file in the bottom-up method sits a .security.json in a parallel tree — the file-level unit the fractal method is built from. The schema itself is publishable in full: it exposes a shape, not a finding.

The fields

FieldCarries
attack_surfaceEndpoints, authentication, input validation, rate limiting — what this file exposes to the outside
vulnerabilitiesid, severity, attack vector, impact, status, mitigation — and risk_decision (below)
secrets_exposureWhether this file can see, log, or leak a credential
dependenciesIncluding trust_boundary_crossings — where this file's data crosses into code it does not control
redundant_codeDead or duplicated logic — a maintainability signal that is also a security one, since unreviewed code is unreviewed regardless of whether it runs

The interesting field: risk_decision

Not every finding is fixed immediately, and the schema does not pretend otherwise. risk_decision records an explicit accept-for-now with its own reasoning attached — an owner, a rationale, and (implicitly) a date, so an accepted risk is a decision on record rather than a finding that quietly disappeared.

A finding is not binary. The decision to defer is itself data, with an owner and a rationale — which is what separates a risk register from a to-do list nobody is accountable for.

Why this is publishable and a finding is not

The schema describes a shape: what a file-level security record looks like. A populated instance of that schema, for a specific file in a live product, is a finding — and the disclosure rule holds those until they are closed. The distinction is the same one this whole site runs on: publish the method, redact the instance.

The Gherkin connection

The wider vault-native argument for this schema goes further: a mitigation expressed as an executable Gherkin scenario is a threat model CI can check, rather than a document nobody re-reads after the review that produced it. /graph/ covers this as part of the vault-native data argument.