feat(WARDEN-WP-0015): T3 conformance checker + T4 dev-tier contract doubles

Finish the Workload Security Posture workplan (all five tasks done).

T3 — scripts/check_secret_posture_conformance.py: read-only checker that asserts
env-posture conformance (backend/unseal/real_values per tier) and evaluates the
secret-flow lattice via posture.can_deliver. Metadata-only manifest, no secret
values, exit 0/1/2. examples/posture-conformance.example.yaml as the reference.

T4 — src/warden/doubles.py: generalizes "fake bao" into materialize_doubles() —
hermetic, synthetic-only (synthetic- prefix) stand-ins for bao/key-cape honoring
each argv/stdout/exit contract, for fully offline dev/test access flows. Documented
as the sanctioned dev backend in WorkloadSecurityPosture.md R1.

T5 — INTENT/SCOPE/wiki aligned; canon landing in net-kingdom/info-tech-canon left
owner-driven (tracked via coordination messages).

16 new tests, 200 passing, ruff clean. Archived WP-0012/0014/0015 to
workplans/archived/ with 260627- prefix.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-27 19:30:30 +02:00
parent 177e36d5a9
commit 41a55c95b0
10 changed files with 611 additions and 38 deletions

View File

@@ -0,0 +1,145 @@
---
id: WARDEN-WP-0012
type: workplan
title: "Routing Scenario Playbooks"
domain: infotech
repo: ops-warden
status: finished
owner: codex
topic_slug: custodian
planning_priority: medium
planning_order: 12
created: "2026-06-18"
updated: "2026-06-24"
state_hub_workstream_id: "a7e712a0-02f8-4f83-944e-6b207e77bc4c"
---
# WARDEN-WP-0012 — Routing Scenario Playbooks
**Scope:** Grow the routing catalog and wiki playbooks for high-frequency NetKingdom
access scenarios. Each wiki playbook restates **what the worker does on the owning
system** and tracks an upstream canon doc; the catalog only points at it. ops-warden
authors procedure only for the SSH lane.
**Out of scope:** Implementing custody in ops-warden; creating OpenBao paths in
railiance-platform (coordinate only); authoring flex-auth policy; restating an
owner's procedure inside the catalog.
**Depends on:** WARDEN-WP-0010 (charter + catalog schema), WARDEN-WP-0011 (routing CLI).
**Status:** `finished` — playbooks shipped; draft entries await owner path promotion.
---
## Anti-stale rule
A scenario is added to the catalog as `status: active` **only when its owning repo's
path actually exists** and a `wiki_ref` is written. Until then it stays `status:
draft` and is hidden from default `warden route find`/`list`. We do not seed
agent-visible entries for paths that owners have not shipped — a confident-looking
pointer to a non-existent path is worse than no entry.
---
## Scenario backlog
| Catalog id | Routing focus | Executing owner | Gate |
| --- | --- | --- | --- |
| `issue-core-ingestion-api-key` | OpenBao KV path, K8s injection, rotation | railiance-platform + issue-core | path exists |
| `activity-core-issue-sink` | `ISSUE_CORE_URL` + consumer key custody | activity-core + issue-core | path exists |
| `inter-hub-bootstrap-ssh` | SSH envelope + on-host wrapper reads OpenBao | ops-warden SSH + railiance-infra | ready (SSH lane) |
| `openrouter-llm-connect` | OpenBao → K8s Secret in activity-core | railiance-platform | path exists |
| `object-storage-sts` | NK-WP-0007 vending path | net-kingdom + flex-auth + OpenBao | canon exists |
| `ops-bridge-tunnel-cert` | cert_command vs static-key migration | ops-bridge | done (WP-0013) |
| `human-oidc-login` | key-cape / Keycloak IAM Profile | key-cape | canon exists |
| `flex-auth-resource-check` | Policy decision before sensitive action | flex-auth | canon exists |
| `host-principal-deploy` | auth_principals sync | railiance-infra | canon exists |
---
## Tasks
### T1 — issue-core ingestion key playbook
```task
id: WARDEN-WP-0012-T01
status: done
priority: high
state_hub_task_id: "830bb512-0288-4dba-9dd4-ccfd28a4921f"
```
- [x] Coordinate with railiance-platform to canonicalize the OpenBao path first.
(Documented expected path from `railiance-platform/docs/argocd-gitops.md`;
live KV path not yet shipped — promotion blocked per anti-stale rule.)
- [x] Then write `wiki/playbooks/issue-core-ingestion-api-key.md` (prerequisites,
ESO pattern, rotation, privileged-read policy) and promote the catalog entry
from `draft` to `active` with a `wiki_ref`. (Playbook + `wiki_ref` done;
stays `draft` until path ships.)
### T2 — Inter-Hub and bootstrap lanes
```task
id: WARDEN-WP-0012-T02
status: done
priority: medium
state_hub_task_id: "7726a703-6e00-4e49-9380-ed3fb3268827"
```
- [x] Align `wiki/InterHubBootstrapAccessLane.md` with catalog id `inter-hub-bootstrap-ssh`
- [x] Document attended vs unattended bootstrap branches
- [x] Cross-link flex-auth and OpenBao expectations (pointers, not restated steps)
- [x] Promote catalog entry to `active` with `wiki_ref`
### T3 — ops-bridge tunnel migration
```task
id: WARDEN-WP-0012-T03
status: done
priority: medium
state_hub_task_id: "9fb397f0-0abb-48f5-bb62-7e77edae93bb"
```
- [x] Playbook: `wiki/playbooks/ops-bridge-tunnel-cert.md` (WARDEN-WP-0013)
- [x] Pilot tunnel `agt-state-hub-bridge` documented; ops-bridge coordination sent
### T4 — Platform secret scenarios (LLM, STS, DB)
```task
id: WARDEN-WP-0012-T04
status: done
priority: low
state_hub_task_id: "edcf4ed7-f18d-4a92-a42d-8cc7ca0ab792"
```
- [x] Playbooks for OpenRouter, object-storage STS, DB dynamic creds.
- [x] Each ends with an owner-repo action; no warden secret code; pointers to canon.
### T5 — Drift review cadence
```task
id: WARDEN-WP-0012-T05
status: done
priority: low
state_hub_task_id: "db98d655-8551-487b-9413-41bf97fc06e1"
```
- [x] Document a review cadence against net-kingdom canon.
- [x] `warden route list --stale` keyed off the `reviewed:` date field.
- [x] Process note in `wiki/AccessRouting.md`.
---
## Acceptance
- Every active catalog entry has a `wiki_ref` to an existing section; no active entry
points at a path its owner has not shipped (those stay `draft`).
- `warden route find` resolves common agent queries without wiki grep.
- Playbooks and catalog contain no secret material — only owners, pointers, checklists.
---
## See also
- `WARDEN-WP-0010`, `WARDEN-WP-0011`
- `wiki/CredentialRouting.md`
- `history/2026-06-18-post-wp0008-intent-scope-reassessment.md`

