feat(openbao): add SSH engine automation for ops-warden signing
Declarative roles, warden-sign policy, apply/verify scripts, and Makefile targets openbao-configure-ssh and openbao-verify-ssh. Document operator flow in docs/openbao.md for NET-WP-0020 T5 / WP-0008 T2.
This commit is contained in:
126
docs/openbao.md
126
docs/openbao.md
@@ -18,15 +18,26 @@ S5 workloads / operators
|
||||
-> openbao-0
|
||||
-> integrated Raft storage on local-path PVC
|
||||
-> audit storage PVC mounted at /openbao/audit
|
||||
|
||||
Platform operators with approved admin identity
|
||||
-> https://bao.coulomb.social
|
||||
-> Traefik Ingress + TLS
|
||||
-> openbao-ui service
|
||||
-> OpenBao UI/API
|
||||
-> KeyCape OIDC at https://kc.coulomb.social for login
|
||||
```
|
||||
|
||||
- OpenBao is the canonical Railiance S3 secrets service.
|
||||
- SOPS/age remains the Git-at-rest bootstrap mechanism.
|
||||
- The first Railiance01 deployment is single-replica Raft, not true HA.
|
||||
- Public ingress is disabled. Operators use `kubectl exec` or port-forwarding.
|
||||
- Browser UI/API exposure is declared for `https://bao.coulomb.social`.
|
||||
Operators authenticate through KeyCape/OIDC with MFA and the
|
||||
`platform-admin` role. Do not use the root token through the browser UI.
|
||||
- `kubectl exec` and port-forwarding remain valid break-glass/operator paths
|
||||
for maintenance and non-browser verification.
|
||||
- TLS is disabled inside the pod listener for this internal-only bootstrap. Add
|
||||
cert-manager-backed internal TLS before exposing OpenBao beyond cluster-local
|
||||
traffic.
|
||||
cert-manager-backed internal TLS before relying on cluster-internal traffic
|
||||
from untrusted namespaces.
|
||||
|
||||
## Deployment
|
||||
|
||||
@@ -41,6 +52,10 @@ make openbao-deploy
|
||||
make openbao-status
|
||||
```
|
||||
|
||||
`make openbao-deploy` also applies `helm/openbao-middleware.yaml`, which
|
||||
defines the Traefik rate-limit and HSTS middlewares referenced by the OpenBao
|
||||
Ingress.
|
||||
|
||||
On Railiance01 directly:
|
||||
|
||||
```bash
|
||||
@@ -51,10 +66,13 @@ sudo env KUBECONFIG=/etc/rancher/k3s/k3s.yaml make openbao-status
|
||||
```
|
||||
|
||||
If the repo is not present on Railiance01 yet, copy only the non-secret values
|
||||
file and run Helm directly:
|
||||
and middleware files, then run Helm directly:
|
||||
|
||||
```bash
|
||||
scp helm/openbao-values.yaml tegwick@92.205.62.239:/tmp/openbao-values.yaml
|
||||
scp helm/openbao-middleware.yaml tegwick@92.205.62.239:/tmp/openbao-middleware.yaml
|
||||
ssh tegwick@92.205.62.239 \
|
||||
'sudo env KUBECONFIG=/etc/rancher/k3s/k3s.yaml kubectl apply -f /tmp/openbao-middleware.yaml'
|
||||
ssh tegwick@92.205.62.239 \
|
||||
'sudo env KUBECONFIG=/etc/rancher/k3s/k3s.yaml helm upgrade --install openbao openbao/openbao \
|
||||
--version 0.28.2 \
|
||||
@@ -78,6 +96,8 @@ Expected immediately after install:
|
||||
- `openbao-0` is Running.
|
||||
- `openbao`, `openbao-active`, `openbao-internal`, and `openbao-ui` services
|
||||
exist as cluster-internal services.
|
||||
- After DNS points at the cluster ingress, `https://bao.coulomb.social` serves
|
||||
the OpenBao UI over valid TLS.
|
||||
- data and audit PVCs are Bound.
|
||||
- `bao status` reports `Initialized: false` and `Sealed: true`.
|
||||
|
||||
@@ -213,6 +233,50 @@ Store that token through the approved operator secret path, then revoke or
|
||||
tightly escrow the initial root token. The root token should not become the
|
||||
normal operator credential.
|
||||
|
||||
## SSH Secrets Engine (ops-warden)
|
||||
|
||||
After `openbao-configure-initial`, enable the SSH user CA used by `ops-warden`
|
||||
(`warden sign` via `backend: vault`). This is **NET-WP-0020 T5** / **WP-0008 T2**
|
||||
prerequisite.
|
||||
|
||||
Declarative artifacts:
|
||||
|
||||
- `openbao/ssh/roles-spec.yaml` — `adm-role`, `agt-role`, `atm-role` TTLs
|
||||
- `openbao/policies/warden-sign.hcl` — least-privilege signing policy
|
||||
- `scripts/openbao-apply-ssh-engine.sh` — idempotent apply via `kubectl exec`
|
||||
- `scripts/openbao-verify-ssh-engine.sh` — non-mutating verification
|
||||
|
||||
Apply (requires `platform-admin` or equivalent token with `ssh/*` admin):
|
||||
|
||||
```bash
|
||||
mkdir -p ~/.local/openbao
|
||||
# Store platform-admin token locally (mode 600, never commit):
|
||||
# echo '<token>' > ~/.local/openbao/platform-admin.token && chmod 600 ~/.local/openbao/platform-admin.token
|
||||
|
||||
OPENBAO_TOKEN_FILE=~/.local/openbao/platform-admin.token OPENBAO_SSH_CA_PUBKEY_OUT=/tmp/openbao-ssh-ca.pub make openbao-configure-ssh
|
||||
|
||||
OPENBAO_TOKEN_FILE=~/.local/openbao/platform-admin.token make openbao-verify-ssh
|
||||
```
|
||||
|
||||
The apply script exports the CA public key to `OPENBAO_SSH_CA_PUBKEY_OUT` and
|
||||
updates K8s secret `openbao/openbao-ssh-ca-pub` (non-secret pubkey only).
|
||||
|
||||
Create a dedicated warden signing token (do not use platform-admin daily):
|
||||
|
||||
```bash
|
||||
kubectl exec -n openbao openbao-0 -- bao token create -policy=warden-sign -period=8h -orphan
|
||||
```
|
||||
|
||||
Host trust and principals are **railiance-infra** scope:
|
||||
|
||||
```bash
|
||||
cd ~/railiance-infra
|
||||
make bootstrap-ssh-ca SSH_CA_PUBKEY=/tmp/openbao-ssh-ca.pub
|
||||
```
|
||||
|
||||
Then on the workstation: `bao login` (or export `VAULT_TOKEN` from the
|
||||
`warden-sign` token) and run `warden sign` per `ops-warden/wiki/OpenBaoSshEngineChecklist.md`.
|
||||
|
||||
## Auth And Workload Integration
|
||||
|
||||
Initial auth model:
|
||||
@@ -228,6 +292,56 @@ Initial auth model:
|
||||
| Human identity | NetKingdom IAM Profile/OIDC | target model; OpenBao is not the identity provider |
|
||||
| Automation | Kubernetes auth or short-lived operator token | no root tokens in automation |
|
||||
|
||||
### Browser UI Login
|
||||
|
||||
The browser operator surface is:
|
||||
|
||||
```text
|
||||
https://bao.coulomb.social
|
||||
```
|
||||
|
||||
Use the KeyCape-backed auth method:
|
||||
|
||||
```text
|
||||
method: OIDC
|
||||
namespace: leave blank
|
||||
mount path: netkingdom
|
||||
role: platform-admin
|
||||
```
|
||||
|
||||
The OpenBao UI redirects the browser to KeyCape at `kc.coulomb.social`, then
|
||||
returns to:
|
||||
|
||||
```text
|
||||
https://bao.coulomb.social/ui/vault/auth/netkingdom/oidc/callback
|
||||
```
|
||||
|
||||
The legacy `keycape` mount remains a compatibility alias for existing
|
||||
operator notes and CLI experiments. The preferred browser mount is
|
||||
`netkingdom`.
|
||||
|
||||
The browser callback URI must be present in both:
|
||||
|
||||
- KeyCape `openbao-admin` client redirect URIs; and
|
||||
- OpenBao `auth/netkingdom/role/platform-admin` `allowed_redirect_uris`.
|
||||
|
||||
If the compatibility alias is kept enabled, also keep
|
||||
`https://bao.coulomb.social/ui/vault/auth/keycape/oidc/callback` in the
|
||||
KeyCape client and `auth/keycape/role/platform-admin`.
|
||||
|
||||
Use the browser UI for metadata inspection and attended operator workflows.
|
||||
Do not use the OpenBao root token through the browser UI. Do not copy secret
|
||||
values, Inter-Hub keys, unseal shares, root tokens, OIDC client secrets, or
|
||||
screenshots of secret values into Git, State Hub, chat, or workplans.
|
||||
|
||||
For `HF-WP-0001`, prefer metadata-only inspection of candidate paths such as:
|
||||
|
||||
```text
|
||||
platform/
|
||||
platform/operators/
|
||||
platform/operators/inter-hub/
|
||||
```
|
||||
|
||||
Workload delivery choice:
|
||||
|
||||
- Prefer External Secrets Operator for values that should become Kubernetes
|
||||
@@ -299,8 +413,8 @@ make openbao-verify-authenticated
|
||||
The target prompts for the token without echoing it, never puts the token on
|
||||
the command line, and only runs non-mutating checks. It verifies that
|
||||
`bao audit list` shows `file/`, `bao secrets list` shows `platform/`,
|
||||
`bao auth list` shows both `kubernetes/` and `keycape/`, and that the file
|
||||
audit log is non-empty.
|
||||
`bao auth list` shows `kubernetes/`, `netkingdom/`, and `keycape/`, and that
|
||||
the file audit log is non-empty.
|
||||
|
||||
If a previous attended OIDC login stored a still-valid token in the pod token
|
||||
helper, use:
|
||||
|
||||
Reference in New Issue
Block a user