ops-warden/pep-stance.yaml
tegwick 00145d705e
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
feat: complete local layer model v0.7 conformance work
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a06eaf-3425-7f92-a0c2-bb4aa4faebe4
2026-09-05 01:19:48 +02:00

104 lines
4.6 KiB
YAML

# ops-warden — PEP unreachable-engine stance map
#
# Framework: net-kingdom/canon/standards/security-layer-model_v0.7.md §6.4, §9.3, §9.7
# Rule of record: docs/adr/ADR-0009
# Validate: pytest tests/test_layer_conformance.py -k stance
#
# §6.4 obligation 3 requires a declared unreachable-engine stance that is total,
# scoped per zone, carries no implicit default and no per-call discretion, and is
# "published rather than held in code comments". §6.4 further requires every
# PEP-shaped consumer to PUBLISH its map so the maps can be inventoried. This
# file is ops-warden's, published because a map that lives only in a dataclass
# default is not published — it is merely written down.
#
# The property that makes this worth reading: it is asserted equal to the shipped
# default in src/warden/config.py (PolicyConfig.failure_modes) by
# tests/test_layer_conformance.py. A published map that may drift from the code
# is worse than none, because it invites reliance it cannot support.
schema_version: "0.1"
framework: netkingdom-security-layer-model
standard_version: "0.7"
repository: ops-warden
pep_shape: true
declared_by: docs/adr/ADR-0009
protected_action: "SSH certificate issuance (warden sign / cert_command)"
decision_engine: access-engine # flex-auth until the governed rename
scope: security-zone # security-zones_v0.1 membership of the TARGET workload
# Total by construction: every zone in security-zones_v0.1, plus the two
# non-zone outcomes. No implicit default — an unlisted value is a config error,
# not a permissive fallback.
stance:
z0-experimental: fail_open
z1-operational: fail_open
z2-protected: fail_open
z2-continuity: fail_open
z3-critical: fail_closed
unknown: fail_open # versioned build profile (ADR-0009); explicit, never inferred
not-applicable: fail_closed
# What happens when the stance is applied. §6.4 obligation 1 requires a decision
# record for a protected side effect; where the engine is unreachable there is no
# decision to hold, so ops-warden records the APPLICATION OF THE STANCE instead.
# See the assessment note: obligation 1 as written admits no such case.
on_apply:
recorded_fields:
- policy_zone
- policy_failure_mode
- policy_decision_id # present only where a decision was actually rendered
- outcome
written_to:
- "signatures log (src/warden/ca.py)"
- "audit.jsonl (src/warden/audit.py)"
never_recorded: "any secret material, any certificate private key"
# §6.4 obligation 2 — the verdict is never cached. Input claims (zone membership,
# compiled from the flex-auth registry snapshot) are cached under their own
# freshness rules; the answer is not.
verdict_caching: none
input_claim_caching: "registry/flex-auth/production_registry_snapshot.json, rebuilt by scripts/build_flex_auth_registry.py"
# §6.4 obligation 4 — reconstructability, bounded by §9.6. ops-warden's audit
# emission on this lane is deliberately non-atomic and therefore ATTRIBUTIVE, not
# load-bearing: no control branches on the presence of a signing record
# (`warden activity` displays it; nothing gates on it). Registered in §13.
reconstructability:
bound: "§9.6 attributive — completeness is not claimed"
declared_at: wiki/AuditTrail.md
# §9.7.2 — the certificate-verification PEP has no active revocation channel.
# A previously allowed certificate remains usable until its enforced TTL expires,
# so the visibility deadline is exactly the maximum issued lifetime per actor type.
revocation_visibility:
boundary: "SSH certificate verification at the target host"
mechanism: ttl_expiry
revocation_channel: none
deadline_hours:
adm: 48
agt: 24
atm: 8
note: >-
No CRL or KRL distribution exists. Host-side authorization belongs to
railiance-infra; shortening or actively recalling this window is a joint
design question, not an implied capability of ops-warden.
# §9.6 — signing evidence is attributive, not load-bearing. Measurement as of
# 2026-09-04 found three signature records across 79 calendar days, concentrated
# on only two active days (1 event on 2026-06-17; 2 within 40 minutes on
# 2026-08-22). That bursty operator-driven sample cannot support a useful rate
# threshold, so cadence is explicitly deferred instead of fabricated.
emission_cadence:
classification: attributive
status: deferred
measured_as_of: "2026-09-04"
observed_window:
first: "2026-06-17T23:18:33Z"
last: "2026-09-04T21:21:30Z"
signature_records: 3
active_signature_days: 2
daily_counts:
"2026-06-17": 1
"2026-08-22": 2
reason: "operator-driven issuance is too sparse and bursty for a meaningful rate threshold"