secrets-engine/layer.yaml
tegwick 8a48cb05df Apply GH-DEC-2026-017: INTENT.md governs, layer.yaml is derived, no version
Verified against gate-house's committed ruling (decisions/decisions.md,
GH-DEC-2026-017) and amendments A9-A13, then ops-warden's reference change set
(a70f559, wiki/playbooks/netkingdom-layer-declaration.md). They agree.

layer.yaml: standard_version removed; derived: true and derived_from:
INTENT.md added; declared_by kept. INTENT.md frontmatter never carried
standard_version, but its standard: value was a version-pinned path; it is
de-versioned as the reference instance did. No layer value is re-spelled:
INTENT.md still says Engine and layer.yaml still says engine.

The checker changes in the same commit because it listed standard_version as
a required key: removing the field alone would have made a conforming
declaration exit 2 MALFORMED. It now reads INTENT.md as the governing form,
requires the derived marking, rejects a returning standard_version in either
form, checks both layer values against the closed four-token vocabulary
(Taxonomy included) after an ASCII fold, and reports a post-fold disagreement
between the forms as a finding rather than resolving it by precedence.

Tests assert the fold, not per-file spelling, and cover fold agreement, a
real disagreement, the closed vocabulary and a returning version. Full suite
430 passed.

role:, pep-stance.yaml and schema_version are untouched (not ruled). Still
open: where the removed version lives in a derived conformance record; asked
of gate-house by ops-warden (4220413a), followed rather than chosen here.

Closes the SECRETS-WP-0008 note that waited on the reference form.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 63291@bnt-lap001
Assistant-Session: 8bd77868-ca68-4f49-bb1e-d539ecc0d703
2026-09-21 07:37:53 +02:00

195 lines
7.5 KiB
YAML