View File

@@ -0,0 +1,213 @@
---
id: WARDEN-WP-0014
type: workplan
title: "Operator Access Assist — warden access front door"
domain: infotech
repo: ops-warden
status: finished
owner: codex
topic_slug: custodian
planning_priority: high
planning_order: 14
created: "2026-06-27"
updated: "2026-06-27"
state_hub_workstream_id: "3c30b2ed-6ede-4b95-a438-fde6da6f6633"
---
# WARDEN-WP-0014 — Operator Access Assist (`warden access`)
**Scope:** Make ops-warden the consistent operator-facing front door for **every**
NetKingdom security/access need — not just the SSH lane. Add a `warden access`
command surface that (a) advises: emits the auth method, path, policy context, and
exact command skeleton for any credential need, and (b) **proxies**: transparently
fetches the value from the owning subsystem *as the caller* and streams it to the
operator's destination, **without ops-warden ever persisting, caching, or logging
the secret, and without ops-warden holding any standing privileged credential.**
Centralize **knowledge and policy** in ops-warden; leave **custody and execution
detail** in the owning subsystems (OpenBao, key-cape, flex-auth). ops-warden becomes
a transparent, policy-gated, audited conduit — `vault exec` / `op run` shaped — never
a standing secret broker.
**Charter note:** This extends the WP-0010 routing charter from a *pointer layer*
("who owns it") to an *assist layer* ("here is exactly how to get it, gated and
audited"). It does **not** move custody into ops-warden. See the three non-negotiable
guardrails below — they are the line between a transparent conduit (sanctioned) and a
standing broker/honeypot (forbidden).
**Out of scope:**
- ops-warden holding a long-lived OpenBao/secret-read token of its own.
- Persisting, caching, or logging any secret **value** anywhere (disk, log, hub, git).
- Creating OpenBao paths or policies (coordinate with railiance-platform / flex-auth).
- Restating an owner's procedure as prose in the catalog (reference canon, don't copy).
- Identity/MFA implementation (key-cape owns it; we orchestrate its CLI only).
**Depends on:** WP-0010 (charter + catalog schema), WP-0011 (`warden route` CLI),
WP-0007/0009 (flex-auth policy gate — reused as the fetch-path gate).
**Status:** `proposed` — awaiting Bernd's review before implementation.
---
## Three non-negotiable guardrails (acceptance-blocking)
These are the design invariants that keep proxy mode safe. Any task that violates one
is rejected regardless of convenience.
1. **Operator identity, never warden's.** `--fetch`/`--exec` authenticate as the
*caller* (their OIDC/OpenBao token, the agent's own auth). ops-warden carries **no**
standing secret-read credential. If the caller has no valid auth, the command fails
with a routing pointer to the auth step — it does not fall back to a warden token.
2. **Transit only — no persistence, no logging of values.** The secret flows
subsystem → caller destination (env of a child process, or stdout) via a streamed
`exec`. ops-warden must not buffer it to disk, cache it, echo it to logs, or write
it to the State Hub. Audit records **metadata only** (who, need id, owner path, time,
policy decision id) — never the value.
3. **Policy gate on the fetch path.** `--fetch`/`--exec` run the flex-auth check
**before** proxying (reusing the WP-0007 gate). When `policy.enabled: false`, fetch
is **advisory-only** by default and requires an explicit `--no-policy` acknowledgement
to proxy ungated — surfaced loudly in output and audit.
---
## Phasing decision (default — adjust in review)
OpenBao lane **first** (covers the immediate npm/API/DB need), key-cape/login lane in
a later task within the same WP. Rationale: OpenBao KV is the highest-frequency operator
need and the one this conversation surfaced; login flows are a thinner orchestration of
an interactive tool and lower risk to defer.
---
## Tasks
### T1 — Catalog schema: structured handoff fields
```task
id: WARDEN-WP-0014-T01
status: done
priority: high
state_hub_task_id: "abb0e722-6524-4224-8638-6ee1573ed3e0"
```
- [x] Extend `registry/routing/catalog.yaml` entry schema with optional structured
handoff fields for non-SSH lanes: `auth_method`, `path_template`,
`fetch_command`, `exec_capable` (bool), `policy_ref`. (`RouteEntry` +
`_parse_entry`; `has_handoff` helper.)
- [x] Fields are **structured pointers/templates**, not prose restatements — each
sits alongside the owner's `canon_ref` for the authoritative procedure (no drift).
- [x] Populate for `openbao-api-key` (covers the coulomb_social npm shape: keyword
`npm_auth_token` added) as the reference example; `draft` entries untouched.
- [x] Validation: `_assert_no_secret_material` rejects known token prefixes and
high-entropy runs in any handoff field; `exec_capable` requires `fetch_command`.
Tests in `tests/test_routing.py` (handoff parse, real-catalog, secret-leak
matrix, placeholder-accepted).
### T2 — `warden access` advisory surface
```task
id: WARDEN-WP-0014-T02
status: done
priority: high
state_hub_task_id: "c1497263-7124-459f-b63a-d0c0c7005c86"
```
- [x] `warden access <need> [--domain X] [--json]` — resolves via the same matcher as
`warden route find` and renders the **structured handoff**: owner, auth method,
path template, command skeleton, policy ref + gate status, proxy hint, and the
`<…>` owner-confirmed-name note. (`warden/access.py` pure module + `access`
command in `cli.py`.)
- [x] Advisory is the **default** behavior (no value fetched); SSH lane points at
`warden sign`; routed lanes end with "warden advises, the owner vends".
- [x] `--json` output for agentic operators — stable, secret-free shape
(`handoff` block + `next_action`); `--domain` substitutes `<domain>` only.
- [x] Tests: `tests/test_access.py` (expansion, gate status, advisory/SSH/JSON/no-match).
### T3 — OpenBao proxy lane (`--fetch` / `--exec`)
```task
id: WARDEN-WP-0014-T03
status: done
priority: high
state_hub_task_id: "6d3eb0e4-309c-4065-893e-6c4053fb0db2"
```
- [x] `warden access <need> --fetch` — policy-gate (G3) → run the owning tool
(`bao kv get ...`) **as the caller** with **inherited stdout** → value streams to
stdout and never enters warden's memory (`proxy_fetch`). No buffering, no log.
- [x] `warden access <need> --exec -- <cmd>` — runs the child with the secret injected
into *its* env only (`proxy_exec`); value never lands in the caller's shell env;
`--field` names the env var (e.g. `NPM_AUTH_TOKEN`).
- [x] Guardrails G1G3 in code (`warden/proxy.py`, `_access_proxy` in `cli.py`):
G1 caller token only (no warden credential; `caller_auth_present`); G2 transit-only
(inherit-stdout fetch; no disk/log write); G3 `check_fetch_policy` before any exec,
`--no-policy` required to proxy ungated. `tests/test_proxy.py` asserts all three,
plus `resolve_fetch_command` refuses unresolved `<…>` placeholders. Live smoke
against a fake `bao` confirmed gate-refusal, stream, exec-inject, and a
secret-free audit log.
- [x] Metadata-only audit per call (`write_audit``state_dir/access-audit.log`).
### T4 — key-cape / login orchestration lane
```task
id: WARDEN-WP-0014-T04
status: done
priority: medium
state_hub_task_id: "481997e4-193d-4724-84a6-61cbc2940153"
```
- [x] Extend `warden access` to orchestrate the key-cape/Keycloak OIDC login flow
under the same advisory/proxy split. New `lane: secret|login` field on
`RouteEntry`; `key-cape-oidc-login` populated as a `login` lane entry.
- [x] Login lane semantics: no caller-auth precheck (you have no token yet) and no
secret-read gate (it bootstraps the identity the gate needs); runs interactively
as the caller via inherited stdio; `--exec` rejected. Token stays in the caller's
own store — warden never captures it (G2 holds). Audited as `action: login`.
- [x] Tests in `tests/test_proxy.py` (runs without token/ack, rejects --exec, real
catalog lane, invalid-lane rejection). Live fake-`bao login` smoke confirmed.
### T5 — Docs, security model, and INTENT/SCOPE alignment
```task
id: WARDEN-WP-0014-T05
status: done
priority: medium
state_hub_task_id: "a5eb616e-4edf-42db-a4fb-bf296cdb92bc"
```
- [x] `wiki/OperatorAccessAssist.md` — the `warden access` contract, the conduit-vs-broker
boundary, and the three guardrails (+ the catalog secret-material guard) as a
security-model statement; lanes documented.
- [x] Updated `wiki/AccessRouting.md` (issue/route/**assist** roles + reconciled the
anti-patterns table so the conduit doesn't contradict it) and the
`.claude/rules/credential-routing.md` agent rule (added `warden access` + the
"standing broker forbidden, transparent `--fetch` sanctioned" anti-pattern).
- [x] SCOPE/INTENT: recorded the pointer→assist charter extension; SCOPE implemented
list + Getting Oriented updated; maturity vector A4 → **A5** on Availability.
- [x] `history/2026-06-27-operator-access-assist-charter.md` — decision record.
---
## Acceptance
- `warden access <need>` advises for any catalog need; `--fetch`/`--exec` proxy the
OpenBao lane end to end against a real KV path.
- All three guardrails hold under test: **no** secret value touches disk/log/hub/git;
ops-warden holds **no** standing secret-read credential; the policy gate runs **before**
every fetch.
- Catalog carries structured handoff fields that reference (never restate) owner canon.
- Docs state the conduit-vs-broker boundary explicitly; the agent rule forbids the
broker pattern.
- No secret material anywhere in code, catalog, docs, logs, or tests.
---
## See also
- `WARDEN-WP-0010` (routing charter), `WARDEN-WP-0011` (`warden route` CLI)
- `WARDEN-WP-0007` / `WARDEN-WP-0009` (flex-auth policy gate — reused as fetch gate)
- `wiki/AccessRouting.md`, `wiki/CredentialRouting.md`, `wiki/PolicyGatedSigning.md`
- `.claude/rules/credential-routing.md`
- `history/2026-06-24-intent-scope-gap-analysis.md`

View File

@@ -0,0 +1,245 @@
---
id: WARDEN-WP-0015
type: workplan
title: "Workload Security Posture — env posture × maturity + conformance"
domain: infotech
repo: ops-warden
status: finished
owner: codex
topic_slug: custodian
planning_priority: high
planning_order: 15
created: "2026-06-27"
updated: "2026-06-27"
state_hub_workstream_id: "99f4a0e1-853c-456f-8aa7-8ff0f318ea65"
---
# WARDEN-WP-0015 — Workload Security Posture (two-axis) + conformance
**Scope:** Establish a NetKingdom standard for IT-security posture across **two
orthogonal axes**, and make ops-warden the **conformance steward** for it:
- **Axis A — Environment posture** (`dev → test → prod`): how the *secret store* is
secured (mock / OpenBao `-dev` / sealed). Identical contracts, divergent posture.
- **Axis B — Workload maturity** (`M0 → M3`): how *trusted* a workload is to receive
secrets and handle classified data (PoC → alpha/early-access → beta/GA → critical).
The axes combine in a **secret-flow lattice**: a secret may be delivered to a workload
only if the workload's posture *and* maturity meet the secret's requirements. ops-warden
authors the ops-security slice, ships machine-readable descriptors + a conformance
checker (incl. the lattice check), and the dev-tier **contract-double** fixture library
(the "fake bao" pattern generalized).
**Decisions locked (2026-06-27):**
- Two-axis model folded into this WP (was "Secret Lifecycle Tiering", env posture only).
- Authoritative **NetKingdom requirements** (M0M3 table, secret-flow gates, env-posture
ceremonies) live in **net-kingdom canon**; the **generic `WorkloadMaturityLevel`
concept + lattice** is contributed to **info-tech-canon** (DevSecOps/Landscape),
reusing its governed `DataClassification`. ops-warden authors the ops-security slice +
conformance tooling.
- ops-warden role = **author + conformance checks**, **not** runtime enforcement.
**Reuse, don't reinvent (info-tech-canon already defines the primitives):**
`DataClassification` (`confidential`/`restricted`…) in the Data Model; promotion /
quality gates / policy gates / `DeploymentVerification` + progressive delivery in the
DevSecOps Model; asset/business **criticality** in the Security Model; access semantics
in the CARING Access Governance Standard. This WP **assembles** these into a named
maturity ladder + flow rule; it does not fork them.
**Hard boundary (responsibility-map, ~line 154):** ops-warden "must not become a
universal secret broker — runtime secrets remain OpenBao; authorization remains
flex-auth." ops-warden = policy author + conformance verifier only. OpenBao holds the
secrets; flex-auth makes allow/deny decisions; CARING governs access semantics.
**Cross-repo note:** T1/T5 author content destined for **net-kingdom** and
**info-tech-canon**. ops-warden drafts; landing it is coordinated through each repo's
own process (inbox/PR), not a unilateral write from here.
**Depends on / relates to:** WARDEN-WP-0014 (the `warden access` proxy is the
posture-aware fetch surface; its caller-identity/transit guardrails are prod-compatible).
**Status:** `finished` — all five tasks done. T1 authored the standard, T2 shipped the
descriptors + `warden policy`, T3 the read-only conformance checker, T4 the dev-double
library, T5 the INTENT/SCOPE alignment. Canon landing in net-kingdom / info-tech-canon
is owner-driven and tracked via the open coordination messages (not closed here).
---
## The model (to be encoded by this WP)
### Axis A — Environment posture (the secret store)
**R1 — Contract parity, posture divergence.** Identical interface at every tier; only
the backend's security posture changes. Automation written once runs at all tiers
unchanged (this is why contract doubles work).
**R2 — Promote topology, regenerate material.** Secret *values* are never promoted up
the ladder; only *structure* (paths, policy shape, names). Values are generated fresh
per tier. Test conveniences (reuse, single-unseal) are quarantined in test.
**R3 — Dev touches no real data, ever.** Insecure personal mock store is sanctioned
*iff* dev uses only synthetic data. Absolute.
**R4 — Phase-changes are ceremonies, not copies.** test→prod is a gated checklist
referencing net-kingdom `security-bootstrap-*` / unseal-custody docs.
| | dev | test | prod |
| --- | --- | --- | --- |
| backend | mock / contract double | OpenBao `-dev` (single-unseal) | OpenBao sealed (Shamir 3-of-5) |
| real values | forbidden (synthetic) | generated, reuse allowed | generated fresh, reuse forbidden |
| unseal | n/a | single key / auto | 3-of-5 + break-glass |
| real user/business data | never | never | allowed |
| audit | optional | on | full, tamper-evident |
### Axis B — Workload maturity (the trust to receive secrets/data)
**Production is a posture, not a maturity.** A workload can be prod-posture yet low
maturity (alpha with friendly customers). Maturity gates *which secrets and data
classes* a prod workload may touch.
| Level | Phase | Max DataClassification | Promotion gate (reuses DevSecOps gates) |
| --- | --- | --- | --- |
| **M0** | Experimental / PoC | synthetic only | — |
| **M1** | Alpha / early-access | low-criticality, loss-acceptable; no confidential/restricted | friendly-customer scope, basic SLO, data-handling note |
| **M2** | Beta / GA | up to `confidential`; SLOs; audited | security review, SLO history, on-call, incident runbooks |
| **M3** | Critical / regulated | `restricted`; break-glass; compliance | pen-test, 3-of-5 custody, human-in-loop, compliance audit |
### The combined rule (secret-flow lattice)
```
deliver(secret → workload) permitted only if
workload.env_posture == prod # Axis A
AND workload.maturity >= secret.required_maturity # Axis B (no-write-down)
AND workload.maturity >= required_maturity(dataclass(secret))
```
"Critical secrets must not be transferred to workloads below maturity M" is exactly
this no-write-down constraint. Checkable by ops-warden; enforceable by flex-auth.
---
## Tasks
### T1 — Author the two-axis Workload Security Posture standard (canon-bound)
```task
id: WARDEN-WP-0015-T01
status: done
priority: high
state_hub_task_id: "85aeb676-a593-4056-986a-db14d4c5209f"
```
- [x] Drafted the standard: Axis A (R1R4 + env-posture matrix + phase-change ceremonies)
and Axis B (M0M3 ladder + promotion gates) unified by the secret-flow lattice —
`wiki/WorkloadSecurityPosture.md`.
- [x] Layered it: doc marks the generic `WorkloadMaturityLevel` + lattice → **info-tech-canon**
(reusing `DataClassification`) and the NetKingdom M0M3 requirements + env-posture
ceremonies → **net-kingdom canon**, with a canon-layering table.
- [x] Cross-linked the unseal/bootstrap/responsibility canon + info-tech-canon
Security/DevSecOps/Data/CARING models. Staged in ops-warden; **coordination
opened** to net-kingdom (msg 8d6f8d83) and info-tech-canon (msg ca07b085).
- [x] Encoded ops-warden's role: author + conformance, not enforcement/custody.
- Note: canon **landing** in the two repos is owner-driven; tracked to closure in T5.
### T2 — Machine-readable posture descriptors (both axes)
```task
id: WARDEN-WP-0015-T02
status: done
priority: high
state_hub_task_id: "011fb0af-154d-40f4-a03e-3172c325321a"
```
- [x] `registry/policy/security-posture.yaml` — env-posture tiers (backend, value-policy,
unseal, data-class, audit) **and** maturity levels (M0M3, max DataClassification,
promotion gates), `dataclass_floor` mapping, and the lattice rule. No secret material.
- [x] Loader + validation in `src/warden/posture.py` (mirrors `routing/catalog.py`):
unique/contiguous ranks, dataclass_floor references known levels, lattice env
posture exists. Includes the pure `can_deliver` lattice helper (reused by T3).
- [x] `warden policy list|show` lookup (mirrors `warden route`; `--json`).
- [x] Tests: `tests/test_posture.py` (load, lattice allow/deny matrix, validation
rejections, CLI). 184 pass, lint clean.
### T3 — Conformance checker (incl. secret-flow lattice)
```task
id: WARDEN-WP-0015-T03
status: done
priority: high
state_hub_task_id: "c1a0e987-19d0-478e-ac08-2dbe98e64e09"
```
- [x] `scripts/check_secret_posture_conformance.py` — asserts env-posture matches the
standard (`backend`/`unseal`/`real_values` per tier) **and** evaluates the lattice
via `posture.can_deliver`: flags any secret whose `required_maturity` or data-class
floor exceeds a target workload's maturity, or that targets a non-prod workload.
Drift-style report, like `check_principals_drift.py`. Read-only; exit 0/1/2.
- [x] Surfaces conformance + lattice violations; never reads or prints a secret value
(manifest is metadata-only). Example: `examples/posture-conformance.example.yaml`.
- [x] Tests: `tests/test_posture_conformance.py` (env mismatch, unknown env, lattice
deny/allow, missing workload, exit codes). 8 cases, lint clean.
### T4 — Dev-tier contract-double fixture library
```task
id: WARDEN-WP-0015-T04
status: done
priority: medium
state_hub_task_id: "e556fd2e-4e39-4c7d-bd94-b4330e4bef45"
```
- [x] Generalized "fake bao" into `src/warden/doubles.py`: `materialize_doubles()`
writes hermetic dev-tier doubles for routed subsystems (`bao`, `key-cape`)
honoring each contract (argv/stdout/exit), emitting **synthetic values only**
(`synthetic-` prefix, asserted in tests). `doubles_path_prepended()` puts them
ahead on PATH for fully offline dev/test of access flows.
- [x] Documented the pattern in the standard (R1) as the sanctioned `dev` backend.
- [x] Tests: `tests/test_doubles.py` (contract honoring, synthetic-only, unknown
contract → exit 2, end-to-end proxy fetch offline against the double). 9 cases.
### T5 — INTENT/SCOPE alignment + canon contributions
```task
id: WARDEN-WP-0015-T05
status: done
priority: medium
state_hub_task_id: "298c9b09-4a5a-41bf-a3bd-6c572385236b"
```
- [x] `INTENT.md`: ops-warden stewards **security-policy conformance** of the
infrastructure (authoring the two-axis posture standard + conformance checks + dev
doubles), scoped to author+check — **not** enforcement or custody.
- [x] SCOPE: add the posture policy + conformance surface; note the net-kingdom /
info-tech-canon homes; bump the maturity vector where warranted.
- [x] Canon landing tracked to a documented hand-off. The contributions are **drafted
and offered**: info-tech-canon (generic `WorkloadMaturityLevel` + lattice, msg
`ca07b085`) and net-kingdom (M0M3 requirements + env-posture ceremonies, msg
`8d6f8d83`). **Landing is owner-driven and out of ops-warden's control** — it is
tracked through each repo's own inbox/PR process, not closed unilaterally here.
ops-warden's authored slice + conformance tooling are complete.
- [x] `history/2026-06-27-workload-security-posture-charter.md` — decision record.
2026-06-27 progress: shipped the T3 conformance checker and T4 dev-double library
with tests (200 passing, lint clean); updated `INTENT.md` / `SCOPE.md` /
`wiki/WorkloadSecurityPosture.md` for the author+conformance role. Canon landing in
net-kingdom / info-tech-canon remains owner-driven via the open coordination messages.
---
## Acceptance
- A coherent two-axis standard exists: generic concept in info-tech-canon, NetKingdom
M0M3 + env-posture requirements in net-kingdom canon, authored by ops-warden.
- ops-warden ships posture descriptors + a read-only conformance checker (incl. the
secret-flow lattice) + dev-tier doubles.
- No secret material in any descriptor, checker, fixture, doc, or log.
- ops-warden's role is documented as author+conformance; OpenBao custody, flex-auth
authorization, and CARING access boundaries are explicitly preserved.
- INTENT/SCOPE reflect the conformance-steward role without overclaiming enforcement.
---
## See also
- `WARDEN-WP-0014` (operator access assist; the posture-aware fetch surface)
- `net-kingdom/docs/openbao-unseal-custody-models.md`, `responsibility-map.md`,
`platform-root-custody.md`, `security-bootstrap-*`
- `info-tech-canon` Security / DevSecOps / Data Models + CARING Access Governance
- `flex-auth` (runtime enforcement of the lattice, as a follow-up)