7.5 KiB
Workload Security Posture — NetKingdom standard (draft)
Status: ops-warden-authored draft, WARDEN-WP-0015 T1. Pending promotion to canon along two homes (see Canon layering). Until landed, this file is the authoritative working draft; the canon copies supersede it once merged.
ops-warden's role: author + conformance. ops-warden does not enforce this standard at runtime (flex-auth) and does not hold the secrets (OpenBao). It authors the ops-security slice and ships conformance checks + dev-tier doubles.
NetKingdom IT-security posture is defined along two orthogonal axes. A workload's right to receive a secret depends on both, unified by a secret-flow lattice.
Axis A — Environment posture (how the secret store is secured)
The lifecycle tier of the secret store backing a workload. Contracts are identical at
every tier (so automation and the warden access proxy run unchanged); only the
backend's security posture changes.
R1 — Contract parity, posture divergence. Identical interface at every tier; only
posture changes. This is why dev-tier contract doubles ("fake bao") 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) stay quarantined in test.
R3 — Dev touches no real data, ever. An insecure personal mock store in dev is
sanctioned iff dev uses only synthetic data. Absolute invariant.
R4 — Phase-changes are ceremonies, not copies. test → prod is a gated checklist
(regenerate secrets, switch unseal model, enable break-glass, human sign-off),
referencing the existing net-kingdom security-bootstrap-* and unseal-custody docs —
not duplicating them.
| 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 (how trusted a workload is)
Production is a posture, not a maturity. A workload can run in prod posture yet be
low maturity (alpha with friendly customers). Maturity gates which secrets and data
classes a prod workload may touch. Levels are a total order M0 < M1 < M2 < M3.
| Level | Phase | Max DataClassification it may handle |
Promotion gate (into this level) |
|---|---|---|---|
| M0 | Experimental / PoC | synthetic only | — (entry level) |
| M1 | Alpha / early-access | low-criticality, loss-acceptable; no confidential/restricted |
friendly-customer scope agreed, 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 ops, compliance audit |
DataClassification (confidential, restricted, …) is reused from the
info-tech-canon Data Model — not redefined here. Promotion gates reuse the
info-tech-canon DevSecOps Model's quality/policy gates and DeploymentVerification
(SLOs / smoke / canary / operator confirmation), applied to maturity advancement.
The combined rule — secret-flow lattice
A secret carries a required_maturity (and implicitly the required_maturity of its
DataClassification). Delivery is no-write-down:
deliver(secret → workload) is permitted only if
workload.env_posture == prod # Axis A
AND workload.maturity >= secret.required_maturity # Axis B
AND workload.maturity >= required_maturity(dataclass(secret)) # data class floor
"Critical-infrastructure secrets must not be transferred to workloads below maturity M" is exactly the second clause. The lattice is checkable by ops-warden (conformance) and enforceable at runtime by flex-auth. Access semantics (who, on behalf of whom) remain governed by the CARING Access Governance Standard.
Worked example: an NPM_AUTH_TOKEN used only by a build pipeline → required_maturity: M1, dataclass internal. A production database password for regulated user data →
required_maturity: M3, dataclass restricted; it may be delivered only to a
prod-posture, M3 workload.
Using this to refine blockers
When a workstream says "blocked on security", classify it before escalating. The classification decides whether the blocker is real, belongs to an owning subsystem, or can be removed by a dev/test double.
| Question | Result |
|---|---|
| Is the work dev or test posture only? | Use synthetic contract doubles or generated test values. Do not wait on real production secrets. |
| Is the work prod posture with real values? | Require owner custody (usually OpenBao), flex-auth policy where applicable, and non-secret evidence only. |
Is workload maturity below the secret's required_maturity or data-class floor? |
This is a real IT-security blocker until the workload advances, the secret is reclassified, or the design avoids the secret. |
Does a route exist and the lane is exec_capable? |
warden access --fetch/--exec may remove operator copy/paste as a blocker by proxying the owner's tool as the caller. |
| Is unseal, break-glass, or issuer custody unresolved? | Keep it as an operator ceremony/design blocker; do not paper it over with agent-visible values. |
The evidence to record is route id, owner, env posture, workload maturity,
required_maturity, policy decision id, OpenBao path/version, populated-key count,
smoke id, or token accessor. Never record the secret value.
This is the practical bridge from WARDEN-WP-0014 (warden access) to WP-0015: access
assist can remove manual secret handling friction, while posture/maturity decides
whether the secret may flow at all.
Canon layering (where each part lands)
| Part | Canonical home | ops-warden role |
|---|---|---|
Generic WorkloadMaturityLevel concept + the secret-flow lattice |
info-tech-canon (DevSecOps / Landscape; reuses Data Model DataClassification, Security Model criticality) |
Contribute; do not fork |
| NetKingdom M0–M3 security requirements + env-posture ceremonies | net-kingdom canon (beside openbao-unseal-custody-models.md, responsibility-map.md) |
Author the ops-security slice |
| Machine-readable descriptors + conformance checker + dev doubles | ops-warden (registry/policy/, scripts/) |
Own (WP-0015 T2–T4) |
| Runtime enforcement of the lattice | flex-auth | Route; do not enforce here |
Boundaries preserved
- OpenBao holds secret values. ops-warden never custodies them.
- flex-auth decides allow/deny (incl. enforcing this lattice at runtime).
- CARING / Access Control governs access semantics and delegation.
- key-cape establishes identity. ops-warden authors the standard and checks conformance — it does not become a broker, PDP, or IdP (responsibility-map).
See also
wiki/OperatorAccessAssist.md— the posture-awarewarden accessfetch surfacenet-kingdom/docs/openbao-unseal-custody-models.md,responsibility-map.md,platform-root-custody.md,security-bootstrap-*- info-tech-canon: Security Model, DevSecOps Model, Data Model, CARING Access Governance
workplans/WARDEN-WP-0015-secret-lifecycle-tiering.md