# secrets-engine — NetKingdom security layer declaration
#
# Framework: net-kingdom/canon/standards/security-layer-model
# Companion: net-kingdom/SECURITY-COMPANION.md
# Voice: INTENT.md (this repository's own declaration, §11)
#
# DERIVED ARTIFACT (§11, GH-DEC-2026-017 §1 / A11). INTENT.md's frontmatter
# `layer:` key is the declaration and governs; this file derives from it and
# must agree with it. `engine` here and `Engine` there are one token: §3's
# vocabulary is closed and compared ASCII case-insensitively (GH-DEC-2026-017
# §2 / A9), so nothing is re-spelled. No standard version is carried here
# (GH-DEC-2026-017 §5 / A12).
# Validate: python3 scripts/check_layer_conformance.py
#
# §11 requires a machine-readable form because prose cannot distinguish a
# declaration from a transcribed review. ops-warden offered the layer.yaml
# shape estate-wide; this file is that shape adapted for a Lifecycle engine
# rather than a Staff repository.
#
# §5 (Staff never touches Tooling) does not apply to this repository's OpenBao
# client. A Lifecycle engine is the deterministic API over Tooling it fronts.
# OpenBao contact here is owned, not a §5.3 gap.
schema_version: "0.1"
framework: netkingdom-security-layer-model
derived: true
derived_from: INTENT.md
repository: secrets-engine
layer: engine
role: lifecycle
declared_by: INTENT.md
declared_at: "2026-08-29"
# §3.3: a Lifecycle engine is a deterministic API over Tooling it owns.
# OpenBao remains the vault; this engine fronts it.
owned_tooling:
- id: openbao-lifecycle
tooling: OpenBao
modules:
- src/secrets_engine/openbao.py
operations:
- "bao policy/auth/kv subprocess adapter"
- "CAS-aware KV create/patch via JSON input files, never argv values"
- "JWT login via JSON input files; issued engine tokens self-revoke"
- "response wrapping via -wrap-ttl; wrap token never in argv evidence"
note: >-
This is the owned Lifecycle contact, not a Staff §5 shape. A new direct
OpenBao client outside the listed modules is a finding.
# §6: no repository other than access-engine exposes an authorization decision
# surface. secrets-engine consumes and validates a supplied ActionAuthorization
# object; it does not evaluate policy.
decision_surfaces_exposed: none
# §6.4 — apply, provision, exec, handoff, revoke, and lifecycle mutations
# cause protected side effects. Being PEP-shaped does not change the layer.
pep_shaped: true
pep_stance: pep-stance.yaml
protected_actions:
- apply
- provision
- verify
- exec
- handoff
- revoke
- lifecycle-suspend
- lifecycle-deactivate
- lifecycle-destroy
- session-revoke
- wrap
- rotate
- lifecycle-compromise
- lifecycle-reactivate
# §13 proposed capabilities. Owner status is proposed, not assented, until
# the surface exists in this repository's own contract.
proposed_capabilities:
- id: ssh-ca-signing-surface
state: unowned-capability
capability: >-
Deterministic engine API for OpenBao SSH-CA signing, so a Staff PEP
(ops-warden) does not hold a direct VaultCA write.
intended_owner: secrets-engine
owner_status: proposed
contract: docs/ssh-ca-signing-contract.md
blocked_on: >-
Contract published; ops-warden has not assented. No OpenBao SSH-CA
write is added to this CLI until that assent. ops-warden continues
to sign through its declared §5.3 gap. This repository accepts the
engine surface and declines operational ownership of the SSH access
lane.
review: "2026-11-28"
consequence: >-
ops-warden's ssh-ca-signing-write gap remains the production path.
- id: secret-use-evidence
state: unowned-capability
capability: >-
Lease, revocation, mount, rotation, and delivery-session metadata
exposed as an engine surface for kings-guard secret-abuse posture.
intended_owner: secrets-engine
owner_status: proposed
contract: docs/secret-use-evidence-contract.md
blocked_on: >-
Surface shipped as `secrets-engine secret-use snapshot`; cadence is the
declared 1d heartbeat. kings-guard assented 2026-09-01 (message
75ebd2cc-a166-4676-94aa-deef2791c0c9) and has not yet admitted the
snapshot as an observation input. Completeness is not claimed.
review: "2026-11-28"
consequence: >-
kings-guard secret-abuse posture stays fixture-driven.
# Contacts that are not Tooling, recorded so the check is total.
non_tooling_clients:
- id: state-hub-decisions-and-progress
target: state-hub
layer: not-catalogued
modules:
- src/secrets_engine/decisions.py
- src/secrets_engine/evidence.py
operation: "HTTP GET /decisions/{id} and POST /progress/"
write: true
note: >-
Outside §5 by the scope rule: State Hub is not a §4 Tooling row.
Decisions consumed from it are a gap relative to access-engine, not a
Tooling contact. Progress notes are not a security state plane.
- id: access-engine-action-authorization
target: access-engine (flex-auth)
layer: engine
modules:
- src/secrets_engine/authorization.py
operation: "Local validation of a supplied ActionAuthorization object"
write: false
note: >-
Engine-to-engine consume, not a decision surface. The durable State Hub
endpoint that would serve the object is not yet available; production
live actions therefore fail closed (see pep-stance.yaml).
- id: approval-engine-consume
target: approval-engine
layer: engine
modules:
- src/secrets_engine/approval_consume.py
operation: "POST /v1/approvals/{id}/consume before a production OpenBao write"
write: true
note: >-
PEP CAS consume under GH-DEC-2026-003. Not a decision surface. Conflict,
unavailability, or a missing binding fail closed; OpenBao is not
called. Production also remains fail-closed until a durable consume
binding is served.
- id: key-cape-service-auth-scaffold
target: key-cape
layer: tooling
modules:
- src/secrets_engine/service_auth.py
- src/secrets_engine/engine_auth.py
operation: "HTTPS client_credentials exchange; OpenBao JWT login when the platform contract is present"
write: false
note: >-
key-cape is catalogued Tooling. The consumer exchanges a service JWT and
logs in only when SECRETS_ENGINE_OPENBAO_JWT_LOGIN names a published
mount/role contract. Failure never falls back to bootstrap or BAO_TOKEN.
The platform-owned role remains unpublished, so auto still uses the
named bootstrap/env providers.
- id: audit-core-outbox-drain
target: audit-core
layer: engine
modules:
- src/secrets_engine/evidence.py
operation: "Optional POST /v1/events from secrets-engine evidence drain"
write: true
note: >-
Engine-to-engine emit. Never on the mutation path. Empty URL skips
delivery and leaves the local outbox in place. Sender binding in
audit-core is not yet admitted.
# §9.6 — what this repository may claim about evidence it writes today.
evidence_bound:
classification: evidence-classification.yaml
proves:
- local JSONL records that were written were not rewritten by this engine
- load-bearing records queued in evidence_dir/outbox/ were written
does_not_prove:
- that a record was ever sent to audit-core
- absence of a record as evidence of non-occurrence
- completeness of the trail
destination_today: "local JSONL; load-bearing also queued locally; attributive State Hub notes"
intended_destination: audit-core
completeness_claimed: false
no_control_branches_on_presence: true