Assistant: codex Assistant-Model: gpt-5.6-sol Assistant-Session: 01a0291a-1e87-7151-9934-fcbfe3f65eb1
7.9 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
-> zone-specific enforce stance (flex-auth policy package)
An enforce stance must not be assigned while /v1/check still answers
unauthenticated callers. ops-warden has no global enable switch or gate bypass;
it applies the compiled zone stance and its local per-zone failure mode.
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