2026-08-29 11:57:47 +02:00
---
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
# THE layer declaration (§11, GH-DEC-2026-017 §1). `layer.yaml` is derived from
# this frontmatter and must agree with it; it does not govern. Comparison of the
# §3 vocabulary is ASCII case-insensitive, so `Engine` here and `engine` there
# are the same value and neither is re-spelled (GH-DEC-2026-017 §2).
2026-08-29 11:57:47 +02:00
layer: Engine
role: Lifecycle
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
# No standard version here or in the sidecar (GH-DEC-2026-017 §5 / A12): the
# declared layer is a standing property that does not change when the standard
# is revised. Version-scoped state belongs in the derived conformance record.
standard: net-kingdom/canon/standards/security-layer-model
2026-08-29 11:57:47 +02:00
companion: net-kingdom/SECURITY-COMPANION.md
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
declaration: layer.yaml # derived form; this frontmatter governs
2026-08-29 11:57:47 +02:00
pep_stance: pep-stance.yaml
declared_at: "2026-08-29"
---
2026-06-28 12:28:45 +02:00
# INTENT
2026-08-29 11:57:47 +02:00
> **Layer: Engine. Role: Lifecycle.** This is this repository's own declaration
> under the accepted NetKingdom Security Layer Model
2026-10-11 02:21:25 +02:00
> (`net-kingdom/canon/standards/security-layer-model_v0.8.md`) and its working
2026-08-29 11:57:47 +02:00
> companion (`net-kingdom/SECURITY-COMPANION.md`). The machine-readable form
> required by §11 is `layer.yaml`. A layer stated about this repository by
> another repository is not a declaration; this file, in this repository's
> voice, is.
>
2026-10-22 17:46:15 +02:00
> secrets-engine is a tool of automation for one capability: the cataloged
> credential lane and its lifecycle. It encapsulates that work in one
> consistent interface. The same authoritative inputs — catalog entry,
> access-engine decision record, and OpenBao state — yield the same plan,
> apply, delivery, and lifecycle result. That determinism is why this
> repository is an Engine, not Staff, even though operators and agents invoke
> it at runtime.
2026-08-29 11:57:47 +02:00
>
2026-10-22 17:46:15 +02:00
> This shape is gate-house ADR-015 and `ArchitectureBlueprint.md` §2.2,
> accepted 2026-10-22. The same wording is assembled in proposed
> `security-layer-model_v0.9` §3.3. The accepted statute and companion remain
> v0.8 until that successor is adopted. v0.8's PEP obligations still bind.
>
> **It enables the capability. It is not access control.** `access-engine`
> (today `flex-auth`) renders whether authority exists, including whether an
> operator may start or call an instance. gate-house authors the doctrine that
> may reach that decision only as a request claim or a versioned policy rule.
> OpenBao is Tooling: custody, policy enforcement, leases, and backend audit.
> This engine does not hold those records. Other engines may use OpenBao for
> other capabilities. This engine materializes an already-rendered decision
> into scoped OpenBao work. A credential is an artifact of authority, never
> its source. Holding the credential inside the process does not make this
> engine a gate on the store.
>
> **One library, three manifestations.** The library validates, explains, and
> plans without the store credential. The CLI is that library in a process. A
> service is the same process kept running for one stage. At start the process
> is injected with that stage's OpenBao credential. The credential enables the
> capability and is not returned to the operator. A use-privilege does not
> confer it. An operator who may delegate can assign the work to an operator
> who may use the instance. The assignment transfers neither privilege.
2026-08-28 20:33:43 +02:00
>
2026-08-29 11:57:47 +02:00
> **It is PEP-shaped.** Apply, provision, exec delivery, handoff, suspend,
> deactivate, and destroy cause protected side effects, so the four PEP
> obligations in §6.4 bind: no side effect without a decision record or a
> recorded stance; no replay of a verdict outside its binding and lifetime;
> a published unreachable-engine stance at `pep-stance.yaml`; reconstructability
> bounded by §9.6. Being PEP-shaped does not change the layer.
2026-08-28 20:33:43 +02:00
>
2026-08-29 11:57:47 +02:00
> **Proposed surfaces, not yet assented as shipped APIs.** ops-warden has
> declared its SSH-CA signing write as an engine gap with intended owner
> secrets-engine. kings-guard has proposed secret-use evidence against this
> engine. This repository **accepts both as proposed Lifecycle surfaces** and
> **declines operational SSH-lane stewardship**: `ops-warden` remains the Staff
> PEP that requests a certificate after a decision. What belongs here is the
> engine API those Staff repositories should call instead of OpenBao. Until
> those surfaces exist, the gaps stay proposed, not silently taken.
2026-08-28 20:33:43 +02:00
>
2026-08-29 11:57:47 +02:00
> **Finding on the §4 catalog cell.** The catalog row currently says this
> repository owns "credential abstraction, custody, lifecycle". Custody belongs
> to OpenBao. This engine owns the lifecycle API *over* that custody. The
> wording should not assign a Tooling property to an Engine.
2026-08-28 20:33:43 +02:00
2026-06-28 12:28:45 +02:00
> This file captures why this repository exists, the direction it is moving
> toward, and the kind of system it is meant to become. It is intentionally
> aspirational and stable, not a description of current implementation.
2026-08-29 11:57:47 +02:00
> See `SCOPE.md` for what is implemented today.
2026-06-28 12:28:45 +02:00
## One-liner
2026-10-22 17:46:15 +02:00
**secrets-engine enables cataloged credential lifecycle: one deterministic
library over OpenBao, manifested as a CLI or as a service for a single stage,
with that stage's credential injected at start and never returned to the
operator.**
2026-06-28 12:28:45 +02:00
## Why This Exists
Secret management is too important to be handled through scattered manual UI
steps, copied commands, chat handoffs, and ad hoc token files.
2026-08-29 11:57:47 +02:00
OpenBao is the right Tooling for custody, policy, lease, and audit. It is not,
by itself, the right daily interaction surface for operators, agents, workloads,
and approval workflows. Direct use of OpenBao UI and CLI surfaces has already
produced avoidable friction:
2026-06-28 12:28:45 +02:00
- approved decisions still require a human to bridge low-level OpenBao details;
- agents and operators hit interface mismatches before reaching the security
work they were trying to complete;
- build, test, and production need different levels of privilege and ceremony;
- secret values must never move through chat, Git, prompts, State Hub messages,
or workplans;
2026-08-29 11:57:47 +02:00
- Staff repositories such as ops-warden need an Engine API for credential and
scoped-capability work, not a direct OpenBao client and not secret-vending
responsibility of their own.
2026-06-28 12:28:45 +02:00
2026-08-29 11:57:47 +02:00
This repository exists to capture that complexity once, behind a stable,
2026-10-22 17:46:15 +02:00
deterministic, and auditable interface that is more reliable and more
efficient than doing the same OpenBao work by hand.
2026-06-28 12:28:45 +02:00
## The Mission
2026-08-29 11:57:47 +02:00
To provide a decision-aware Lifecycle engine that can:
2026-06-28 12:28:45 +02:00
2026-08-29 11:57:47 +02:00
- consume an access-engine decision and refuse to proceed without one, or
record the application of a declared unreachable-engine stance in its place;
- translate that decision into narrowly scoped OpenBao changes or capability
2026-06-30 00:52:05 +02:00
grants;
2026-06-28 12:28:45 +02:00
- operate with distinct build, test, and production privilege layers;
2026-06-30 00:52:05 +02:00
- deliver secrets and scoped capabilities to commands and workloads without
printing or storing raw values in coordination systems;
2026-08-29 11:57:47 +02:00
- emit non-secret evidence under the §9.6 bound — the archive proves records
it holds were not altered or truncated after arrival, not that every event
was sent, and not that absence means non-occurrence;
2026-06-28 12:28:45 +02:00
- make routine secure work fast enough that operators and agents actually use
2026-08-29 11:57:47 +02:00
the Engine path instead of touching OpenBao.
2026-06-28 12:28:45 +02:00
## Core Principles
2026-08-29 11:57:47 +02:00
### 1. Decision elsewhere, materialization here
2026-06-28 12:28:45 +02:00
2026-08-29 11:57:47 +02:00
Secret establishment, access, rotation, and deactivation start from an
access-engine decision record naming the request it was rendered for.
This engine may automate the work after that decision; it does not render,
cache, or substitute one. Compiled catalog data that would determine an
2026-09-02 01:06:50 +02:00
outcome before the engine runs is still deciding, and is forbidden. For a
privileged production side effect, a successful approval-engine CAS consume
must precede the OpenBao call (`GH-DEC-2026-003` ). Holding an ALLOW is not
authority to act.
2026-06-28 12:28:45 +02:00
2026-10-22 17:46:15 +02:00
### 2. OpenBao is Tooling; this engine enables one capability over it
2026-06-28 12:28:45 +02:00
2026-10-22 17:46:15 +02:00
OpenBao remains the vault, policy, lease, and audit backend. Several engines
may use that store. secrets-engine enables the catalog, validation, delivery,
scoped capability handoff, and lifecycle operations, and it is the
operator/agent/Staff interface for that capability. It does not own custody,
it is not the store's only client, and it does not decide who may use an
instance. Staff does this capability through the engine rather than by hand.
Another engine's different capability over OpenBao is outside this intent.
2026-06-28 12:28:45 +02:00
2026-08-29 11:57:47 +02:00
### 3. Stage-aware privilege
2026-06-28 12:28:45 +02:00
Build, test, and production are separate security contexts. Each has its own
OpenBao role, policy boundary, approval expectation, TTL limits, and delivery
2026-08-29 11:57:47 +02:00
rules. Stage is the current equivalent scope for the PEP stance map until
security-zone membership is consumed as a claim.
2026-06-28 12:28:45 +02:00
2026-08-29 11:57:47 +02:00
### 4. No secret values in coordination surfaces
2026-06-28 12:28:45 +02:00
Git, State Hub, workplans, chat, prompts, issue comments, and normal logs carry
only non-secret metadata. Raw values are delivered through OpenBao, wrapped
responses, local exec-time injection, or short-lived bootstrap files with strict
permissions.
2026-08-29 11:57:47 +02:00
### 5. Least friction without broad power
2026-06-28 12:28:45 +02:00
2026-08-29 11:57:47 +02:00
The common path should be one clear command or Engine API call. That ease must
not require handing platform-root or platform-admin power to routine
automation, and it must not mint standing credentials for agents. Agent
authority is per task, time-bounded, and attributable to the principal the
agent acts for.
2026-06-28 12:28:45 +02:00
2026-08-29 11:57:47 +02:00
### 6. Bootstrap honestly, then harden
2026-06-28 12:28:45 +02:00
During infrastructure setup it is acceptable to use temporary root-created
OpenBao credentials stored outside repositories with mode 0600 and explicit
2026-08-29 11:57:47 +02:00
revocation. Those bootstrap shortcuts must be tracked as temporary, must never
become an implicit fallback, and must be replaced by narrower service identity
bound to OpenBao.
2026-06-28 12:28:45 +02:00
2026-08-29 11:57:47 +02:00
### 7. Prefer exec-time delivery
2026-06-28 12:28:45 +02:00
When a workload or operator command needs a secret, the default delivery mode is
2026-08-29 11:57:47 +02:00
process-local injection for the duration of that command. Every such allow has
an explicit lifetime — a TTL, or a binding to a session that ends. The engine
should make this easier than copying or inspecting a secret value.
2026-06-28 12:28:45 +02:00
2026-08-29 11:57:47 +02:00
### 8. Evidence is bounded, not omniscient
2026-06-28 12:28:45 +02:00
Every apply, read, delivery, lease, verification, revocation, and deactivation
2026-08-29 11:57:47 +02:00
emits non-secret evidence. Load-bearing events — those a control would be
unsound without — require atomic local emission and a declared cadence or
heartbeat. Attributive events should seek atomicity; where they trade it away,
the trade is declared and completeness is not claimed. Evidence belongs in
`audit-core` . Local JSONL and State Hub notes are not a substitute for that
engine.
### 9. Adaptive systems may only tighten
This engine may shorten a lifetime, refuse a delivery, suspend a lane, or
require a fresh decision. It must not manufacture authority, widen a grant, or
treat silence from `access-engine` as permission.
2026-06-28 12:28:45 +02:00
## What This Is
secrets-engine is:
2026-08-29 11:57:47 +02:00
- the Lifecycle engine for cataloged credential lanes;
2026-10-22 17:46:15 +02:00
- one library for that capability;
- a CLI, and for one stage that must stay up, a service, both manifestations
of that library and both injected with that stage's credential at start;
- a typed catalog of KV lanes, auth-capability lanes, grants, delivery
2026-06-30 00:52:05 +02:00
modes, and stage policies;
2026-06-28 12:28:45 +02:00
- an OpenBao policy/auth-role applier with strict local validation;
2026-10-22 17:46:15 +02:00
- an exec-time delivery and scoped capability handoff helper;
2026-08-29 11:57:47 +02:00
- a PEP at every protected side effect, with a published unreachable-engine
2026-10-22 17:46:15 +02:00
stance, consuming access-engine's decision rather than rendering one;
2026-08-29 11:57:47 +02:00
- the credential interaction surface that ops-warden routes to after a
decision.
2026-06-28 12:28:45 +02:00
## What This Is Not
secrets-engine is not:
2026-10-22 17:46:15 +02:00
- a replacement for OpenBao, the owner of custody, or the only client of that store;
- access control for OpenBao, or a decider of who may start or call an instance;
2026-06-28 12:28:45 +02:00
- an identity provider or MFA system;
2026-08-29 11:57:47 +02:00
- an authorization decision engine, an approval store, or a maturity engine;
2026-10-22 17:46:15 +02:00
- a second implementation that appears only when the library is manifested as a service;
2026-06-28 12:28:45 +02:00
- an application-specific secret store;
- a place to persist raw secret values outside OpenBao;
- a prompt-time secret injection mechanism for LLMs;
2026-08-29 11:57:47 +02:00
- a bypass around review, approval, or production custody;
- the operational owner of the SSH certificate lane — that Staff PEP remains
ops-warden's; this engine may later expose the signing API it should call;
- an observation or containment system — kings-guard proposes, this engine
does not watch production, and actuation is unowned estate-wide.
2026-06-28 12:28:45 +02:00
## System Boundary
| Concern | Primary owner | secrets-engine responsibility |
| --- | --- | --- |
2026-10-22 17:46:15 +02:00
| Secret custody, leases, backend audit | OpenBao (Tooling) / railiance-platform | Enable the lifecycle capability over least-privilege roles and validated paths. Other engines may use the same store for other capabilities. |
2026-08-29 11:57:47 +02:00
| Authorization decisions | access-engine (`flex-auth` ) | Consume a decision record; never render or cache one. |
| Approval object | approval-engine | Consume an approval as an input claim; never store or mutate it. |
| Security doctrine | gate-house | Apply doctrine only as it arrives on the decision or in a versioned policy package. |
2026-06-28 12:28:45 +02:00
| Human and service identity | key-cape / user-engine | Consume identity claims; do not replace identity lifecycle. |
2026-08-29 11:57:47 +02:00
| SSH certificate issuance (Staff PEP) | ops-warden | Route and, when the surface exists, expose the OpenBao SSH-CA API; do not take the lane. |
| Evidence custody and integrity | audit-core | Emit non-secret events under the §9.6 bound; do not become the archive. |
2026-06-30 00:52:05 +02:00
| Workload secret consumption | Workload repos / CI / runtime | Provide safe delivery and handoff contracts plus catalog entries. |
2026-08-29 11:57:47 +02:00
| Request history and progress | State Hub | Write non-secret progress pointers only; not a security state plane. |
2026-06-28 12:28:45 +02:00
## Direction of Evolution
The repository should evolve through these phases:
1. **Bootstrap:** root-created temporary OpenBao roles/tokens allow efficient
setup without repeated manual UI handoffs.
2. **MVP:** catalog, decision validation, OpenBao apply plan, and safe exec-time
delivery work for the whynot-design npm publish token pilot.
3. **Stage separation:** build, test, and production roles have distinct policy
boundaries and verification rules.
4. **Hardening:** replace bootstrap token files with OIDC/service auth, wrapped
delivery, short leases, dual control for production provisioning, and routine
rotation/deactivation workflows.
2026-08-29 11:57:47 +02:00
5. **Layer-model conformance:** published PEP stance equals shipped behaviour;
live side effects hold an access-engine decision record or a recorded stance;
evidence classified and emitted to audit-core; proposed SSH-CA and secret-use
surfaces accepted or declined in this repository's own contract, not only in
other repositories' gap registers.
2026-10-22 17:46:15 +02:00
6. **Manifestations:** the library stays free of the store credential. The CLI
and a kept-running service are that same library in a process injected for
one stage. The service is not a second product. Operators, agents, CI, and
future UI surfaces call it without knowing OpenBao internals and without
receiving the injected credential.
2026-06-28 12:28:45 +02:00
## Guiding Question
**How can approved secret work become low-friction for humans and agents while
2026-08-29 11:57:47 +02:00
keeping raw values, OpenBao privileges, and production impact tightly bounded
to a decision this engine did not render?**