net-kingdom/tools/security-case-types
tegwick bb9b9b556c
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Select explicitly pinned security case type revisions without fallback
Assistant: codex
Assistant-Model: gpt-6.1-sol
Assistant-Session: 01a126e1-76f8-7643-8cf3-e93336539ade
2026-10-11 09:09:24 +02:00
..
tests Select explicitly pinned security case type revisions without fallback 2026-10-11 09:09:24 +02:00
README.md Select explicitly pinned security case type revisions without fallback 2026-10-11 09:09:24 +02:00
security_case_validator.py Select explicitly pinned security case type revisions without fallback 2026-10-11 09:09:24 +02:00

security-case-types tools

Validator and renderer for SecurityCaseTypes and SecurityCases (canon/standards/security-case-types_v0.1.md, schemas canon/schemas/security-case-type_v0.1.schema.json and security-case_v0.1.schema.json).

# a type directory: type.yaml, README.md sections, tests, example cases
python3 tools/security-case-types/security_case_validator.py validate-type security-case-types/<type-id>

# a case against its type (security-case-types/<type-id>/type.yaml)
python3 tools/security-case-types/security_case_validator.py validate-case <case.yaml> --types security-case-types

# render a case into the composer's plan plus materialization, follow-through,
# verification and rollback; execution is never permitted
python3 tools/security-case-types/security_case_validator.py render <case.yaml> \
  --types security-case-types capabilities/playbooks/*.yaml

Only implemented types accept cases. --allow-unimplemented exists for a type's own example cases while the type is being written and acknowledged.

The validator refuses, among other things: missing sections, unknown or unpinned capabilities, attended steps without justification, steps or materialized items without a rollback, verification without a negative check or that reads a value, templates with unknown parameters, credential-shaped values anywhere, secret parameters that are not custody references, and high-risk types without founder acceptance.

To start a type: copy security-case-types/_template/, rename the directory to the type id, and rewrite every section. The template's tests travel with it: rename tests/test_type.py to tests/test_<type_id>_contract.py so module names stay unique.

Tests: python3 -m pytest tools/security-case-types/tests security-case-types/*/tests.

Explicit source versions

The default --types root is unchanged. Select a separately acknowledged source version explicitly, without moving its package into the default root:

python3 tools/security-case-types/security_case_validator.py validate-case \
  security-case-type-revisions/1.2/oidc-browser-relying-party/examples/forgejo.yaml \
  --types security-case-types \
  --version-root 1.2=security-case-type-revisions/1.2

This ordinary command refuses:1.2 is acknowledged, not implemented. For source-only preparation, the existing --allow-unimplemented option may be added; its render is deterministic and execution.permitted remains false. Current canonical1.1 is also acknowledged and its historical accepted case/normal refusal/preparation render remain exactly retained. No source acknowledgment or historical case acceptance is an implementation/native proof waiver.

The Python API is load_type(default_root, exact_reference, version_roots={"1.2": explicit_root}). Each key must be an exact major.minor and each root a Path. CLI --version-root VERSION=PATH may repeat for DIFFERENT versions. A matching explicit version selects exactly one root; a missing/wrong/ambiguous source refuses without trying the default or another revision. Versions without a mapping continue using --types. No directory discovery, highest/latest selection, status promotion or automatic owner-adapter adoption occurs. Duplicate mappings (even identical), duplicate YAML fields, mismatched source ID/version, malformed/traversal references and selected symlinks refuse. Direct case validation also requires the case reference to match the supplied type ID/version.

An explicit root is source input, not an owner acknowledgment or grant. Callers retain exact source hashes/type/case/render in their own reviewed receipts. Existing two-argument load_type callers, including ops-mason, retain their default behavior until their owner deliberately adopts the optional input. Adapter/global provenance/native first-reference gates remain separate in NK-WP-0048-T06 and the existing ORGREF driver.