14 KiB
Credential Routing — NetKingdom Access Desk
Date: 2026-06-17
Use this page when a development worker (human, kaizen agent, CI job, or custodian tool) needs access or credentials and is unsure which subsystem owns the request.
ops-warden maintains this routing guide. It issues SSH certificates directly.
For every other credential type, use the routed owner path. warden access may
also assist: it renders the owner, auth method, path, and command shape and,
for exec_capable catalog lanes, can proxy the owner's tool as the caller.
That is a transparent conduit, not custody: do not paste secrets into Git,
State Hub, agent chat, or workplans.
Practice follows SecurityCanon SEC-DSM 1.0.0
(security-canon/infospace/standards/devops-secrets-management/SecurityCanonDevOpsSecretsManagementStandard.md),
which Gate House teaches. Prefer, in order: native identity, federated identity,
an ephemeral credential, an automatically rotated secret, then a vaulted static
secret (§5, decision procedure §37). SSH certificates are the ephemeral path
this repo issues. A static secret stays in the owner's custody. This page routes
to that owner. It does not collect the value.
Quick decision tree
What do you need?
|
+-- Log in as a human / get OIDC claims / MFA
| -> key-cape (lightweight) or Keycloak (expanded)
| net-kingdom/docs/platform-identity-security-architecture.md
|
+-- Permission to perform an action on a resource
| -> flex-auth (policy decision)
| flex-auth/INTENT.md
|
+-- API key, DB password, provider token, K8s secret, dynamic lease
| -> OpenBao (after flex-auth approval where policy requires it)
| railiance-platform/docs/openbao.md
| NEVER ops-warden as owner or store
|
+-- S3 / object-storage temporary credentials
| -> NK-WP-0007 vending path (flex-auth + OpenBao + storage STS)
| net-kingdom/docs/object-storage-sts-credential-vending.md
| NEVER ops-warden as owner or store
|
+-- SSH certificate for host / ops reachability (adm/agt/atm)
| -> ops-warden (warden sign / cert_command)
| wiki/OpsWardenConfig.md
|
+-- SSH tunnel / port forward (already have or will get a cert)
| -> ops-bridge
| ops-bridge tunnels.yaml + cert_command from ops-warden
|
+-- Host accepts your SSH principal / force-command on server
| -> railiance-infra Ansible
| /etc/ssh/auth_principals/, sshd hardening
Under two minutes: match your need to a branch above, open the linked doc,
and treat non-SSH branches as owner-routed work. warden access can advise or
proxy an exec_capable lane, but it does not make ops-warden the owner of the value.
Routing table
| I need… | Subsystem | ops-warden role |
|---|---|---|
| Interactive login, OIDC token, MFA | key-cape / Keycloak | Assist: advise; proxy the login lane when the catalog entry is exec_capable |
| "May I do X on resource Y?" | flex-auth (+ Topaz PDP) | Route; policy gate for SSH/access proxies where configured |
| OpenRouter / LLM provider API key | OpenBao → K8s Secret | Assist: route; proxy only as caller when the catalog lane is exec_capable |
| Inter-Hub operator / runtime API key | OpenBao or 0600 temp file |
Assist: route/custody notes; see wiki/InterHubBootstrapAccessLane.md |
| Database or service password | OpenBao dynamic/KV | Assist: route; proxy only as caller when the catalog lane is exec_capable |
| Short-lived SSH cert for operator | ops-warden (adm-*) |
Issue via warden sign |
| Short-lived SSH cert for agent | ops-warden (agt-*) |
Issue via warden sign / wrapper |
| Short-lived SSH cert for CI/cron | ops-warden (atm-*) |
Issue via warden sign / warden issue |
| Tunnel to remote service | ops-bridge | Consumer of cert_command |
| Principal file on host | railiance-infra | Document only |
Routing catalog index
These needs are also carried in the machine-readable pointer catalog
(registry/routing/catalog.yaml, surfaced via warden route — WARDEN-WP-0011).
The catalog is a pointer-and-assist layer: it names the owner, links the doc,
and carries secret-free handoff templates for warden access. Only the SSH row is
something ops-warden executes with its own authority. Non-SSH exec_capable rows
run the owner's tool as the caller and preserve owner custody. Every execution
position is classified permanent / native / interim (warden route gaps
lists the interim set — WARDEN-WP-0030).
Catalog id |
What ops-warden answers | What the worker does next |
|---|---|---|
ssh-cert-host-access |
Issues the cert (warden sign) |
Use the cert / wire it into cert_command |
ops-warden-warden-sign-token |
"railiance-platform broker owns the warden-sign lease — use credential exec" |
railiance-platform/scripts/credential.py exec --grant ops-warden/warden-sign (see playbook) |
openbao-api-key |
"OpenBao owns this — here is the path/command shape" | Call OpenBao directly, or use warden access --fetch/--exec as yourself when the lane is exec_capable |
openbao-platform-admin-login |
"This is an attended OpenBao administration identity act, not workload secret retrieval" | Use KeyCape-backed OIDC/MFA at auth/netkingdom, role platform-admin; never substitute a workload role or root token |
kubernetes-railiance01-admin |
"Attended railiance01 admin kubeconfig; the agent default path is ops-mason-builder" | Prefix kubectl with KUBECONFIG=/home/worsch/.kube/config-railiance01. Do not fetch the file. |
openbao-shamir-recovery-ceremony |
"This is an attended trust-root ceremony, not secret provisioning" | Obtain one explicit approval and follow the railiance-platform recovery checklist with the existing out-of-band custodians; never send shares through Warden |
flex-auth-policy-check |
"flex-auth decides — here is the policy doc" | Query flex-auth / embed the PEP |
key-cape-oidc-login |
"key-cape / Keycloak owns identity" | Authenticate via IAM Profile, or use the warden access login lane as yourself |
ops-bridge-tunnel |
"ops-bridge owns transport — supply a cert_command" |
Open the tunnel with ops-bridge |
railiance-infra-principals |
"railiance-infra deploys host principals" | Run the infra Ansible |
activity-core-issue-sink |
"activity-core + issue-core own emission — pair ISSUE_CORE_* env vars" |
See wiki/playbooks/activity-core-issue-sink.md |
inter-hub-bootstrap-ssh |
"Inter-Hub bootstrap SSH envelope — attended vs unattended branches" | See wiki/InterHubBootstrapAccessLane.md |
issue-core-ingestion-api-key |
"railiance-platform OpenBao KV + ESO deliver ISSUE_CORE_API_KEY — here is the path" |
ESO consumes in-cluster; warden access issue-core-ingestion-api-key --fetch ISSUE_CORE_API_KEY as yourself |
openrouter-llm-connect |
"railiance-platform OpenBao KV + ESO deliver OPENROUTER_API_KEY to activity-core" |
ESO consumes in-cluster; warden access openrouter-llm-connect --fetch OPENROUTER_API_KEY as yourself (risk: high) |
reuse-surface-hub-write-token |
"railiance-platform OpenBao KV + ESO deliver REUSE_SURFACE_TOKEN to reuse-surface" |
ESO consumes in-cluster; warden access reuse-surface-hub-write-token --fetch as yourself |
railiance-backup-offsite-lane |
"railiance-platform OpenBao KV for Nextcloud WebDAV + age recovery" | warden access railiance-backup-offsite-lane --out FILE (risk: high; agents: no raw stream) |
forgejo-admin-api-token |
"railiance-platform OpenBao KV for Forgejo admin PAT" | warden access forgejo-admin-api-token --out FILE (risk: high) |
binky-company-email-imap |
"tenant IMAP on tenants/binky/company-email/imap (IONOS)" |
warden access binky-company-email-imap --out FILE (risk: high) |
binky-qonto-api |
"tenant Qonto API on tenants/binky/qonto-api (API_KEY+API_USER)" |
warden access binky-qonto-api --out FILE (risk: high) |
net-kingdom-lldap-bind-credential |
"railiance-platform custody for the LLDAP bind credential used by identity-provisioner and the privacyIDEA resolver" | Follow the owner-approved NetKingdom reconciliation runbook; lane is currently unresolved and never fetches a value |
net-kingdom-privacyidea-admin-token |
"railiance-platform custody for the privacyIDEA administrative token used by attended resolver reconciliation" | Follow the owner-approved NetKingdom reconciliation runbook; lane is currently unresolved and never fetches a value |
keycape-client-secret-generate |
"railiance-platform's broker generates a KeyCape client secret inside custody for an accepted SecurityCase. The value is never returned" | bao login to role credential-broker-keycape-client-secret-generate, then credential.py generate --case-file ... --case-ref ... (see playbook). Agents are refused |
audit-core-senders |
"ops-mason built the audit-core sender registry in OpenBao. audit-core reads it through ESO only" | Nobody reads the registry. A sender gets its own exact-path projection (see playbook table) |
Promotion criteria: wiki/playbooks/catalog-lane-promotion.md.
High-risk / agent boundary: wiki/playbooks/agent-read-boundary.md.
EXPOSED taint: wiki/playbooks/exposed-taint.md · warden taint <id>.
Tenant secrets: mount tenants/ — path tenants/<tenant>/<workload>/<bundle>
(see wiki/playbooks/tenant-secret-onboarding.md, WARDEN-WP-0028). Not under
platform/workloads/.
Draft (hidden from default lookup until owner path ships — warden route list --all):
Catalog id |
Routing focus | Playbook |
|---|---|---|
object-storage-sts |
NK-WP-0007 STS vending path | wiki/playbooks/object-storage-sts.md |
database-dynamic-credentials |
OpenBao database secrets engine | wiki/playbooks/database-dynamic-credentials.md |
fluid-telegram-operator |
ops-mason attended OIDC lane for the Hall of Helix campaign (pending owner-run checks) | wiki/playbooks/fluid-telegram-operator.md |
ops-warden answers where + who + how. The worker still acts on the owning system.
When warden access proxies a non-SSH lane, it does so as the caller and stores no
value; the owner remains OpenBao, key-cape, flex-auth, or the routed subsystem.
Policy gate for proxied credential reads
warden access <need> with --exec, --fetch, --to-file, --wrap or
--fingerprint runs a flex-auth read check before any fetch. That check goes
to the fetch evaluator flex-auth-ops-warden-fetch
(policy.fetch_flex_auth_url, workstation http://127.0.0.1:19091 through
ops-bridge tunnel flex-auth-ops-warden-fetch-railiance01). It does not go to
the SSH signing pin flex-auth-ops-warden (policy.flex_auth_url,
127.0.0.1:19090), which admits only the ops-warden system. If the fetch
evaluator is unset or unreachable, the fetch is refused (exit 4). It is never
sent to the signing pin and never allowed by default. The gate line of
warden access <need> names the evaluator in use. Config:
wiki/OpsWardenConfig.md → "Two evaluators" (CUST-WP-0075).
Examples — do NOT ask ops-warden to own or vend
| Request | Correct path |
|---|---|
"VAULT_TOKEN for ops-warden production sign / policy-gate smoke" |
railiance-platform credential broker — warden route show ops-warden-warden-sign-token |
"Populate OPENROUTER_API_KEY for llm-connect" |
Operator → OpenBao custody; delivery via warden route show openrouter-llm-connect |
| "Store Inter-Hub admin key for bootstrap" | Operator → OpenBao or IHUB_OPERATOR_KEY_FILE (CUST-WP-0049) |
| "Give me Vault root token" | Break-glass ceremony → railiance-platform/docs/openbao.md |
| "S3 credentials for artifact upload" | NK-WP-0007 / artifact-store consumer path |
| "JWT for my app" | key-cape / Keycloak IAM Profile |
No duplicate ownership. Commands that would make warden a store, IdP, or
transport owner — warden secret, warden bao, warden login as an identity
service, or warden tunnel — do not exist. A future warden policy lookup, if
added by WARDEN-WP-0015, is metadata/conformance only; flex-auth remains the PDP.
The canonical anti-pattern table lives in
wiki/AccessRouting.md#anti-patterns-not-coming-to-ops-warden; it is not
restated here.
Examples — ops-warden IS correct
| Request | Command / pattern |
|---|---|
| ops-bridge tunnel needs a cert | cert_command: warden sign <actor> --pubkey <path> |
| Agent reaching bootstrap host | agt-codex-interhub-bootstrap — wiki/InterHubBootstrapAccessLane.md |
| Check cert expiry before shift | warden status <actor> |
| New tunnel actor | warden inventory add — wiki/ActorInventoryPatterns.md |
| Lab without OpenBao | backend: local — wiki/OpsWardenConfig.md |
Typical flows
Human operator → remote host
- Identity: key-cape login if web/API access needed (optional for pure SSH).
- SSH cert:
warden sign adm-<you> --pubkey ~/.ssh/id_ed25519.pub. - Tunnel (if needed): ops-bridge with
cert_commandpointing at warden. - Host: principal deployed by railiance-infra.
Kaizen / Codex agent → attended task
- Register actor:
agt-codex-<task>perwiki/ActorInventoryPatterns.md. - SSH cert:
WARDEN_ACTOR=... ops-ssh-wrapper ssh ...orwarden sign. - Secrets for task (API keys): OpenBao path — not warden.
- Tunnel: ops-bridge if required.
CI automation → scheduled job
- Actor:
atm-<job>with narrow principal and low TTL (≤ 8 h). warden issue atm-<job>or sign with pre-provisioned key.- No long-lived keys in CI env vars.
When guidance drifts
NetKingdom security architecture is canonical in net-kingdom. When it
changes (OpenBao, IAM Profile, new bootstrap lanes), ops-warden updates:
- This file
wiki/NetKingdomSecurityMap.mdSCOPE.md/INTENT.mdas needed
Report drift via custodian workplan or State Hub message to ops-warden.
See also
INTENT.md— steward missionwiki/AccessRouting.md— what ops-warden issues vs routes (role and boundary)wiki/NetKingdomSecurityMap.md— component literacywiki/WorkloadSecurityPosture.md— dev/test/prod posture, M0-M3 maturity, and blocker triagewiki/ActorInventoryPatterns.md— actor namingwiki/OpenBaoSshEngineChecklist.md— production SSH signing verifynet-kingdom/docs/platform-identity-security-architecture.md— platform canon