secrets-engine wrap writes a single-use OpenBao wrap token to a mode-0600 out-of-repo file and never prints it. KV reads and AppRole secret_ids are wrapped with a 15m TTL cap. Unwrapped secret payloads fail closed. Production wrap remains fail-closed. Assistant: grok Assistant-Session: 01a05f07-ae72-7781-9fcb-19efd61add00
184 lines
7.1 KiB
YAML
184 lines
7.1 KiB
YAML
# secrets-engine — NetKingdom security layer declaration
|
|
#
|
|
# Framework: net-kingdom/canon/standards/security-layer-model_v0.7.md
|
|
# Companion: net-kingdom/SECURITY-COMPANION.md
|
|
# Voice: INTENT.md (this repository's own declaration, §11)
|
|
# 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
|
|
standard_version: "0.7"
|
|
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
|
|
|
|
# §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
|