# secrets-engine — PEP unreachable-engine stance map # # Framework: net-kingdom/canon/standards/security-layer-model_v0.7.md §6.4, §9.3 # Companion: net-kingdom/SECURITY-COMPANION.md §5 # Voice: INTENT.md / layer.yaml # Validate: pytest tests/test_layer_conformance.py # # §6.4 obligation 3 requires a declared unreachable-engine stance that is # total, scoped per zone or equivalent, carries no implicit default and no # per-call discretion, and is published rather than held in code comments. # Catalog stage is the equivalent scope until security-zone membership arrives # as a claim on the decision. # # Runtime reads this file. tests/test_layer_conformance.py also pins # secrets_engine.pep_stance.SHIPPED_STANCE to this map. A published map free # to drift from that pin is worse than none. schema_version: "0.1" framework: netkingdom-security-layer-model standard_version: "0.7" repository: secrets-engine pep_shape: true declared_by: INTENT.md decision_engine: access-engine # flex-auth until the governed rename scope: catalog-stage # equivalent scope; not security-zones yet protected_action: >- OpenBao metadata apply, KV provision, verification, exec delivery, auth-capability handoff, native revoke, and lifecycle suspend/deactivate/destroy # Total by construction over every catalog stage plus unknown. # No implicit default — an unlisted value is a config error, not a fallback. # "fail_closed" means no protected side effect without a durable # access-engine / ActionAuthorization record. # "fail_open" here means the engine-unreachable residue: proceed only under # the existing lane-approval check (State Hub or local fixture), which is # itself a tracked gap relative to access-engine, not a manufactured allow. stance: build: fail_open test: fail_open prod: fail_closed unknown: fail_closed # Explicit, three-factor exception. Not a stance row and not a default. # All three must hold or the production gate remains closed. demo_exception: id: unsafe-local-demo requires: - "SECRETS_ENGINE_UNSAFE_DEMO=1" - "hub URL empty" - "OpenBao target is loopback" applies_to: prod note: >- Throwaway local demonstration only. Not a production residue and not available when any one factor is missing. on_apply: recorded_fields: - stance_stage - stance_failure_mode - stance_demo_exception - stance_decision_id # present only where a decision was resolved - approval_status # rejected when the stance refuses - error_type # DecisionError when fail_closed fires written_to: - "local JSONL (.evidence/evidence-YYYY-MM-DD.jsonl)" - "evidence_dir/outbox/ for load-bearing classes" - "best-effort State Hub progress note (attributive only)" never_recorded: "any secret material, token, password, or raw value" # §6.4 obligation 2 — the verdict is never cached. A retry of the same # canonical request digest inside the decision lifetime is the decision # being used as issued; a different resource is not. verdict_caching: none # §6.4 obligation 4 / §9.6 — attributive today. No control branches on the # presence of a local evidence record. Completeness is not claimed. reconstructability: bound: "§9.6 attributive — completeness is not claimed" declared_at: layer.yaml#evidence_bound