# Credential Request And Lease Broker **Workplan:** `RAILIANCE-WP-0005` **Owner:** `railiance-platform` **Status:** source implementation started This document records the Railiance credential broker ownership decision and the first implementation contract for short-lived OpenBao credential leases. ## Decision `railiance-platform` owns OpenBao credential request, generation, delivery, audit, and revocation because this repo owns the platform secrets service and the OpenBao policy surface. The broker may later split into a dedicated service repo if the implementation grows, but the grant catalog and OpenBao policy contracts remain platform-owned. The broker is not a new secret store. It is a controlled request path for bounded credentials that already belong to OpenBao or adjacent platform authorities. ## Boundaries | Concern | Owner | Boundary | | --- | --- | --- | | OpenBao mounts, policies, token roles, response wrapping, audit | `railiance-platform` | Generates and revokes bounded credentials. | | Human login, OIDC, MFA, IAM profile claims | `key-cape` | Authenticates human and service identities. | | Authorization decision | `flex-auth` | Decides whether an actor may request a grant for a purpose, TTL, audience, and delivery mode. | | SSH certificate signing | `ops-warden` | Issues SSH certificates only. It does not vend OpenBao tokens, API keys, or provider secrets. | | Request tracking | State Hub | Stores non-secret metadata only: request ids, actor, grant, purpose, TTL, decision id, lease accessor, status, timestamps, and audit pointers. | | Agent/runtime consumption | `llm-connect` and callers | Never place secrets in prompts. Consume credentials through local exec injection, response wrapping, service-account auth, or approved local files. | ## Non-Secret Metadata Only State Hub, workplans, docs, Git, chat, and prompts may contain: - grant ids such as `ops-warden/warden-sign`; - requested TTL and bounded max TTL; - actor and subject ids; - purpose strings; - lease handles or accessors when they are not sufficient to use the secret; - OpenBao audit request ids or timestamps; - status values such as requested, issued, denied, revoked, or expired. They must not contain: - OpenBao root tokens, platform-admin tokens, or wrapped token values; - unseal shares, recovery codes, private keys, OTP seeds, passwords, or API keys; - raw bearer tokens in command lines, prompt text, State Hub bodies, or logs; - screenshots or pasted command output containing secret values. ## Grant Catalog The catalog lives at: ```text credential-grants/catalog.yaml ``` Validate it with: ```bash make credential-grants-validate ``` Every grant entry defines: - a stable grant id; - credential type and OpenBao policy set; - grant class: `self-service`, `approval-required`, or `break-glass`; - default and max TTL; - allowed actor types and purpose examples; - allowed and denied delivery modes; - audit and revocation expectations. The first pilot grant is `ops-warden/warden-sign`, which creates a short-lived OpenBao token with only the `warden-sign` policy. ## Delivery Modes `exec-env` is the preferred local path. The helper obtains a lease, injects the credential only into a child process environment, redacts output, and then revokes or lets the credential expire. `response-wrap` is for attended handoff. The broker returns a single-use OpenBao wrapping token instead of the raw credential. The recipient unwraps it once; a second unwrap must fail. `local-token-file` is for tools that cannot consume environment variables cleanly. Files must be mode `0600`, stored under `.local/credential-leases/`, and removed when the lease is revoked or expires. That directory is ignored by Git. `kubernetes-auth` is for in-cluster workloads. Workloads should authenticate with service-account-bound auth instead of receiving manually handed tokens. The denied modes are absolute unless a later ADR updates the catalog: - `chat` - `state-hub-body` - `git` - `command-line-token-argument` - `llm-prompt` ## Pilot Flow The target ops-warden smoke path is: ```bash credential exec --grant ops-warden/warden-sign --ttl 15m -- \ SMOKE_VAULT=1 /home/worsch/ops-warden/scripts/policy_gate_production_smoke.sh ``` The child process receives `VAULT_TOKEN` in its environment. The token is not printed, written to shell history, sent to State Hub, or placed in an LLM prompt. ## Implementation Sequence 1. Validate and maintain the non-secret grant catalog. 2. Add bounded OpenBao token role configuration for each OpenBao-token grant. 3. Build a small helper that supports `request`, `exec`, `status`, and `revoke`. 4. Add optional flex-auth preflight and State Hub request lifecycle metadata. 5. Update ops-warden routing so OpenBao token needs point here, while SSH certificate issuance remains in ops-warden. token role configuration for each OpenBao-token grant. 3. Build a small helper that supports `request`, `exec`, `status`, and `revoke`. 4. Add optional flex-auth preflight and State Hub request lifecycle metadata. 5. Update ops-warden routing so OpenBao token needs point here, while SSH certificate issuance remains in ops-warden. Live token issuance requires an approved operator path to create or use the non-root issuer capability. Source-only validation and dry-run helper behavior must remain useful without a live token.