Files
ops-warden/wiki/CredentialRouting.md
tegwick ffc2722006 docs(WP-0010): sharpen mission to "issue SSH, route the rest" + pointer catalog
Implements WARDEN-WP-0010 (charter + pointer catalog). ops-warden issues
short-lived SSH certificates and routes every other credential need to the
subsystem that owns it — no desk metaphor, one execution lane.

- wiki/AccessRouting.md: role/boundary, issue-vs-route matrix, anti-patterns
- registry/routing/catalog.yaml: machine-readable pointer layer (6 active + 1
  draft). No-double-source rule enforced structurally — authored steps/cert_command
  only on the warden_executes:true SSH entry; every wiki_ref anchor resolves
- wiki/CredentialRouting.md: catalog-keyed index + no-duplicate-interfaces note
- INTENT/SCOPE/AGENTS/repo-boundary/capability: aligned to the new framing;
  SCOPE notes A3 -> A4 lands with WP-0011 warden route CLI
- WP-0011/0012 + WP-0010: state_hub id writeback; WP-0010 marked done

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 20:44:53 +02:00

169 lines
6.8 KiB
Markdown

# 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 only**.
For every other credential type, follow the routed path — do not paste secrets
into Git, State Hub, agent chat, or workplans.
---
## Quick decision tree
```text
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
|
+-- 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
|
+-- 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,
stop if you landed on "NEVER ops-warden" for non-SSH secrets.
---
## Routing table
| I need… | Subsystem | ops-warden role |
| --- | --- | --- |
| Interactive login, OIDC token, MFA | key-cape / Keycloak | Document only — use IAM Profile |
| "May I do X on resource Y?" | flex-auth (+ Topaz PDP) | Future pre-sign gate for SSH; document only today |
| OpenRouter / LLM provider API key | OpenBao → K8s Secret | **Do not** ask ops-warden |
| Inter-Hub operator / runtime API key | OpenBao or `0600` temp file | See `wiki/InterHubBootstrapAccessLane.md` |
| Database or service password | OpenBao dynamic/KV | Document only |
| 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 layer**: it names the owner and links the doc, it does
not restate the owner's procedure. Only the SSH row is something ops-warden
executes.
| 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` |
| `openbao-api-key` | "OpenBao owns this — here is the path" | Call OpenBao on the owning system |
| `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 |
| `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 |
ops-warden answers *where + who*; the worker acts on the owning system. ops-warden
never performs the non-SSH step on the worker's behalf.
---
## Examples — do NOT ask ops-warden
| Request | Correct path |
| --- | --- |
| "Populate `OPENROUTER_API_KEY` for llm-connect" | Operator → OpenBao/K8s Secret in `activity-core` namespace |
| "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 interfaces.** Commands like `warden secret`, `warden login`,
`warden policy`, or `warden tunnel` do not exist and will not be added — each
belongs to another subsystem. 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
1. Identity: key-cape login if web/API access needed (optional for pure SSH).
2. SSH cert: `warden sign adm-<you> --pubkey ~/.ssh/id_ed25519.pub`.
3. Tunnel (if needed): ops-bridge with `cert_command` pointing at warden.
4. Host: principal deployed by railiance-infra.
### Kaizen / Codex agent → attended task
1. Register actor: `agt-codex-<task>` per `wiki/ActorInventoryPatterns.md`.
2. SSH cert: `WARDEN_ACTOR=... ops-ssh-wrapper ssh ...` or `warden sign`.
3. Secrets for task (API keys): OpenBao path — not warden.
4. Tunnel: ops-bridge if required.
### CI automation → scheduled job
1. Actor: `atm-<job>` with narrow principal and low TTL (≤ 8 h).
2. `warden issue atm-<job>` or sign with pre-provisioned key.
3. 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.md`
- `SCOPE.md` / `INTENT.md` as needed
Report drift via custodian workplan or State Hub message to `ops-warden`.
---
## See also
- `INTENT.md` — steward mission
- `wiki/AccessRouting.md` — what ops-warden issues vs routes (role and boundary)
- `wiki/NetKingdomSecurityMap.md` — component literacy
- `wiki/ActorInventoryPatterns.md` — actor naming
- `wiki/OpenBaoSshEngineChecklist.md` — production SSH signing verify
- `net-kingdom/docs/platform-identity-security-architecture.md` — platform canon