forked from tangled.org/core
this repo has no description
1# spindle secrets with openbao 2 3This document covers setting up Spindle to use OpenBao for secrets 4management via OpenBao Proxy instead of the default SQLite backend. 5 6## overview 7 8Spindle now uses OpenBao Proxy for secrets management. The proxy handles 9authentication automatically using AppRole credentials, while Spindle 10connects to the local proxy instead of directly to the OpenBao server. 11 12This approach provides better security, automatic token renewal, and 13simplified application code. 14 15## installation 16 17Install OpenBao from nixpkgs: 18 19```bash 20nix shell nixpkgs#openbao # for a local server 21``` 22 23## setup 24 25The setup process can is documented for both local development and production. 26 27### local development 28 29Start OpenBao in dev mode: 30 31```bash 32bao server -dev -dev-root-token-id="root" -dev-listen-address=127.0.0.1:8201 33``` 34 35This starts OpenBao on `http://localhost:8201` with a root token. 36 37Set up environment for bao CLI: 38 39```bash 40export BAO_ADDR=http://localhost:8200 41export BAO_TOKEN=root 42``` 43 44### production 45 46You would typically use a systemd service with a configuration file. Refer to 47[@tangled.org/infra](https://tangled.org/@tangled.org/infra) for how this can be 48achieved using Nix. 49 50Then, initialize the bao server: 51```bash 52bao operator init -key-shares=1 -key-threshold=1 53``` 54 55This will print out an unseal key and a root key. Save them somewhere (like a password manager). Then unseal the vault to begin setting it up: 56```bash 57bao operator unseal <unseal_key> 58``` 59 60All steps below remain the same across both dev and production setups. 61 62### configure openbao server 63 64Create the spindle KV mount: 65 66```bash 67bao secrets enable -path=spindle -version=2 kv 68``` 69 70Set up AppRole authentication and policy: 71 72Create a policy file `spindle-policy.hcl`: 73 74```hcl 75# Full access to spindle KV v2 data 76path "spindle/data/*" { 77 capabilities = ["create", "read", "update", "delete"] 78} 79 80# Access to metadata for listing and management 81path "spindle/metadata/*" { 82 capabilities = ["list", "read", "delete", "update"] 83} 84 85# Allow listing at root level 86path "spindle/" { 87 capabilities = ["list"] 88} 89 90# Required for connection testing and health checks 91path "auth/token/lookup-self" { 92 capabilities = ["read"] 93} 94``` 95 96Apply the policy and create an AppRole: 97 98```bash 99bao policy write spindle-policy spindle-policy.hcl 100bao auth enable approle 101bao write auth/approle/role/spindle \ 102 token_policies="spindle-policy" \ 103 token_ttl=1h \ 104 token_max_ttl=4h \ 105 bind_secret_id=true \ 106 secret_id_ttl=0 \ 107 secret_id_num_uses=0 108``` 109 110Get the credentials: 111 112```bash 113# Get role ID (static) 114ROLE_ID=$(bao read -field=role_id auth/approle/role/spindle/role-id) 115 116# Generate secret ID 117SECRET_ID=$(bao write -f -field=secret_id auth/approle/role/spindle/secret-id) 118 119echo "Role ID: $ROLE_ID" 120echo "Secret ID: $SECRET_ID" 121``` 122 123### create proxy configuration 124 125Create the credential files: 126 127```bash 128# Create directory for OpenBao files 129mkdir -p /tmp/openbao 130 131# Save credentials 132echo "$ROLE_ID" > /tmp/openbao/role-id 133echo "$SECRET_ID" > /tmp/openbao/secret-id 134chmod 600 /tmp/openbao/role-id /tmp/openbao/secret-id 135``` 136 137Create a proxy configuration file `/tmp/openbao/proxy.hcl`: 138 139```hcl 140# OpenBao server connection 141vault { 142 address = "http://localhost:8200" 143} 144 145# Auto-Auth using AppRole 146auto_auth { 147 method "approle" { 148 mount_path = "auth/approle" 149 config = { 150 role_id_file_path = "/tmp/openbao/role-id" 151 secret_id_file_path = "/tmp/openbao/secret-id" 152 } 153 } 154 155 # Optional: write token to file for debugging 156 sink "file" { 157 config = { 158 path = "/tmp/openbao/token" 159 mode = 0640 160 } 161 } 162} 163 164# Proxy listener for Spindle 165listener "tcp" { 166 address = "127.0.0.1:8201" 167 tls_disable = true 168} 169 170# Enable API proxy with auto-auth token 171api_proxy { 172 use_auto_auth_token = true 173} 174 175# Enable response caching 176cache { 177 use_auto_auth_token = true 178} 179 180# Logging 181log_level = "info" 182``` 183 184### start the proxy 185 186Start OpenBao Proxy: 187 188```bash 189bao proxy -config=/tmp/openbao/proxy.hcl 190``` 191 192The proxy will authenticate with OpenBao and start listening on 193`127.0.0.1:8201`. 194 195### configure spindle 196 197Set these environment variables for Spindle: 198 199```bash 200export SPINDLE_SERVER_SECRETS_PROVIDER=openbao 201export SPINDLE_SERVER_SECRETS_OPENBAO_PROXY_ADDR=http://127.0.0.1:8201 202export SPINDLE_SERVER_SECRETS_OPENBAO_MOUNT=spindle 203``` 204 205Start Spindle: 206 207Spindle will now connect to the local proxy, which handles all 208authentication automatically. 209 210## production setup for proxy 211 212For production, you'll want to run the proxy as a service: 213 214Place your production configuration in `/etc/openbao/proxy.hcl` with 215proper TLS settings for the vault connection. 216 217## verifying setup 218 219Test the proxy directly: 220 221```bash 222# Check proxy health 223curl -H "X-Vault-Request: true" http://127.0.0.1:8201/v1/sys/health 224 225# Test token lookup through proxy 226curl -H "X-Vault-Request: true" http://127.0.0.1:8201/v1/auth/token/lookup-self 227``` 228 229Test OpenBao operations through the server: 230 231```bash 232# List all secrets 233bao kv list spindle/ 234 235# Add a test secret via Spindle API, then check it exists 236bao kv list spindle/repos/ 237 238# Get a specific secret 239bao kv get spindle/repos/your_repo_path/SECRET_NAME 240``` 241 242## how it works 243 244- Spindle connects to OpenBao Proxy on localhost (typically port 8200 or 8201) 245- The proxy authenticates with OpenBao using AppRole credentials 246- All Spindle requests go through the proxy, which injects authentication tokens 247- Secrets are stored at `spindle/repos/{sanitized_repo_path}/{secret_key}` 248- Repository paths like `did:plc:alice/myrepo` become `did_plc_alice_myrepo` 249- The proxy handles all token renewal automatically 250- Spindle no longer manages tokens or authentication directly 251 252## troubleshooting 253 254**Connection refused**: Check that the OpenBao Proxy is running and 255listening on the configured address. 256 257**403 errors**: Verify the AppRole credentials are correct and the policy 258has the necessary permissions. 259 260**404 route errors**: The spindle KV mount probably doesn't exist - run 261the mount creation step again. 262 263**Proxy authentication failures**: Check the proxy logs and verify the 264role-id and secret-id files are readable and contain valid credentials. 265 266**Secret not found after writing**: This can indicate policy permission 267issues. Verify the policy includes both `spindle/data/*` and 268`spindle/metadata/*` paths with appropriate capabilities. 269 270Check proxy logs: 271 272```bash 273# If running as systemd service 274journalctl -u openbao-proxy -f 275 276# If running directly, check the console output 277``` 278 279Test AppRole authentication manually: 280 281```bash 282bao write auth/approle/login \ 283 role_id="$(cat /tmp/openbao/role-id)" \ 284 secret_id="$(cat /tmp/openbao/secret-id)" 285```