Inbox triage (ADHOC-2026-08-17), three messages, all answered and marked read. flex-auth (FLEX-WP-0015 T02) reported that /v1/check and /v1/batch_check authenticate no caller — any workload with cluster reach can assert any subject and get an authoritative allow. It lands here because ops-warden owns workload identity in this estate and its pre-sign gate is a flex-auth PEP. Recommendation recorded in wiki/NetKingdomSecurityMap.md: Kubernetes ServiceAccount TokenReview with a projected, audience-scoped token. Rejected the shared-secret header — it manufactures a risk: high lane with a rotation owner per caller on the authorization path, the exact interim-proxy debt WP-0030 exists to stop growing. Deferred mTLS pending an owner for a workload X.509 CA. Bind `system` to the authenticated SA at auth time, but keep the resource-type allowlist in the policy package rather than the admission layer. Warn-only rollout; policy.enabled must not flip while /v1/check answers unauthenticated callers. Recorded as a pattern, not a catalog entry. Catalog delegation refreshes: - coulomb-social-runtime-env: USER_ENGINE_PROXY_SECRET ownership settled (decision 8fe22037, USER-WP-0021) — intended_owner stays railiance-apps, answered clause dropped from blocked_on, consumers: [user-engine] recorded. - rapp-qonto-keycape-client: blocked_on no longer implies an in-flight KEY-WP-0008 dependency; the key-cape-native exchange command is unopened work. uv run pytest -q → 338 passed, 4 deselected. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
7.7 KiB
NetKingdom Security Map (ops-warden view)
Date: 2026-06-17
Condensed literacy guide for ops-warden stewards and development workers.
Canonical source remains net-kingdom/docs/platform-identity-security-architecture.md.
ops-warden implements the operational SSH lane and documents how the other lanes connect.
Planes
Bootstrap plane railiance-infra, railiance-cluster, net-kingdom bootstrap
Platform control key-cape, flex-auth, OpenBao, Topaz, railiance-platform
Tenant plane railiance-apps, coulomb workloads, future tenants
Operational access ops-warden (SSH certs), ops-bridge (tunnels)
Component map
| Component | Answers | Credential types | ops-warden |
|---|---|---|---|
| key-cape | Who are you? (lightweight IAM) | OIDC tokens, MFA | Route — do not issue |
| Keycloak | Who are you? (expanded IAM) | OIDC/SAML federation | Route — do not issue |
| privacyIDEA | MFA / step-up | OTP, hardware tokens | Route — do not issue |
| flex-auth | May you do this action? | Policy decisions, audit envelopes | Future SSH pre-sign; route today |
| Topaz | PDP runtime for flex-auth | Authorization evaluations | Route — do not issue |
| OpenBao | Runtime secret authority | API keys, DB creds, leases, K8s auth | SSH engine signing backend only |
| ops-warden | SSH ops access | Short-lived SSH certificates | Own and issue |
| ops-bridge | Tunnel transport | Uses certs via cert_command | Consumer |
| railiance-infra | Host enforcement | auth_principals, sshd | Route — deploy hosts |
| railiance-platform | Platform deploy | OpenBao, Postgres, ingress | Route — do not deploy from warden |
Credential lanes (summary)
| Lane | Owner | Lifetime | Worker entrypoint |
|---|---|---|---|
| Identity | key-cape / Keycloak | Session / token TTL | Login / OIDC |
| Authorization | flex-auth | Per request | Policy API / embedded PEP |
| Runtime secrets | OpenBao | Lease-bound | bao CLI, K8s ESO, app integration |
| SSH operational | ops-warden | adm 48h / agt 24h / atm 8h | warden sign |
| Tunnel | ops-bridge | Session | bridge + cert_command |
Full routing: wiki/CredentialRouting.md.
Trust flow (simplified)
Worker request
-> Identity? key-cape / Keycloak
-> Authorized? flex-auth
-> Secret material? OpenBao
-> SSH cert? ops-warden
-> Tunnel? ops-bridge (cert from warden)
-> Host accepts? railiance-infra principals
OpenBao does not replace identity or authorization. flex-auth decides; OpenBao stores/issues; ops-warden signs SSH certs when host reachability is the need.
Service-to-service caller authentication (in-cluster)
Status: recommended pattern, 2026-08-17. Raised by flex-auth (FLEX-WP-0015 T02):
POST /v1/check and /v1/batch_check authenticate no caller, so any workload with
network reach can assert any subject and receive an authoritative allow.
There is no prior estate pattern for this. What exists covers adjacent needs and none of them covers in-cluster service→service HTTP:
| Existing mechanism | What it authenticates | Why it does not apply |
|---|---|---|
| ops-warden SSH certificates | adm/agt/atm actors to hosts |
Host reachability, not an HTTP call between pods |
KeyCape client_credentials |
Workload OIDC clients (rapp-qonto-keycape-client) |
Needs a client secret per caller — a custodied lane per consumer |
| OpenBao AppRole | Host-standing non-interactive workers | role_id+secret_id on disk; the WP-0030 register already flags AppRole as having no owner front door for minting or rotating |
Recommendation: Kubernetes ServiceAccount TokenReview
Use the caller's projected ServiceAccount token with an explicit audience
(e.g. flex-auth); the callee verifies it via TokenReview.
Why this and not the alternatives:
- It introduces no new secret material. A shared-secret header (flex-auth's
option (c)) would immediately become a
risk: highcredential lane with a rotation owner, per calling system, on the authorization path — precisely the interim-proxy debt the WP-0030 delegation register exists to stop growing. ops-warden would end up fronting it. - It matches the estate's short-lived-credential doctrine. A projected,
audience-scoped SA token has the same shape as
warden signoutput: bounded TTL, issued by an authority, verified on use, never stored. - mTLS (option (b)) is the stronger end state but has no owner. It requires an X.509 workload CA, and no component owns one today — ops-warden issues SSH certificates, not workload X.509. Adopting mTLS means first answering who owns the workload CA, which is a permanent-ownership question, not a rollout task. Record it as future direction; do not block on it.
Implementation notes that matter:
- Use a projected token volume with an explicit
audience, not the legacy automount token. KeepautomountServiceAccountToken: falseand add the projected volume per Deployment. An audience-scoped token stolen from a pod cannot be replayed against the kube-apiserver or another service.
Authenticate and bind — but keep policy in the policy engine
Bind the system asserted in the request to the authenticated ServiceAccount and
reject a mismatch. That is identity binding, not authorization: it is cheap and it
costs nothing extra when a new consumer arrives, since a caller must have a mapping
regardless.
Do not put a caller allowlist for resource types ("only ops-warden may ask about
ssh-certificate") in the authentication middleware. flex-auth is the estate's
policy engine; encoding that rule in its own admission layer puts authorization in
two places, where only one of them is reviewable and versioned. Express it in the
policy package.
Rollout
Warn-only first, then fail-closed. ops-warden adopts the calling side on its own schedule rather than in lockstep. The binding condition is sequencing, not a date:
flex-auth warn-only -> ops-warden pre-sign gate presents its SA token
-> logs clean of unauthenticated callers
-> flex-auth fail-closed
-> policy.enabled: true (ops-warden side, FLEX-WP-0007)
policy.enabled must not flip anywhere while /v1/check still answers
unauthenticated callers.
Division of the call: the mechanism above is an architecture recommendation and ops-warden's to make. Accepting the pod-spec change and the rollout timing are the operator's.
This is a pattern, not a credential lane, so it gets no registry/routing/catalog.yaml
entry — the catalog indexes credential needs and their owners.
NetKingdom documents to watch
| Document | Why ops-warden cares |
|---|---|
platform-identity-security-architecture.md |
Planes, secret path, SSH path |
responsibility-map.md |
Operational SSH dependency section |
platform-identity-security-architecture.md |
Operational SSH Path section |
platform-root-custody.md |
OpenBao ceremony — not warden's job |
object-storage-sts-credential-vending.md |
S3 creds — never warden |
canon/standards/iam-profile_v0.2.md |
Claims for future policy-gated sign |
When these change, update ops-warden wiki and wiki/CredentialRouting.md.
Recursive platform rule
Tenant admins (including tenant:coulomb) must not gain platform-root
authority. ops-warden SSH actors should use narrow principals for agent
and automation work — not platform-admin equivalents on hosts.
See also
INTENT.mdwiki/AccessRouting.md— issue-vs-route role and boundarywiki/CredentialRouting.mdwiki/PolicyGatedSigning.md(future flex-auth hook)net-kingdom/docs/platform-identity-security-architecture.md