2026-08-19 22:20:44 +02:00
|
|
|
# ops-warden tenancy posture declaration
|
|
|
|
|
# Framework: net-kingdom/canon/standards/tenancy-posture_v0.1.md draft-9
|
|
|
|
|
# Conformance rule (§6): accuracy, not altitude. Nothing here is aspirational.
|
|
|
|
|
# Validate: python3 ~/net-kingdom/tools/tenancy-posture/validate.py tenancy.yaml
|
|
|
|
|
|
|
|
|
|
schema_version: "0.1"
|
|
|
|
|
framework: netkingdom-tenancy-posture
|
|
|
|
|
service: ops-warden
|
|
|
|
|
role: ssh-certificate-authority
|
|
|
|
|
|
2026-08-22 15:36:37 +02:00
|
|
|
workload_identity:
|
|
|
|
|
name: ops-warden
|
|
|
|
|
kind: operational-control-plane
|
|
|
|
|
responsible_repo: ops-warden
|
|
|
|
|
identity_bindings:
|
|
|
|
|
- scheme: kubernetes-service-account
|
|
|
|
|
authority: railiance01
|
|
|
|
|
subject: system:serviceaccount:ops-warden:ops-warden
|
|
|
|
|
principal_type: service
|
|
|
|
|
environment: prod
|
|
|
|
|
|
2026-08-19 22:20:44 +02:00
|
|
|
tenancy:
|
|
|
|
|
current:
|
|
|
|
|
I: 1
|
|
|
|
|
A: 1
|
|
|
|
|
E: 0
|
|
|
|
|
P: "n/a"
|
|
|
|
|
R: "n/a"
|
|
|
|
|
V: 0
|
|
|
|
|
implemented:
|
|
|
|
|
A: 3
|
|
|
|
|
target:
|
|
|
|
|
I: 1
|
|
|
|
|
A: 3
|
|
|
|
|
E: 0
|
|
|
|
|
P: "n/a"
|
|
|
|
|
R: "n/a"
|
|
|
|
|
V: 1
|
|
|
|
|
reviewed: "2026-08-19"
|
|
|
|
|
review_due: "2027-02-18"
|
|
|
|
|
service_class: interactive
|
|
|
|
|
permanent: [P, R]
|
|
|
|
|
|
|
|
|
|
gap:
|
|
|
|
|
I: >-
|
|
|
|
|
ops-warden has a tenant notion — `policy.tenant` in warden.yaml, and the
|
|
|
|
|
tenant/platform path split introduced by WP-0028 — but it is a static
|
|
|
|
|
configuration constant, not a claim verified on an inbound call. `warden`
|
|
|
|
|
is a CLI invoked by an operator or agent; its caller is an OS user and no
|
|
|
|
|
token is presented to it. Subject id comes from `WARDEN_POLICY_SUBJECT`
|
|
|
|
|
or falls back to the actor name, which is §4.1's "taken from the request"
|
|
|
|
|
case exactly. I1.
|
|
|
|
|
|
|
|
|
|
Not declared permanent. `warden desk` (WP-0029) already performs an OIDC
|
|
|
|
|
login against key-cape, so a verified inbound identity is reachable
|
|
|
|
|
rather than structurally excluded. It is simply not built, and I2 would
|
|
|
|
|
require it on the signing path, not just the desk.
|
|
|
|
|
A: >-
|
|
|
|
|
There is a single choke point on the signing path — inventory membership,
|
|
|
|
|
actor type, and the TTL ceiling — but it binds an *actor* to principals,
|
|
|
|
|
not a request to the tenants it may act for. Tenant context is a
|
|
|
|
|
constant, so "bound once, centrally" (§4.2 A2) would be true only in a
|
|
|
|
|
trivial sense that overclaims. A1.
|
|
|
|
|
|
|
|
|
|
`implemented: A3` is the honest separate fact: delegation to flex-auth as
|
|
|
|
|
PDP is built (`src/warden/policy.py`, `check_sign_policy`) and was
|
|
|
|
|
verified live on 2026-08-19 against the enforcing `flex-auth-ops-warden`
|
|
|
|
|
pin — `decision:f3f7c88f9585582a`, with an anonymous `/v1/check`
|
|
|
|
|
returning 401. It is not `current` because `policy.enabled` is false, and
|
|
|
|
|
it is false by decision rather than by blocker: `ADR-0006` scopes
|
|
|
|
|
enforcement to security zones, which `zone-engine` is defining
|
|
|
|
|
(`ZONE-WP-0001`). Evidence:
|
|
|
|
|
`history/2026-08-19-flex-auth-caller-identity-evidence.md`.
|
|
|
|
|
|
|
|
|
|
A4 is not a target here. The AuthZEN interface question belongs to
|
|
|
|
|
flex-auth as the decision point; ops-warden would follow it, not lead it.
|
|
|
|
|
E: >-
|
|
|
|
|
E0 is accurate and is not a defect to remediate. ops-warden holds no
|
|
|
|
|
tenant-partitioned data: `registry/routing/catalog.yaml` is a pointer
|
|
|
|
|
layer carrying no secret values (`ADR-0001`, CI-enforced) and no `tenant`
|
|
|
|
|
field on any entry; local state (`signatures.log`, `audit.jsonl`,
|
|
|
|
|
`access-audit.log`) is operator-scoped and keyed by actor, not tenant.
|
|
|
|
|
|
|
|
|
|
The tenant boundaries ops-warden *routes* to — `tenants/binky/...` versus
|
|
|
|
|
`platform/workloads/...` — are enforced by OpenBao policy, which is the
|
|
|
|
|
owner's control, not ops-warden's. Claiming E1 on the strength of someone
|
|
|
|
|
else's enforcement is the overclaim §6 prohibits. Under `ADR-0002`
|
|
|
|
|
ops-warden is a transparent conduit and takes no custody, so it has no
|
|
|
|
|
tenant data to key. Raising E would mean acquiring data it is out of
|
|
|
|
|
scope to hold.
|
|
|
|
|
P: >-
|
|
|
|
|
n/a and permanent. No primary datastore: state is files under
|
|
|
|
|
`~/.local/state/warden` on the invoking operator's machine, and
|
|
|
|
|
§3.3 scopes P to the primary datastore. Custody of secrets is explicitly
|
|
|
|
|
out of scope (`SCOPE.md`, `ADR-0002`), so ops-warden will not acquire a
|
|
|
|
|
tenant-bearing substrate.
|
|
|
|
|
R: >-
|
|
|
|
|
n/a and permanent, on the same ground as P: no tenant data at rest.
|
|
|
|
|
|
|
|
|
|
Named honestly rather than hidden behind the n/a: ops-warden *does* keep
|
|
|
|
|
local operator records indefinitely — `audit.jsonl` is append-only by
|
|
|
|
|
design (WP-0022) and `signatures.log` has no retention position. They are
|
|
|
|
|
metadata-only and guarded against secret material, and they are not
|
|
|
|
|
tenant data, so they do not move this axis. But "no declared retention
|
|
|
|
|
for local audit" is a real gap on a different axis than this file grades,
|
|
|
|
|
and is recorded here so it is not lost.
|
|
|
|
|
V: >-
|
|
|
|
|
V0. `warden sign` depends synchronously on OpenBao at
|
|
|
|
|
`https://bao.coulomb.social` (railiance01) and, once enabled, on the
|
|
|
|
|
flex-auth pin reached through the ops-bridge tunnel
|
|
|
|
|
`flex-auth-ops-warden-railiance01`. §4.6.1 takes the minimum across that
|
|
|
|
|
path, and none of it has an exercised recovery objective.
|
|
|
|
|
|
|
|
|
|
A `backend: local` CA exists in the code and is covered by tests, but it
|
|
|
|
|
has never been exercised as a production degraded mode, and §13 does not
|
|
|
|
|
accept "the code path exists" as V evidence. Target V1 means documenting
|
|
|
|
|
and actually rehearsing recovery of the signing path — not adding
|
|
|
|
|
redundancy, which the substrate cannot currently support: `reef-railiance`
|
|
|
|
|
is single-node with a shared control plane, and under Decision 4.6.1 that
|
|
|
|
|
caps V for everything bound to it (see NK-WP-0027).
|
|
|
|
|
|
2026-08-22 15:36:37 +02:00
|
|
|
zones:
|
|
|
|
|
standard: security-zones_v0.1
|
|
|
|
|
membership: z1-operational
|
|
|
|
|
responsible_party: team:platform-security
|
|
|
|
|
justification: >-
|
|
|
|
|
The attended platform signing service has a bounded operational scope and
|
|
|
|
|
internal metadata exposure. It has M1 evidence, but no SLO history, on-call
|
|
|
|
|
rotation, or incident exercise that would support z2-protected.
|
|
|
|
|
context:
|
|
|
|
|
maturity: M1
|
|
|
|
|
criticality: medium
|
|
|
|
|
data_classification: internal
|
|
|
|
|
evidence:
|
|
|
|
|
- ref: docs/evidence/security-zone-admission-2026-08-22.md
|
|
|
|
|
supports: [M1, platform-only-scope, basic-slo, data-handling-note]
|
|
|
|
|
- ref: history/2026-08-19-flex-auth-caller-identity-evidence.md
|
|
|
|
|
supports: [production-policy-path, authenticated-caller]
|
|
|
|
|
reviewed: "2026-08-22"
|
|
|
|
|
review_due: "2026-11-22"
|
2026-08-19 22:20:44 +02:00
|
|
|
|
|
|
|
|
evidence:
|
|
|
|
|
A: >-
|
|
|
|
|
Built and verified live 2026-08-19 against the enforcing
|
|
|
|
|
`flex-auth-ops-warden` pin: `decision:f3f7c88f9585582a`, anonymous
|
|
|
|
|
`/v1/check` 401. Record:
|
|
|
|
|
`history/2026-08-19-flex-auth-caller-identity-evidence.md`. Re-establish on
|
|
|
|
|
demand with `scripts/check_policy_caller_identity.py`. Why it is implemented
|
|
|
|
|
and not current: `docs/adr/ADR-0006-enforcement-is-zone-scoped.md`.
|
|
|
|
|
E: >-
|
|
|
|
|
`docs/adr/ADR-0002-conduit-not-broker.md` and `ADR-0001` (catalog is a
|
|
|
|
|
pointer layer, CI-enforced) — why no tenant-keyed data exists to enforce on.
|
|
|
|
|
P: >-
|
|
|
|
|
No datastore. State is operator-local files under `~/.local/state/warden`.
|
|
|
|
|
V: >-
|
|
|
|
|
Production signing path verified 2026-06-17
|
|
|
|
|
(`history/2026-06-17-openbao-production-verify.md`). No recovery exercise
|
|
|
|
|
exists for that path, which is why this is V0 and not V1.
|
|
|
|
|
|
|
|
|
|
notes:
|
|
|
|
|
- >-
|
|
|
|
|
ops-warden issues short-lived SSH certificates and routes every other
|
|
|
|
|
credential need to its owner.
|
|
|
|
|
- >-
|
|
|
|
|
Five of six axes are low because it deliberately holds nothing. The low
|
|
|
|
|
grades on E, P and R are the intended consequence of ADR-0002 and ADR-0005,
|
|
|
|
|
not deferred work, and raising them would mean acquiring data ops-warden is
|
|
|
|
|
out of scope to hold.
|
|
|
|
|
- >-
|
|
|
|
|
The two axes with real movement are A — built, deferred by ADR-0006 pending
|
|
|
|
|
the zone model — and V, which needs a rehearsed recovery and is capped by
|
|
|
|
|
the substrate until NK-WP-0027 lands.
|