From 15bf8cb54394e77cb60f9039af0f26007f3b2ed1 Mon Sep 17 00:00:00 2001 From: tegwick Date: Wed, 17 Jun 2026 07:36:13 +0200 Subject: [PATCH] WARDEN-WP-0005: OpenBao-first documentation alignment Document OpenBao as the platform production secrets service while keeping the vault-compatible warden.yaml config shape. Update OpsWardenConfig, SCOPE, and CertCommandInterface cross-references. --- SCOPE.md | 22 +-- wiki/CertCommandInterface.md | 7 +- wiki/OpsWardenConfig.md | 135 +++++++++++++++--- .../WARDEN-WP-0005-openbao-doc-alignment.md | 63 ++++++++ 4 files changed, 193 insertions(+), 34 deletions(-) create mode 100644 workplans/WARDEN-WP-0005-openbao-doc-alignment.md diff --git a/SCOPE.md b/SCOPE.md index 4377d2d..72b610e 100644 --- a/SCOPE.md +++ b/SCOPE.md @@ -18,16 +18,16 @@ by ops-bridge and other tooling. Implements `wiki/AccessManagementDirective.md` §§1–5. Owns the CA key, actor identity inventory, signing logic, and scorecard. Two backends: `local` (ssh-keygen, for labs / -non-Vault use) and `vault` (HashiCorp Vault SSH engine, for production). Both expose the -same CLI surface and the same `cert_command` interface — callers never need to know which -backend is in use. +offline use) and `vault` (OpenBao or other Vault-compatible SSH secrets engine API, for +production). Both expose the same CLI surface and the same `cert_command` interface — +callers never need to know which backend is in use. --- ## In Scope -- Local CA backend (`ssh-keygen -s`) — fully functional without Vault -- Vault SSH engine backend — production-grade signing via Vault API +- Local CA backend (`ssh-keygen -s`) — fully functional without platform secrets access +- OpenBao / Vault-compatible SSH engine backend — production signing via HTTP API - Actor identity registry (`inventory.yaml`) — maps actors to principals and TTL policy - `cert_command` interface: `warden sign --pubkey ` → cert text on stdout - TTL policy enforcement per `ActorType` (`adm` 48 h, `agt` 24 h, `atm` 8 h) @@ -43,7 +43,7 @@ backend is in use. - Tunnel lifecycle management → `ops-bridge` - Host-side principal deployment (`/etc/ssh/auth_principals/`) → `railiance-infra` Ansible - SSH key generation for human admins (self-service: `ssh-keygen`) -- Vault cluster setup, HA, or PKI secrets engine +- OpenBao / Vault cluster setup, HA, or PKI secrets engine deployment - Session recording, SIEM forwarding, audit log aggregation - SSO / Teleport integration (trigger when §6.2 scale thresholds are hit) - Host-side scorecard checks (password auth disabled, root login disabled) → `railiance-infra` @@ -76,8 +76,8 @@ backend is in use. - Status: shipped — WARDEN-WP-0001 through WARDEN-WP-0003 complete (v0.1.0) - Implementation: full `warden` CLI with `local` and `vault` backends, inventory, scorecard, cleanup, signatures log, and `ops-ssh-wrapper` -- Active maintenance: WARDEN-WP-0004 (repo hygiene); follow-ups tracked separately - for OpenBao doc alignment and capability registry publish +- Active maintenance: WARDEN-WP-0005 (OpenBao doc alignment) complete; capability + registry publish remains a separate follow-up --- @@ -99,7 +99,7 @@ backend is in use. - `principals`: SSH roles embedded in the cert, matched against `/etc/ssh/auth_principals/%u` - `inventory.yaml`: authoritative registry of actor → principals + TTL policy - `LocalCA`: file-based CA backend using `ssh-keygen -s` -- `VaultCA`: Vault SSH engine backend +- `VaultCA`: OpenBao / Vault-compatible SSH engine backend (`backend: vault`) --- @@ -117,8 +117,8 @@ backend is in use. type: security title: SSH certificate issuance description: Issues short-lived CA-signed SSH certificates for adm/agt/atm actors via a - pluggable cert_command interface; supports local CA (ssh-keygen) and Vault SSH engine backends. -keywords: [ssh, certificate, ca, credential, warden, ops-warden, pki, vault] + pluggable cert_command interface; supports local CA (ssh-keygen) and OpenBao/Vault-compatible SSH engine backends. +keywords: [ssh, certificate, ca, credential, warden, ops-warden, pki, openbao, vault] ``` --- diff --git a/wiki/CertCommandInterface.md b/wiki/CertCommandInterface.md index a6506c5..a9209e4 100644 --- a/wiki/CertCommandInterface.md +++ b/wiki/CertCommandInterface.md @@ -14,8 +14,9 @@ SSH certificate for a named actor. The caller passes the cert to the SSH process the actor's private key. This interface is intentionally tool-agnostic: the caller (`ops-bridge`, a script, a CI -pipeline) does not need to know whether the CA is a local file or HashiCorp Vault. Any -command that writes a cert to stdout and exits 0 satisfies the contract. +pipeline) does not need to know whether the CA is a local file, OpenBao, or another +Vault-compatible SSH secrets engine. Any command that writes a cert to stdout and exits 0 +satisfies the contract. --- @@ -30,7 +31,7 @@ warden sign --pubkey Or any equivalent shell command: ``` -vault write -field=signed_key ssh/sign/agt-role public_key=@/tmp/key.pub +bao write -field=signed_key ssh/sign/agt-role public_key=@/tmp/key.pub ssh-keygen -s /path/to/ca -I agt-test -n agt-task -V +24h /tmp/key.pub && cat /tmp/key-cert.pub ``` diff --git a/wiki/OpsWardenConfig.md b/wiki/OpsWardenConfig.md index 4cbea70..3536038 100644 --- a/wiki/OpsWardenConfig.md +++ b/wiki/OpsWardenConfig.md @@ -4,19 +4,36 @@ Config file: `~/.config/warden/warden.yaml` (override with `WARDEN_CONFIG` env v --- -## Local Backend (lab / non-Vault) +## Backend overview + +| Backend | Config value | Use when | +|---------|--------------|----------| +| Local CA | `backend: local` | Labs, CI, air-gapped dev, hosts without platform secrets access | +| Platform CA | `backend: vault` | Production and shared ops environments | + +**Platform standard:** Railiance S3 uses [OpenBao](https://openbao.org/) as the +runtime platform secrets service (`RAIL-PL-WP-0002` in `railiance-platform`). +OpenBao exposes a **Vault-compatible HTTP API**, so ops-warden keeps the config +keys `backend: vault` and the `vault:` block — no separate OpenBao backend name +is required. The same config works against OpenBao or HashiCorp Vault if you point +`vault.addr` at either service. + +ops-warden signs SSH certificates only. It does **not** deploy OpenBao, manage +unseal keys, or store long-lived API secrets. Cluster bootstrap and custody live +in `railiance-platform` and NetKingdom docs. + +--- + +## Local backend (lab / offline) ```yaml -# Backend selection. "local" uses ssh-keygen -s with a CA key on disk. +# Uses ssh-keygen -s with a CA private key on disk. backend: local # Path to the CA private key. Keep this file mode 600 and never commit it. ca_key: ~/.ssh/ops-ca-user -# Path to the principals inventory (default shown). inventory_path: ~/.config/warden/inventory.yaml - -# Where to store signed certs and generated keypairs (default shown). state_dir: ~/.local/state/warden ``` @@ -35,48 +52,126 @@ chmod 644 ~/.ssh/ops-ca-user.pub --- -## Vault Backend (production) +## OpenBao / Vault-compatible backend (production) + +Use this backend against the platform OpenBao instance or any other SSH secrets +engine that implements the Vault signing API (`POST /v1//sign/`). + +### Example — Railiance01 (browser / operator workstation) ```yaml backend: vault vault: - # Vault server address. - addr: https://vault.example.com + # OpenBao UI/API (KeyCape OIDC). Prefer short-lived tokens from policy, not root. + addr: https://bao.coulomb.social - # Vault SSH secrets engine mount path (default: ssh). mount: ssh - # Map from ActorType to Vault signing role name. role_map: adm: adm-role agt: agt-role atm: atm-role - # Environment variable holding the Vault token (default: VAULT_TOKEN). + # OpenBao accepts the same X-Vault-Token header name as Vault. token_env: VAULT_TOKEN inventory_path: ~/.config/warden/inventory.yaml state_dir: ~/.local/state/warden ``` -### Vault setup snippet +### Example — in-cluster caller (pod or trusted host) + +```yaml +backend: vault + +vault: + addr: http://openbao.openbao.svc.cluster.local:8200 + mount: ssh + role_map: + adm: adm-role + agt: agt-role + atm: atm-role + token_env: VAULT_TOKEN +``` + +Choose the `addr` that matches where `warden` runs: operators on a laptop use +the external HTTPS endpoint; workloads inside the cluster use the internal +service URL. See `railiance-platform/docs/openbao.md` for deployment and access +paths. + +### Authentication + +Export a token with permission to sign against the mapped roles: ```bash -vault secrets enable ssh -vault write ssh/roles/agt-role \ +# After OIDC login or policy-issued token (OpenBao CLI) +export VAULT_TOKEN="" + +# Or HashiCorp Vault CLI against a Vault-compatible endpoint +vault login +``` + +`warden` reads the token from the env var named in `vault.token_env` (default +`VAULT_TOKEN`). OpenBao uses the same header; you do not need a separate +`BAO_TOKEN` unless you configure `token_env` that way. + +On failure, `warden sign` suggests falling back to `--backend local` only for +lab recovery — not as a production substitute. + +### SSH secrets engine setup (OpenBao) + +Run once per environment after OpenBao is initialized and unsealed. Adjust TTL +limits to match `ActorType` policy in `wiki/AccessManagementDirective.md` +(adm 48 h, agt 24 h, atm 8 h). + +```bash +# OpenBao CLI (bao) — preferred on Railiance +bao secrets enable ssh + +bao write ssh/roles/agt-role \ key_type=ca \ allowed_users="*" \ allow_user_certificates=true \ default_user="agt" \ ttl=24h max_ttl=24h -export VAULT_TOKEN=$(vault token create -field=token) +bao write ssh/roles/adm-role \ + key_type=ca \ + allowed_users="*" \ + allow_user_certificates=true \ + default_user="adm" \ + ttl=48h max_ttl=48h + +bao write ssh/roles/atm-role \ + key_type=ca \ + allowed_users="*" \ + allow_user_certificates=true \ + default_user="atm" \ + ttl=8h max_ttl=8h ``` +HashiCorp Vault uses the same paths with the `vault` CLI: + +```bash +vault secrets enable ssh +vault write ssh/roles/agt-role key_type=ca ... # same role parameters +``` + +Mount path defaults to `ssh`; override with `vault.mount` in `warden.yaml` if +your engine lives elsewhere. + +### Platform references + +| Topic | Location | +|-------|----------| +| OpenBao deploy, unseal, OIDC admin | `railiance-platform/docs/openbao.md` | +| Host CA trust and principals | `railiance-infra` Ansible playbooks | +| Signing contract for callers | `wiki/CertCommandInterface.md` | + --- -## Principals Inventory (`inventory.yaml`) +## Principals inventory (`inventory.yaml`) ```yaml actors: @@ -117,12 +212,12 @@ hosts: --- -## Environment Variables +## Environment variables | Variable | Default | Description | -|---|---|---| +|----------|---------|-------------| | `WARDEN_CONFIG` | `~/.config/warden/warden.yaml` | Config file path | -| `VAULT_TOKEN` | — | Vault token (vault backend only; env var name is configurable) | +| `VAULT_TOKEN` | — | API token for `backend: vault` (OpenBao or Vault; name configurable via `vault.token_env`) | --- @@ -144,4 +239,4 @@ tunnels: `ops-bridge` runs `cert_command` before each SSH launch, captures stdout as the cert, and passes it alongside the private key via `ssh -i -i `. -See `wiki/CertCommandInterface.md` for the full contract. +See `wiki/CertCommandInterface.md` for the full contract. \ No newline at end of file diff --git a/workplans/WARDEN-WP-0005-openbao-doc-alignment.md b/workplans/WARDEN-WP-0005-openbao-doc-alignment.md new file mode 100644 index 0000000..34334a0 --- /dev/null +++ b/workplans/WARDEN-WP-0005-openbao-doc-alignment.md @@ -0,0 +1,63 @@ +--- +id: WARDEN-WP-0005 +type: workplan +title: "OpsWarden OpenBao-First Documentation Alignment" +domain: custodian +repo: ops-warden +status: finished +owner: codex +topic_slug: custodian +created: "2026-06-17" +updated: "2026-06-17" +state_hub_workstream_id: "57f6ebf8-0ef3-4686-9a73-3f9d38288be9" +--- + +# WARDEN-WP-0005 — OpenBao-First Documentation Alignment + +**Scope:** Update ops-warden documentation so production guidance names OpenBao +as the platform secrets service while preserving the existing `backend: vault` +config surface (Vault-compatible SSH secrets engine API). No code changes. + +**Out of scope:** VaultCA backend rewrite, OpenBao SSH engine deployment in +`railiance-platform`, AccessManagementDirective canon updates. + +**Reference:** `RAIL-PL-WP-0002` — Railiance standardizes on OpenBao; ops-warden +follow-up noted 2026-05-17. + +--- + +## Tasks + +### T1 — OpsWardenConfig.md + +```task +id: WARDEN-WP-0005-T01 +status: done +priority: high +state_hub_task_id: "bbbc4dda-9634-4c04-86e5-94b96c021b43" +``` + +- [x] OpenBao-first production section with Railiance URLs and `bao` CLI examples +- [x] Explain `backend: vault` / `vault:` keys as Vault-compatible API abstraction +- [x] Link to `railiance-platform/docs/openbao.md` + +### T2 — Cross-reference updates + +```task +id: WARDEN-WP-0005-T02 +status: done +priority: medium +state_hub_task_id: "6391cb82-896e-405a-a59b-36640e6480ba" +``` + +- [x] `SCOPE.md` Core Idea and In Scope — OpenBao-first, Vault-compatible +- [x] `wiki/CertCommandInterface.md` — caller-agnostic wording includes OpenBao + +--- + +## Acceptance Criteria + +- [x] Production config example uses OpenBao (`bao.coulomb.social` or in-cluster URL) +- [x] No reader is told HashiCorp Vault is the platform standard +- [x] `backend: vault` config shape unchanged (code compatibility preserved) +- [x] `uv run pytest` still passes (docs-only change) \ No newline at end of file