Implement SECRETS-WP-0008 unblocked layer-model obligations
Load pep-stance.yaml as the live unreachable-engine gate and record named stance fields on privileged evidence. Classify evidence, queue load-bearing records in a local outbox, and add heartbeat/drain commands that never sit on a mutation path. Publish proposed SSH-CA and secret-use evidence contracts without adding an OpenBao SSH-CA write. T02 (access-engine decision records) and T06 (no standing credential) stay wait on external endpoints. Assistant: grok Assistant-Session: 01a04cea-cb33-7c63-bad7-c1b0f9f0076b
This commit is contained in:
parent
57f6c4fa65
commit
3cd9955ac9
16 changed files with 1041 additions and 77 deletions
90
docs/ssh-ca-signing-contract.md
Normal file
90
docs/ssh-ca-signing-contract.md
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
# SSH-CA signing engine contract (proposed)
|
||||
|
||||
Status: **proposed**. `layer.yaml` owner_status remains `proposed` until this
|
||||
surface ships. ops-warden must assent or contest before any replacement client
|
||||
is written.
|
||||
|
||||
Standard: NetKingdom Security Layer Model v0.7 §3.3 (Lifecycle), §6.4 (PEP).
|
||||
Companion: `net-kingdom/SECURITY-COMPANION.md`.
|
||||
|
||||
## What this is
|
||||
|
||||
A deterministic Lifecycle engine API that asks OpenBao to sign a short-lived
|
||||
SSH user certificate **after** an `access-engine` decision record naming the
|
||||
request. secrets-engine presents no additional authority of its own beyond the
|
||||
decision-bound role. The action reconstructs as the caller's.
|
||||
|
||||
## What this is not
|
||||
|
||||
- Operational ownership of the SSH access lane. `warden sign`, `cert_command`,
|
||||
and host-access stewardship stay with ops-warden (Staff PEP).
|
||||
- A break-glass AppRole. The cataloged standalone `warden-sign` AppRole stays
|
||||
parked.
|
||||
- An authorization decision, an approval store, or a second PDP.
|
||||
- A writer of private keys. The caller supplies the public key; the engine
|
||||
returns only the signed certificate material through a scoped delivery path.
|
||||
|
||||
## Caller
|
||||
|
||||
ops-warden, after it holds an `access-engine` decision for the sign request, or
|
||||
after it has recorded the application of its own published unreachable-engine
|
||||
stance in place of a decision (`pep-stance.yaml` in ops-warden).
|
||||
|
||||
## Request
|
||||
|
||||
| Field | Meaning |
|
||||
| --- | --- |
|
||||
| `actor_type` | `adm` \| `agt` \| `atm` |
|
||||
| `actor_name` | Attributable principal the certificate is issued for |
|
||||
| `identity` | Certificate key id / identity string |
|
||||
| `principals` | Exact principal list; no wildcards |
|
||||
| `public_key` | Caller-supplied public key (not a private key) |
|
||||
| `ttl` | Requested lifetime; engine enforces the actor-type maximum |
|
||||
| `decision_id` | Access-engine decision record id, present only where a decision was rendered |
|
||||
| `request_digest` | Canonical digest of subject, action, resource, context |
|
||||
| `stance` | Named unreachable-engine residue if no decision was rendered |
|
||||
|
||||
Replay is permitted iff the canonical request digest matches and the decision
|
||||
lifetime holds. A different resource is a different request.
|
||||
|
||||
## Response (non-secret)
|
||||
|
||||
| Field | Meaning |
|
||||
| --- | --- |
|
||||
| `signed` | Whether OpenBao signed |
|
||||
| `valid_before` | Certificate expiry |
|
||||
| `role` | OpenBao SSH role used (`agt-role` / `adm-role` / `atm-role`) |
|
||||
| `decision_id` | Echoed when present |
|
||||
| `evidence_id` | Local non-secret evidence record id |
|
||||
|
||||
Certificate private material never appears in this response, in evidence, or in
|
||||
argv. Delivery of the signed certificate uses a scoped file or exec path with
|
||||
mode 0600, outside Git, same rules as existing handoff.
|
||||
|
||||
## Lifetime
|
||||
|
||||
Every allow has an explicit end: the certificate TTL, bounded by actor-type
|
||||
maxima already documented on the `warden-sign` lane. No standing grant.
|
||||
|
||||
## Evidence
|
||||
|
||||
Attributive unless a future control branches on the presence of a signing
|
||||
record — today none does. Completeness is not claimed. Records may include
|
||||
actor type, role, `valid_before`, decision id, and stance fields. They must
|
||||
never include a public-key blob if it could identify a live private key
|
||||
handle, a token, or certificate private material.
|
||||
|
||||
Destination today: local JSONL. Intended destination: `audit-core`.
|
||||
|
||||
## Non-responsibilities
|
||||
|
||||
secrets-engine does not choose principals, mint SSH keys, open tunnels, log
|
||||
into hosts, or override ops-warden's zone stance map. If `access-engine` is
|
||||
unreachable, this engine applies **its own** published catalog-stage stance
|
||||
(`pep-stance.yaml` in this repository) and does not consult ops-warden's map.
|
||||
|
||||
## Assent
|
||||
|
||||
A coordination message to ops-warden records this contract. Assent or contest
|
||||
belongs in ops-warden's own voice. Until then no OpenBao SSH-CA write is added
|
||||
to the secrets-engine CLI.
|
||||
Loading…
Add table
Add a link
Reference in a new issue