···1+# spindle secrets with openbao
2+3+This document covers setting up Spindle to use OpenBao for secrets
4+management instead of the default SQLite backend.
5+6+## installation
7+8+Install OpenBao from nixpkgs:
9+10+```bash
11+nix-env -iA nixpkgs.openbao
12+```
13+14+## local development setup
15+16+Start OpenBao in dev mode:
17+18+```bash
19+bao server -dev
20+```
21+22+This starts OpenBao on `http://localhost:8200` with a root token. Save
23+the root token from the output -- you'll need it.
24+25+Set up environment for bao CLI:
26+27+```bash
28+export BAO_ADDR=http://localhost:8200
29+export BAO_TOKEN=hvs.your-root-token-here
30+```
31+32+Create the spindle KV mount:
33+34+```bash
35+bao secrets enable -path=spindle -version=2 kv
36+```
37+38+Set up AppRole authentication:
39+40+Create a policy file `spindle-policy.hcl`:
41+42+```hcl
43+path "spindle/data/*" {
44+ capabilities = ["create", "read", "update", "delete", "list"]
45+}
46+47+path "spindle/metadata/*" {
48+ capabilities = ["list", "read", "delete"]
49+}
50+51+path "spindle/*" {
52+ capabilities = ["list"]
53+}
54+```
55+56+Apply the policy and create an AppRole:
57+58+```bash
59+bao policy write spindle-policy spindle-policy.hcl
60+bao auth enable approle
61+bao write auth/approle/role/spindle \
62+ token_policies="spindle-policy" \
63+ token_ttl=1h \
64+ token_max_ttl=4h
65+```
66+67+Get the credentials:
68+69+```bash
70+bao read auth/approle/role/spindle/role-id
71+bao write -f auth/approle/role/spindle/secret-id
72+```
73+74+Configure Spindle:
75+76+Set these environment variables for Spindle:
77+78+```bash
79+export SPINDLE_SERVER_SECRETS_PROVIDER=openbao
80+export SPINDLE_SERVER_SECRETS_OPENBAO_ADDR=http://localhost:8200
81+export SPINDLE_SERVER_SECRETS_OPENBAO_ROLE_ID=your-role-id-from-above
82+export SPINDLE_SERVER_SECRETS_OPENBAO_SECRET_ID=your-secret-id-from-above
83+export SPINDLE_SERVER_SECRETS_OPENBAO_MOUNT=spindle
84+```
85+86+Start Spindle:
87+88+Spindle will now use OpenBao for secrets storage with automatic token
89+renewal.
90+91+## verifying setup
92+93+List all secrets:
94+95+```bash
96+bao kv list spindle/
97+```
98+99+Add a test secret via Spindle API, then check it exists:
100+101+```bash
102+bao kv list spindle/repos/
103+```
104+105+Get a specific secret:
106+107+```bash
108+bao kv get spindle/repos/your_repo_path/SECRET_NAME
109+```
110+111+## how it works
112+113+- Secrets are stored at `spindle/repos/{sanitized_repo_path}/{secret_key}`
114+- Each repository gets its own namespace
115+- Repository paths like `at://did:plc:alice/myrepo` become
116+ `at_did_plc_alice_myrepo`
117+- The system automatically handles token renewal using AppRole
118+ authentication
119+- On shutdown, Spindle cleanly stops the token renewal process
120+121+## troubleshooting
122+123+**403 errors**: Check that your BAO_TOKEN is set and the spindle mount
124+exists
125+126+**404 route errors**: The spindle KV mount probably doesn't exist - run
127+the mount creation step again
128+129+**Token expired**: The AppRole system should handle this automatically,
130+but you can check token status with `bao token lookup`