Replace the gate-house review note with this repository's own declaration: INTENT.md frontmatter, layer.yaml, and a published PEP stance map. SCOPE.md and agent boundary docs now match that layer. The review under history/ identifies the implementation remainder; SECRETS-WP-0008 is the follow-on workplan. SECRETS-IN-0001 is closed. The layer is not contested. Catalog "custody" is a finding: OpenBao owns custody, this engine owns the lifecycle API over it. SSH-CA signing is accepted as a proposed engine API and declined as a Staff lane. Assistant: grok Assistant-Session: 01a04cea-cb33-7c63-bad7-c1b0f9f0076b
18 KiB
SCOPE
Implemented capability boundary for agents and contributors. Aspirational direction belongs in
INTENT.md; current work and operational gates belong inworkplans/.Layer declaration (accepted model v0.7): Engine / Lifecycle. Machine-readable form:
layer.yaml. PEP stance:pep-stance.yaml. This file states what the implementation currently does inside that layer; it does not restate doctrine.
One-liner
secrets-engine is the Lifecycle engine for cataloged credential work: a decision-gated Python CLI that validates non-secret lane metadata and orchestrates narrowly scoped OpenBao policy, AppRole, provisioning, verification, delivery, routing, handoff, and revocation actions.
It is a deterministic API over OpenBao, not a vault, not a policy decision point, not an identity provider, and not a general secrets API.
Implemented Capabilities
Catalog and validation
- Loads YAML catalog entries for
kvandauth-capabilitylanes. - Models
build,test, andprodstages, exact mounts/paths/fields, consumers, approvals, delivery modes, verification, lifecycle ownership, workload-delivery metadata, andstandard/highrisk. - Distinguishes engine-managed and existing KV mounts, and engine-managed, existing, or absent native delivery auth.
- Rejects malformed entries, inline secret-looking values, wildcard paths, unsupported modes, bootstrap-only approval for high-risk lanes, and high-risk entries without rotation/deactivation owners.
- Records existing ESO/Kubernetes/OIDC workload delivery as metadata only; it does not operate those delivery systems.
Decision-gated planning and OpenBao metadata apply
- Resolves a catalog lane by catalog id or
approval.decision_ref. - Resolves legacy lane decisions from State Hub by id, with tracked local YAML mirrors retained only for non-production and explicit throwaway demos. This is not an access-engine decision record.
- Fails every production live command closed while there is no durable
access-engine / ActionAuthorization record. That fail-closed row is the
published unreachable-engine stance for
prodinpep-stance.yaml. A local mirror can unlock a prod-labeled lane only when an explicit unsafe-demo switch, disabled Hub URL, and loopback OpenBao target are all present. Plans andapply --dry-runremain usable. - Builds and validates the flex-auth
ActionAuthorizationprofile, including exact lane/stage/action/target/actor/purpose matching, bounded validity, State Hub authority, request digest and decision binding, accepted policy package/version, and an independently required distinct-approver threshold. Validation is consume-only; this process does not evaluate policy. - Renders guarded OpenBao plans for exact consumer ACL policies and AppRoles.
- Applies policy and AppRole metadata idempotently. Existing mounts render a non-mutating check and are never created by apply.
- Rejects stage mismatches, wildcard paths, broad-admin names, forbidden
sys/, token, identity, root, or sudo semantics, and auth-capability paths outside an exact allowlist.
KV provisioning
- Imports one declared field from a mode-0600 file outside Git worktrees.
- Generates random values only for non-production lanes.
- Keeps values out of CLI output and evidence records.
- Uses a CAS-aware create/patch primitive. Secret data is passed through a
mode-0600 temporary JSON input reference that is removed in a
finallypath, never as a raw subprocess argument. Existing-path updates preserve unmentioned sibling fields and stale-version writes fail closed.
Verification
- KV positive verification logs in through the lane AppRole and reports field
presence without printing values. With no
--field, it checks every declared field; an explicit--fieldnarrows the check. - KV negative verification requires a real unrelated token supplied through a mode-0600 file outside Git and checks that it cannot read the path. Missing unrelated identity material fails closed without a backend probe.
- Auth-capability verification checks the AppRole token's capabilities on exact allowlisted and denial-probe paths.
These are bounded policy/presence probes. A throwaway OpenBao integration test proves an overlapping unrelated policy is detected. Production still needs a reviewed owner/source for each unrelated identity; the engine does not mint or select that identity itself. Verification does not yet exercise a provider operation or produce OpenBao audit-request correlation.
Exec-time delivery
exec-envfetches one declared field through the lane AppRole and injects it into a child process environment.npm-configcreates a temporary mode-0600 npm config containing an environment reference rather than the token, injects the value only into the child, and deletes the config afterward.- Child stdout and stderr are combined and streamed through token-pattern and exact-value redaction.
- Undeclared fields and undeclared/unsupported exec modes are rejected before value fetch.
The OpenBao KV response is parsed in the parent process, so every field stored
at the path crosses that process boundary even though only the selected field is
injected. Exec and verification use scoped AppRole sessions that explicitly
self-revoke in a finally path. Non-secret evidence contains only an accessor
fingerprint and establishment/revocation outcome; TTL/use limits remain cleanup
backstops.
Auth-capability handoff
- Models narrow non-KV AppRole grants such as exact
ssh/sign/<role>update capability. - Mints
role_id/secret_idmaterial only after approval and writes it to distinct mode-0600 files outside Git worktrees without printing thesecret_id.
The cataloged standalone warden-sign AppRole is currently parked by governance
and must not be applied as a break-glass or recovery path. OpenBao being sealed
cannot be recovered through that AppRole.
Routing and evidence
routereturns a non-secret pointer containing lane ownership, decision status, metadata/value-presence booleans, missing declared field names, readiness, and a safe next command. Every declared field must be present.- Records scrubbed local JSONL evidence and posts a minimal State Hub progress
event on a best-effort basis. Posts carry stable idempotency/source headers.
Each requested State Hub delivery receives an append-only local
delivered,queued,failed, orskipped-no-topiccompanion record; edge-relay queued receipts retain only the non-secret outbox id. This trail is attributive: completeness is not claimed, and it is notaudit-core. - Every live privileged CLI handler records an attempt before lane-approval resolution and a terminal success, verification failure, rejection, interruption, or typed backend/input failure. Failure evidence contains the exception class and approval state, never exception prose.
auditsummarizes allowlisted local lane evidence: action/result counts, canonical decision references, session cleanup outcomes, and State Hub delivery outcomes. It never re-emits arbitrary evidence detail.- Keeps OpenBao audit logs as the backend source of truth.
The engine recognizes edge-relay queued receipts but does not own or initiate outbox replay. Direct State Hub failure remains locally visible. Route and audit do not replace exact-action authorization or OpenBao audit logs.
Steady-state service-auth scaffold
- Implements an explicit KeyCape
client_credentialsexchange for the acceptedsecrets-engine-openbaoservice identity. - Reads the confidential-client secret only from a mode-0600 file outside Git, sends it through HTTP Basic authentication, and rejects ID/refresh tokens.
- Preflights the exact issuer, subject, audience, principal type, tenant, role, scope, assurance, RS256 algorithm, and 15-minute lifetime. The in-memory JWT is excluded from object representations and is renewed at the three-minute boundary.
- Never retries into or falls back to bootstrap, operator, or AppRole auth.
This provider is deliberately not connected to OpenBao. Signature verification and token issuance remain with the platform-owned exact-bound OpenBao JWT role, whose mount/role contract is still outstanding. Treat their output as operational guidance, not complete attestation for high-risk lanes.
Revocation currently available
- For engine-managed native auth, live
revokedeletes the AppRole and policy. - For KV lanes, ordinary revoke explicitly preserves all KV metadata/versions.
- Externally managed delivery auth and workload delivery are reported as preserved and are not mutated.
lifecycle suspendremoves only the managed AppRole and preserves its policy for reviewed re-apply.lifecycle deactivateremoves managed native AppRole/policy objects while preserving KV custody.lifecycle destroy --dry-runrenders managed-auth removal plus irreversible KV metadata deletion. Live destroy is currently disabled even with exact catalog-id confirmation; it will remain closed until the canonical exact-action approval contract inSECRETS-WP-0007-T04is enforced.
These operations do not manage external workload delivery. There is currently no general lease/accessor operator command, rotation command, compromised state, or persistent/reversible lane state machine.
CLI Surface
secrets-engine catalog list|show
secrets-engine decision inspect
secrets-engine plan
secrets-engine apply [--dry-run]
secrets-engine provision
secrets-engine verify
secrets-engine handoff
secrets-engine exec
secrets-engine policy publication
secrets-engine route
secrets-engine revoke [--dry-run]
secrets-engine lifecycle suspend|deactivate|destroy
secrets-engine audit <catalog-id> [--json]
The implemented exec adapters are exec-env and npm-config. read-check is
verification, approle-login is auth-capability handoff metadata, and
exec-file/wrapped are reserved schema names without executable adapters.
Proven Operationally
- The whynot-design npm pilot completed a real publish through native
secrets-engine execwithout placing the token in the parent shell. - Throwaway OpenBao integration tests exercise plan, apply, provisioning, positive/negative verification, exec delivery, routing, revocation, and idempotent metadata apply.
- Five existing high-risk
platformmount lanes have reviewed catalog metadata and guarded dry-run plans. Their native AppRoles are not live: workplanSECRETS-WP-0006waits on per-lane approval, production authority, live positive/negative verification, and routing cutover.
Not Implemented
- A service API, daemon, UI, queue, scheduler, or remote multi-user service.
- OpenBao JWT login and platform materialization for the implemented KeyCape service-auth provider.
- Native
exec-fileor response-wrapped delivery. - Provider-side rotation or coordinated multi-consumer rollout.
- First-class rotate, compromise, reactivate, lease-status, or audit report commands; lifecycle operations currently execute plans without persistent lane state.
- Resolution of a durable access-engine decision record / State Hub ActionAuthorization and wiring its validated approval threshold to each production handler. The consumer validator exists; the serving endpoint does not, so live production remains fail-closed.
- Direct access-engine evaluation, JWT signature verification, or identity authentication. KeyCape claims receive only a consumer preflight; OpenBao is responsible for cryptographic JWT validation.
- Runtime tenancy isolation;
org,repo, consumers, and stages are catalog metadata plus local path/policy guards, not a tenant control plane. - Management or health verification of ESO, Kubernetes Secrets, deployments, provider accounts, SSH issuance, tunnels, or remote transport.
- Any backend other than the local
bao/vaultCLI speaking to OpenBao. - An SSH-CA signing engine API. ops-warden still signs through its declared OpenBao gap; this repository has accepted that surface as proposed only.
- A secret-use evidence engine API for kings-guard.
routeandauditare operator summaries over local JSONL, not an observation surface. - Emission to
audit-core. Evidence today is local JSONL plus best-effort State Hub progress notes, classified attributive, completeness not claimed. - Named stance-application records (stage, failure mode, decision id present
only where rendered). Fail-closed production currently surfaces as a
DecisionErroron the privileged-evidence path. - Security-zone membership as a request claim. PEP scope is catalog stage.
System Boundary
- OpenBao / railiance-platform (Tooling) owns custody, policy enforcement, leases, and backend audit. secrets-engine is the Lifecycle API over it.
- access-engine (
flex-auth) owns authorization decisions. secrets-engine consumes a decision record or applies its published unreachable-engine stance; it does not evaluate policy. - approval-engine owns the durable approval object. secrets-engine may consume an approval as an input claim and must not store or mutate one.
- gate-house owns security doctrine. Doctrine reaches this engine only as it already reached the decision, never as a side channel.
- audit-core owns evidence custody and integrity. Local JSONL and State Hub notes are not that archive.
- user-engine / key-cape own identity, OIDC, MFA, and claims.
- ops-warden issues SSH certificates (Staff PEP) and routes non-SSH credential needs here; it does not vend their values. The SSH-CA write surface is a proposed engine API, not a transferred lane.
- ops-bridge owns tunnels and remote execution transport and may consume a scoped delivery path.
- workload/platform repositories own ESO/Kubernetes delivery, provider rotation, and application health.
- info-tech-canon / net-kingdom own canonical terminology and the cross-system security boundary. gate-house owns the layer model.
Canonical boundary:
net-kingdom/docs/secrets-engine-security-infrastructure-boundary.md.
Layer model: net-kingdom/canon/standards/security-layer-model_v0.7.md.
Working companion: net-kingdom/SECURITY-COMPANION.md.
Security Rules
- Never place raw secret values in Git, State Hub, chat, prompts, workplans, normal logs, or evidence.
- Never render or cache an authorization decision. Catalog admission, a dry-run, an old workload CCR, or a local fixture is not an access-engine allow.
- Never treat silence from
access-engineas permission. Production live actions fail closed; any unreachable-engine residue must be the published stance, recorded, never implicit. - Never mutate an existing shared mount or replace workload delivery by implication.
- Never add KV destruction back to ordinary
revoke; irreversible custody destruction requireslifecycle destroy, exact confirmation, and a distinct approved action. The live path remains disabled until that approval contract exists. - Keep bootstrap and handoff material outside repositories with mode 0600 and explicit expiry/revocation handling. Bootstrap is not an implicit fallback from service identity.
- Never claim that local evidence or a missing record proves occurrence or non-occurrence. Completeness is not claimed.
Layer-model obligations (current vs intended)
| Obligation | Current | Intended |
|---|---|---|
| Layer declaration | INTENT.md frontmatter + layer.yaml |
Keep in this repository's own voice |
| One decision point | Consumer validator for ActionAuthorization; production live fail-closed | Consume an access-engine decision record before every protected side effect |
| PEP stance | pep-stance.yaml; prod fail-closed, build/test fail-open relative to access-engine |
Published map equals shipped behaviour; stance application recorded by name |
| Evidence bound | Attributive local JSONL + best-effort State Hub | Load-bearing vs attributive classified; load-bearing to audit-core with cadence |
| SSH-CA surface | Proposed; not shipped | Engine API for ops-warden's Staff PEP; lane stewardship stays with ops-warden |
| Secret-use evidence | route / audit over local JSONL |
Engine surface of lease/revocation/mount/rotation metadata |
| Agent credential | Bootstrap token file still accepted; KeyCape scaffold unwired | Per-task, time-bounded service identity; no standing engine credential |
Where Current Work Lives
workplans/is the source of truth for open work and operational gates.docs/hardening-backlog.mdtracks exit from bootstrap mode.history/contains dated capability and intent assessments.INTENT.mdremains the stable aspirational direction.layer.yamlandpep-stance.yamlare the layer-model declaration surface.
Provided Capabilities
type: security
title: Guarded OpenBao lane planning and metadata apply
description: Validates cataloged KV and auth-capability lanes, renders exact policy/AppRole plans,
and applies approved metadata while rejecting missing decisions, stage mismatches, wildcards,
broad-admin names, and forbidden capability paths. Existing mounts are check-only.
keywords: [secrets, openbao, policy, approle, catalog, decision, stage, least-privilege]
type: security
title: AppRole-scoped exec delivery
description: Fetches one declared KV field through a lane AppRole and injects it into a child
process using exec-env or a temporary npm config, with output redaction, explicit scoped-token
self-revocation, and non-secret cleanup evidence. This is CLI-local delivery; exec-file, wrapping,
and service delivery are absent.
keywords: [secrets, delivery, exec, npm, injection, redaction, openbao]
type: security
title: Scoped OpenBao auth-capability handoff
description: Generates an exact-path policy/AppRole plan and writes role-id/secret-id material to
strict out-of-repo files after approval. Operational use remains subject to lane-specific governance.
keywords: [openbao, approle, auth-capability, handoff, least-privilege]
type: governance
title: Non-secret routing and evidence pointers
description: Reports decision/readiness metadata and records scrubbed local and best-effort State Hub
evidence without returning secret values. Append-only delivery receipts expose State Hub failures,
and an allowlisted audit command summarizes lane operations and cleanup. KV verification can attest a
supplied real unrelated identity, but the engine does not own identity selection. This is attributive
local evidence, not audit-core and not a secret-use observation API.
keywords: [routing, evidence, state-hub, audit, secrets]