Threat model テンプレート
このページは、記入用テンプレートを誤ってサイトのメタデータとして解釈しないよう、原文をコードとして表示しています。
---schema: codex-delivery/threat-model@1document_id: "TM-<<required: change ID or stable model ID>>"change_id: "CHG-<<required: YYYYMMDD-slug>>"risk_tier: "<<required: R0 | R1 | R2 | R3>>"document_status: draftdecision_state: UNKNOWNowner: "<<required: risk owner>>"evidence_as_of: "<<required: ISO 8601 or UNKNOWN>>"commit_sha: "<<required: exact SHA for implementation delta or N/A with reason>>"supersedes: "<<required: prior threat model ID or N/A>>"refs: - TASK-<<required>>---
# Threat-model delta: <<required: system/change>>
This is a change-specific delta. Reference the system baseline instead of rewriting it.
## Scope and review trigger
- System/baseline model: `<<required: path/ID + version/hash>>`- Change and exact fingerprint: `<<required>>`- Included assets/flows: `<<required>>`- Excluded scope and owner: `<<required>>`- Risk tier / methodology used: `<<required: e.g. scenario-based, ASVS mapping; no score-only conclusion>>`- Required re-review triggers: `<<required: boundary, data, provider, permission, model/tool, migration, incident>>`
## Assets and impact
| Asset ID | Asset/data class | Confidentiality | Integrity | Availability | Maximum impact | Owner ||---|---|---|---|---|---|---|| ASSET-01 | <<required>> | low/medium/high | low/medium/high | low/medium/high | <<required>> | <<required>> |
Include customer trust, money, credentials, domain/email/cloud control, audit evidence, and founder recovery capacity where relevant.
## Actors and capabilities
| Actor ID | Legitimate role or attacker | Starting access | Capability/motive | Explicitly excluded capability ||---|---|---|---|---|| ACTOR-01 | <<required>> | <<required>> | <<required>> | <<required>> |
## Entry points and trust boundaries
| ID | Source | Boundary crossed | Authentication/validation | Destination/sink | Data/action ||---|---|---|---|---|---|| FLOW-01 | <<required>> | <<required>> | <<required>> | <<required>> | <<required>> |
Provide a small diagram when the table does not make ordering or privilege visible.
```text<<required: source → validation → trusted service → sink / external effect>>```
## Data handling delta
| Data class | New collection/use? | Storage/retention | Provider/region | Log/eval use | Delete/export | Evidence ||---|---|---|---|---|---|---|| <<required>> | yes/no | <<required>> | <<required>> | <<required>> | <<required>> | <<required>> |
Do not paste raw credentials, personal data, payment data, or customer prompts here. Reference a controlled/redacted artifact.
## Threat scenarios
Copy one block per material scenario. High/Critical scenarios require positive verification and named residual-risk acceptance after mitigation. Active residual Critical is `STOP`; active residual High remains at least `PAUSE` until mitigation or scope reduction lowers the residual severity below High. Acceptance or a formal policy does not relabel severity.
### TH-01 — <<required: source-to-sink abuse/failure scenario>>
- Assets: `<<required: ASSET-*>>`- Actor and prerequisites: `<<required>>`- Entry/flow/sink: `<<required: FLOW-* and exact effect>>`- Scenario: `<<required: attacker or failure sequence, not just an OWASP category>>`- Impact/severity: `low | medium | high | critical` — `<<required: concrete consequence>>`- Likelihood basis: `<<required: evidence/range/unknown; do not hide impact in a single score>>`- Prevent controls: `<<required: server-side, least privilege, validation, constraint>>`- Detect controls: `<<required: signal, query, threshold, owner>>`- Contain controls: `<<required: flag, scope/authority limit, key revoke, isolation>>`- Recover controls: `<<required: rollback, restore, compensation, communication>>`- Verification IDs: `<<required: test/eval/manual EVID-*>>`- Verification result and fingerprint: `<<required or UNKNOWN>>`- Residual severity: `low | medium | high | critical | unknown`- Residual risk statement: `<<required: consequence and remaining uncertainty>>`- Active?: `yes | no`- Waivable under an applicable formal policy?: `yes | no`- Owner / due / state: `<<required>> / <<required>> / identified | mitigating | verified | accepted_risk | closed | reopened`- Risk acceptance: `<<required for accepted_risk: actor ID + authority/policy basis + exact scope + expiry + rationale + reopen trigger; otherwise N/A>>`- Reopen trigger: `<<required>>`
## Required negative/abuse cases
| Case ID | Scenario | Expected safe result | Evidence | Result ||---|---|---|---|---|| SEC-NEG-01 | another tenant/resource ID | no read, no mutation, auditable denial | EVID-<<required>> | UNKNOWN || SEC-NEG-02 | duplicate/replayed external event | one idempotent effect | EVID-<<required>> | UNKNOWN || SEC-NEG-03 | untrusted input attempts to reach privileged sink | blocked or bounded; no unsafe side effect | EVID-<<required>> | UNKNOWN |
Delete inapplicable examples with a reason and add change-specific cases.
### Authorization, tenant, and state-consumer coverage
A single “other tenant” case is an example, not coverage. Enumerate changed paths plus every semantically affected reader/writer reachable from the changed state, schema, event, permission, or API contract. Reconcile the denominator; a file with no diff can still mis-handle a new persisted state.
| Path ID | Entry point/channel | Identity/role/tenant state | Resource/operation/condition | Sink/effect | Positive cases | Denial/isolation cases | Evidence | Covered? ||---|---|---|---|---|---|---|---|---|| AUTH-PATH-01 | API/UI/auth middleware/job/queue/search/cache/serializer/export/support | <<required>> | list/read/create/update/delete/bulk/file/state interpretation | <<required>> | <<required>> | <<required>> | EVID-<<required>> | yes/no/unknown |
- Affected path inventory source/hash: `<<required: route/policy/schema/event manifest + consumer/reference/dataflow graph>>`- Paths scheduled / covered / excluded: `<<required: x / n / IDs>>`- Exclusion reason / owner / expiry: `<<required or N/A>>`- Generated/property/policy test used: `<<required or N/A with reason>>`
`SHIP` requires every semantically affected reachable path to be covered or explicitly removed from scope. “No diff” is not an exclusion. Prove the path unreachable/unexposed or prove its consumed contract unchanged with positive evidence. Missing list/bulk/cache/search/file/job/queue/serializer/old-client/export/support-impersonation paths are `UNKNOWN`, not “0 authorization failures.”
## Dependency and build delta
| Dependency/action | Identity/version/digest | Why needed | Maintainer/license/install scripts | Transitive/CI privilege | Vulnerability/provenance evidence | Removal path | Decision ||---|---|---|---|---|---|---|---|| <<required or N/A with reason>> | <<required>> | <<required>> | <<required>> | <<required>> | <<required>> | <<required>> | UNKNOWN |
### Privileged CI/build privilege flow
Fill one row for every changed or release-relevant privileged producer, artifact consumer, publisher, or deployer job, even when its workflow file has no diff. `N/A` requires proof that this change uses no privileged build/publication/deployment flow at all.
| Job/workflow | Trigger and actor trust | Checked-out/ref executed | Runner trust | Token permissions | Secrets/OIDC | Network/write targets | Artifact input producer/trust | Artifact output/consumer | Decision/evidence ||---|---|---|---|---|---|---|---|---|---|| CI-JOB-01 | pull_request / pull_request_target / workflow_run / push | <<required>> | hosted/self-hosted | <<required>> | <<required>> | <<required>> | <<required>> | <<required>> | STOP/PAUSE/UNKNOWN/SHIP + EVID-<<required>> |
Untrusted contributor-controlled code or artifact must not execute in a context that has write token, secret/OIDC, trusted self-hosted runner, production network, or publication authority. If that source-to-sink path exists, it is a non-waivable veto until the path is removed or isolated and reverified.
## Residual-risk summary
| Threat | Initial severity | Residual severity | Active? | Waivable? | Control evidence | Acceptance policy/actor/scope/expiry/rationale/reopen | State ||---|---|---|---:|---:|---|---|---|| TH-01 | <<required>> | low/medium/high/critical/unknown | yes/no | yes/no | <<required>> | <<required or N/A>> | UNKNOWN |
## Decision
- Active critical/high unverified scenarios: `<<required: count and IDs>>`- Required evidence missing/stale: `<<required: count and IDs>>`- Derived state: `STOP | PAUSE | UNKNOWN | SHIP`- Decision event / actor / time: `<<required>>`- Reason: `<<required>>`- Next action / owner / due: `<<required>>`
`0 identified threats` is not proof of safety. Record review scope and blind spots.
Derive the gate from the structured fields. Residual `unknown` or missing/stale evidence is `UNKNOWN`. Any active residual Critical is non-waivable `STOP`. Any active residual High is at least `PAUSE`; marking it `accepted_risk` or `waivable=yes` does not lower its severity. `SHIP` requires mitigation/scope reduction that moves every active residual below High, plus any policy-required acceptance for the remaining Low/Medium risk.