secrets-engine/pep-stance.yaml
tegwick 3cd9955ac9
Some checks are pending
CI Smoke / host-smoke (push) Waiting to run
CI Smoke / container-smoke (push) Waiting to run
Implement SECRETS-WP-0008 unblocked layer-model obligations
Load pep-stance.yaml as the live unreachable-engine gate and record named
stance fields on privileged evidence. Classify evidence, queue load-bearing
records in a local outbox, and add heartbeat/drain commands that never sit
on a mutation path. Publish proposed SSH-CA and secret-use evidence
contracts without adding an OpenBao SSH-CA write.

T02 (access-engine decision records) and T06 (no standing credential) stay
wait on external endpoints.

Assistant: grok
Assistant-Session: 01a04cea-cb33-7c63-bad7-c1b0f9f0076b
2026-08-29 12:52:55 +02:00

81 lines
3.3 KiB
YAML

# 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