generated from coulomb/repo-seed
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.
This commit is contained in:
22
SCOPE.md
22
SCOPE.md
@@ -18,16 +18,16 @@ by ops-bridge and other tooling.
|
|||||||
|
|
||||||
Implements `wiki/AccessManagementDirective.md` §§1–5. Owns the CA key, actor identity
|
Implements `wiki/AccessManagementDirective.md` §§1–5. Owns the CA key, actor identity
|
||||||
inventory, signing logic, and scorecard. Two backends: `local` (ssh-keygen, for labs /
|
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
|
offline use) and `vault` (OpenBao or other Vault-compatible SSH secrets engine API, for
|
||||||
same CLI surface and the same `cert_command` interface — callers never need to know which
|
production). Both expose the same CLI surface and the same `cert_command` interface —
|
||||||
backend is in use.
|
callers never need to know which backend is in use.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## In Scope
|
## In Scope
|
||||||
|
|
||||||
- Local CA backend (`ssh-keygen -s`) — fully functional without Vault
|
- Local CA backend (`ssh-keygen -s`) — fully functional without platform secrets access
|
||||||
- Vault SSH engine backend — production-grade signing via Vault API
|
- OpenBao / Vault-compatible SSH engine backend — production signing via HTTP API
|
||||||
- Actor identity registry (`inventory.yaml`) — maps actors to principals and TTL policy
|
- Actor identity registry (`inventory.yaml`) — maps actors to principals and TTL policy
|
||||||
- `cert_command` interface: `warden sign <actor> --pubkey <path>` → cert text on stdout
|
- `cert_command` interface: `warden sign <actor> --pubkey <path>` → cert text on stdout
|
||||||
- TTL policy enforcement per `ActorType` (`adm` 48 h, `agt` 24 h, `atm` 8 h)
|
- 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`
|
- Tunnel lifecycle management → `ops-bridge`
|
||||||
- Host-side principal deployment (`/etc/ssh/auth_principals/`) → `railiance-infra` Ansible
|
- Host-side principal deployment (`/etc/ssh/auth_principals/`) → `railiance-infra` Ansible
|
||||||
- SSH key generation for human admins (self-service: `ssh-keygen`)
|
- 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
|
- Session recording, SIEM forwarding, audit log aggregation
|
||||||
- SSO / Teleport integration (trigger when §6.2 scale thresholds are hit)
|
- SSO / Teleport integration (trigger when §6.2 scale thresholds are hit)
|
||||||
- Host-side scorecard checks (password auth disabled, root login disabled) → `railiance-infra`
|
- 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)
|
- Status: shipped — WARDEN-WP-0001 through WARDEN-WP-0003 complete (v0.1.0)
|
||||||
- Implementation: full `warden` CLI with `local` and `vault` backends, inventory,
|
- Implementation: full `warden` CLI with `local` and `vault` backends, inventory,
|
||||||
scorecard, cleanup, signatures log, and `ops-ssh-wrapper`
|
scorecard, cleanup, signatures log, and `ops-ssh-wrapper`
|
||||||
- Active maintenance: WARDEN-WP-0004 (repo hygiene); follow-ups tracked separately
|
- Active maintenance: WARDEN-WP-0005 (OpenBao doc alignment) complete; capability
|
||||||
for OpenBao doc alignment and capability registry publish
|
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`
|
- `principals`: SSH roles embedded in the cert, matched against `/etc/ssh/auth_principals/%u`
|
||||||
- `inventory.yaml`: authoritative registry of actor → principals + TTL policy
|
- `inventory.yaml`: authoritative registry of actor → principals + TTL policy
|
||||||
- `LocalCA`: file-based CA backend using `ssh-keygen -s`
|
- `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
|
type: security
|
||||||
title: SSH certificate issuance
|
title: SSH certificate issuance
|
||||||
description: Issues short-lived CA-signed SSH certificates for adm/agt/atm actors via a
|
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.
|
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, vault]
|
keywords: [ssh, certificate, ca, credential, warden, ops-warden, pki, openbao, vault]
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -14,8 +14,9 @@ SSH certificate for a named actor. The caller passes the cert to the SSH process
|
|||||||
the actor's private key.
|
the actor's private key.
|
||||||
|
|
||||||
This interface is intentionally tool-agnostic: the caller (`ops-bridge`, a script, a CI
|
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
|
pipeline) does not need to know whether the CA is a local file, OpenBao, or another
|
||||||
command that writes a cert to stdout and exits 0 satisfies the contract.
|
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 <actor-name> --pubkey <path/to/actor.pub>
|
|||||||
Or any equivalent shell command:
|
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
|
ssh-keygen -s /path/to/ca -I agt-test -n agt-task -V +24h /tmp/key.pub && cat /tmp/key-cert.pub
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
```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
|
backend: local
|
||||||
|
|
||||||
# Path to the CA private key. Keep this file mode 600 and never commit it.
|
# Path to the CA private key. Keep this file mode 600 and never commit it.
|
||||||
ca_key: ~/.ssh/ops-ca-user
|
ca_key: ~/.ssh/ops-ca-user
|
||||||
|
|
||||||
# Path to the principals inventory (default shown).
|
|
||||||
inventory_path: ~/.config/warden/inventory.yaml
|
inventory_path: ~/.config/warden/inventory.yaml
|
||||||
|
|
||||||
# Where to store signed certs and generated keypairs (default shown).
|
|
||||||
state_dir: ~/.local/state/warden
|
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/<mount>/sign/<role>`).
|
||||||
|
|
||||||
|
### Example — Railiance01 (browser / operator workstation)
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
backend: vault
|
backend: vault
|
||||||
|
|
||||||
vault:
|
vault:
|
||||||
# Vault server address.
|
# OpenBao UI/API (KeyCape OIDC). Prefer short-lived tokens from policy, not root.
|
||||||
addr: https://vault.example.com
|
addr: https://bao.coulomb.social
|
||||||
|
|
||||||
# Vault SSH secrets engine mount path (default: ssh).
|
|
||||||
mount: ssh
|
mount: ssh
|
||||||
|
|
||||||
# Map from ActorType to Vault signing role name.
|
|
||||||
role_map:
|
role_map:
|
||||||
adm: adm-role
|
adm: adm-role
|
||||||
agt: agt-role
|
agt: agt-role
|
||||||
atm: atm-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
|
token_env: VAULT_TOKEN
|
||||||
|
|
||||||
inventory_path: ~/.config/warden/inventory.yaml
|
inventory_path: ~/.config/warden/inventory.yaml
|
||||||
state_dir: ~/.local/state/warden
|
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
|
```bash
|
||||||
vault secrets enable ssh
|
# After OIDC login or policy-issued token (OpenBao CLI)
|
||||||
vault write ssh/roles/agt-role \
|
export VAULT_TOKEN="<short-lived-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 \
|
key_type=ca \
|
||||||
allowed_users="*" \
|
allowed_users="*" \
|
||||||
allow_user_certificates=true \
|
allow_user_certificates=true \
|
||||||
default_user="agt" \
|
default_user="agt" \
|
||||||
ttl=24h max_ttl=24h
|
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
|
```yaml
|
||||||
actors:
|
actors:
|
||||||
@@ -117,12 +212,12 @@ hosts:
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Environment Variables
|
## Environment variables
|
||||||
|
|
||||||
| Variable | Default | Description |
|
| Variable | Default | Description |
|
||||||
|---|---|---|
|
|----------|---------|-------------|
|
||||||
| `WARDEN_CONFIG` | `~/.config/warden/warden.yaml` | Config file path |
|
| `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`) |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
63
workplans/WARDEN-WP-0005-openbao-doc-alignment.md
Normal file
63
workplans/WARDEN-WP-0005-openbao-doc-alignment.md
Normal file
@@ -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)
|
||||||
Reference in New Issue
Block a user