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
163 lines
10 KiB
Markdown
163 lines
10 KiB
Markdown
# Review: Security layer model v0.7 vs INTENT, SCOPE, and implementation
|
|
|
|
Date: 2026-08-29
|
|
Author: grok
|
|
Standard: `net-kingdom/canon/standards/security-layer-model_v0.7.md` (accepted)
|
|
Companion: `net-kingdom/SECURITY-COMPANION.md` v0.2
|
|
Compared: adapted `INTENT.md`, updated `SCOPE.md`, current CLI implementation
|
|
Intake closed by this session: `SECRETS-IN-0001`
|
|
|
|
## Executive assessment
|
|
|
|
The accepted layer model confirms what this repository already was in practice
|
|
and had not yet declared in its own voice: **Engine, role Lifecycle** — a
|
|
deterministic API over OpenBao for cataloged credential lanes. The gate-house
|
|
review note at the top of `INTENT.md` was not a declaration. That note is now
|
|
replaced by frontmatter, prose, `layer.yaml`, and a published PEP stance map.
|
|
|
|
The intent remains directionally sound. The layer model does not move the
|
|
system boundary (OpenBao stays Tooling; `access-engine` stays the only PDP;
|
|
ops-warden stays the SSH Staff PEP). It **tightens the contract** this engine
|
|
owes at every protected side effect, and it **names two proposed surfaces**
|
|
this repository had not answered: an SSH-CA signing API, and secret-use
|
|
evidence for kings-guard.
|
|
|
|
`SCOPE.md` and the implementation already describe a guarded OpenBao CLI MVP
|
|
with one proven native workload pilot. Against the new intent they are
|
|
**aligned on layer and ownership, behind on PEP, decision, and evidence
|
|
obligations**. Several of those obligations overlap active work in
|
|
`SECRETS-WP-0007`; the new work is the layer-model remainder, not a restart of
|
|
CLI hardening.
|
|
|
|
A finding is raised against the §4 catalog cell, not against the proposed
|
|
layer: the catalog says this repository owns "custody". Custody is OpenBao's.
|
|
This engine owns the lifecycle API over that custody.
|
|
|
|
## What was declared
|
|
|
|
| Artifact | Content |
|
|
| --- | --- |
|
|
| `INTENT.md` frontmatter | `layer: Engine`, `role: Lifecycle` |
|
|
| `INTENT.md` body | Own-voice declaration, PEP shape, evidence bound, proposed surfaces |
|
|
| `layer.yaml` | Machine-readable declaration; owned OpenBao contact; no decision surface |
|
|
| `pep-stance.yaml` | Unreachable-engine stance by catalog stage; prod fail-closed |
|
|
| `scripts/check_layer_conformance.py` | Mechanical check of the above |
|
|
| `tests/test_layer_conformance.py` | Declaration + published map equals shipped prod fail-closed |
|
|
|
|
Contest of the proposed **layer** (Engine): none. The determinism test holds.
|
|
|
|
Contest of **catalog wording**: yes — "custody" should not appear as this
|
|
engine's owned property.
|
|
|
|
Answers to proposed ownerships:
|
|
|
|
| Proposed surface | Answer |
|
|
| --- | --- |
|
|
| SSH-CA signing write (`ops-warden` §5.3 gap) | **Accept** as a Lifecycle engine API. **Decline** operational SSH-lane stewardship. ops-warden remains the Staff PEP. |
|
|
| Secret-use evidence (`kings-guard`) | **Accept** as a proposed Lifecycle engine surface, bounded by §9.6. Not shipped. |
|
|
|
|
## INTENT vs SCOPE
|
|
|
|
No contradiction on layer, owners, or forbidden claims. Drift is maturity:
|
|
|
|
| Intent claim | SCOPE today | Gap kind |
|
|
| --- | --- | --- |
|
|
| Engine / Lifecycle declaration | Declared | Closed this session |
|
|
| Consume an access-engine decision before every protected side effect | Consumer validator exists; production live fail-closed because the durable object is not served | Implementation (WP-0007-T04 + WP-0008-T02) |
|
|
| Published PEP stance equals shipped behaviour, stance application recorded | Map published; prod fail-closed matches; records are `DecisionError`, not named stance fields | Implementation (WP-0008-T01) |
|
|
| Evidence to `audit-core` under §9.6 | Local JSONL + best-effort State Hub; attributive; completeness not claimed | Implementation (WP-0008-T03) |
|
|
| SSH-CA engine API | Not implemented; ops-warden still writes OpenBao | Proposed surface (WP-0008-T04) |
|
|
| Secret-use evidence API | `route` / `audit` summarize local JSONL | Proposed surface (WP-0008-T05) |
|
|
| No standing agent credential | Bootstrap token file still accepted; KeyCape scaffold unwired to OpenBao | Hardening (WP-0007-T05 / WP-0008-T06) |
|
|
| Service API | CLI only | Deferred until WP-0007 exit criteria |
|
|
| Every allow has a lifetime | Delivery sessions self-revoke; decision TTL waits on durable authorization | Partial |
|
|
| Doctrine as claims | Catalog/policies are local YAML | Later; do not compile outcomes here |
|
|
|
|
`SCOPE.md` remains the implemented-capability ledger. Volatile workplan status
|
|
stays out of it. The new durable additions are the layer table, the updated
|
|
system boundary, and the explicit not-implemented layer-model surfaces.
|
|
|
|
## INTENT vs implementation
|
|
|
|
The strongest implemented slice is unchanged:
|
|
|
|
```text
|
|
catalog -> approval-status or fail-closed prod gate -> guarded plan
|
|
-> policy/AppRole apply -> bounded presence/capability verification
|
|
-> CLI-local exec/handoff -> non-secret route/evidence pointer
|
|
```
|
|
|
|
That slice is a Lifecycle engine **shape**. It is not yet a conforming PEP.
|
|
|
|
### Scorecard against the accepted model
|
|
|
|
| Rule | Assessment | Evidence | Material gap |
|
|
| --- | --- | --- | --- |
|
|
| §3.3 Lifecycle | Aligned in shape | OpenBao isolated in `openbao.py`; catalog/plan/delivery/lifecycle are the API | Service API absent; CLI is the only surface |
|
|
| §6 one decision point | Partial, fail-closed | `authorization.py` validates a supplied object and does not evaluate policy. Production live commands refuse without a durable ActionAuthorization. Build/test still accept State Hub status or a local fixture | Local/hub status is not an access-engine decision record. Risk of compiled early decision if fixtures return for production |
|
|
| §6.1 compiled data | Watch | Catalog admission and publication-scope policy clamp lanes; they must not become the allow | Keep catalog descriptive; effects stay in the decision |
|
|
| §6.4 PEP obligation 1 | Partial | Privileged handlers record attempt/terminal evidence; production refusal is a `DecisionError` | Stance application is not recorded as named fields (stage, failure mode, decision id present only where rendered) |
|
|
| §6.4 PEP obligation 2 | Aligned as declared | No verdict cache; `verdict_caching: none` | Must remain none when ActionAuthorization is live |
|
|
| §6.4 PEP obligation 3 | Published, not yet loaded | `pep-stance.yaml` is total over build/test/prod/unknown; tests pin prod fail-closed to `_require_lane_approval` | Code still hardcodes the gate rather than loading the map. Build/test fail-open is relative to access-engine, not a manufactured allow — that residue is itself a gap |
|
|
| §6.4 PEP obligation 4 | Attributive | Local JSONL + hub receipts; OpenBao remains backend audit | Completeness not claimed (correct). No `audit-core` emit |
|
|
| §9.6 load-bearing vs attributive | Undeclared in code | `layer.yaml` classifies today's trail as attributive | Destroy, revoke, and dual-control provision will become load-bearing once they are production-live. They need atomic local outbox + cadence/heartbeat **before** any control branches on them |
|
|
| §9.7 lifetime | Partial | AppRole sessions self-revoke; ActionAuthorization has `expires_at` in the consumer schema | Production never reaches the lifetime because live prod is disabled. Bootstrap tokens remain standing credentials |
|
|
| §20.2 credentials after a decision | Principle aligned; production blocked | Fail-closed is the honest residue while the PDP object is unserved | Do not reopen production on hub status |
|
|
| Staff must not touch OpenBao | External | ops-warden still has the SSH-CA write gap with intended owner here | Engine surface not shipped; do not take the Staff lane |
|
|
| Agent rule 1 (no standing credential) | Not met | `--bootstrap-token-file` and `BAO_TOKEN` are the live auth path | KeyCape scaffold exists and is deliberately unwired |
|
|
| Observation / actuation | Correctly not claimed | Companion §10: nothing is observed in production; nothing can be contained automatically | Do not plan as if either existed |
|
|
|
|
### Overlap with active workplans
|
|
|
|
`SECRETS-WP-0007` already owns CLI hardening that the 2026-08-23 assessment
|
|
called P0/P1: merge-safe provision (done), lifecycle split (in progress),
|
|
exact-action authorization (in progress), session self-revocation (in
|
|
progress), verification/evidence (in progress). Those tasks stay there.
|
|
|
|
What the layer model **adds**, and what `SECRETS-WP-0008` is for:
|
|
|
|
1. Bind the published PEP stance to shipped behaviour and record stance
|
|
application by name.
|
|
2. Treat the durable ActionAuthorization as an **access-engine decision
|
|
record** under §6.4, not as a State Hub status check, once WP-0007-T04's
|
|
endpoint exists.
|
|
3. Classify evidence and emit it to `audit-core`.
|
|
4. Answer the two proposed surfaces (SSH-CA API, secret-use evidence) in this
|
|
repository's own contract.
|
|
5. Retire standing engine credentials as a layer obligation, not only as
|
|
bootstrap hygiene.
|
|
|
|
Do not start service mode, runtime tenancy, or a second custody backend from
|
|
this review. Companion §10 still holds: nothing is observed in production, and
|
|
nothing can be contained automatically.
|
|
|
|
## Recommended sequence
|
|
|
|
1. Keep `SECRETS-WP-0007` as the CLI-hardening track. Do not reopen live
|
|
production on coarse hub status.
|
|
2. Land `SECRETS-WP-0008-T01` — load `pep-stance.yaml` as the source of the
|
|
fail-closed gate and record stance application fields.
|
|
3. When the durable authorization object is served, consume it as a decision
|
|
record (`WP-0008-T02` / `WP-0007-T04`) with digest+lifetime replay rules.
|
|
4. Classify evidence; emit load-bearing classes to `audit-core` with a local
|
|
outbox; declare cadence or heartbeat.
|
|
5. Publish the SSH-CA engine contract with ops-warden before writing a client
|
|
replacement. Keep their Staff PEP.
|
|
6. Publish the secret-use evidence contract with kings-guard. `audit` is not
|
|
that contract.
|
|
7. Wire service identity only after the platform-owned OpenBao JWT role exists.
|
|
Bootstrap remains break-glass.
|
|
|
|
## Conclusion
|
|
|
|
`INTENT.md` now declares Engine / Lifecycle in this repository's own voice and
|
|
accepts the two proposed surfaces without taking Staff work. `SCOPE.md` is
|
|
honest about the CLI MVP and the new not-implemented obligations. The
|
|
implementation is a Lifecycle engine in shape and a partial PEP in behaviour:
|
|
production fail-closed is the correct residue, build/test still run on a
|
|
pre-decision-record approval path, and evidence is attributive local notes
|
|
rather than `audit-core`.
|
|
|
|
The repository should not advertise itself as a service API, a second PDP, a
|
|
custody backend, an SSH issuer, or an observation system. Follow-on work is
|
|
`SECRETS-WP-0008`.
|