Mirror of @tangled.org/core. Running on a Raspberry Pi Zero 2 (Please be gentle).
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

docs/spindle: describe openbao proxy dev and prod setups

Signed-off-by: Anirudh Oppiliappan <anirudh@tangled.sh>

authored by

Anirudh Oppiliappan and committed by
Tangled
ee1083d6 cccf0b0b

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