ops: add HashiCorp Vault for secrets management
Replaces .env files across all KiteStacks apps. Vault runs as a Docker container bound to 127.0.0.1:8200 with file storage backend. - apps/vault/: compose file + vault.hcl config (TLS disabled, localhost only) - scripts/vault-env.sh: fetches secret from Vault KV and injects as env vars before running docker compose (drops the .env pattern entirely) - scripts/vault-init.sh: one-time init — GPG-encrypts unseal keys to ~/.vault-keys.gpg, creates kitestacks policy + limited app token - scripts/vault-unseal.sh: post-restart unseal via GPG-decrypted key - docs/vault-setup.md: full setup guide including secret migration steps Usage: vault-env.sh kitestacks/authentik -- docker compose up -d Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
5b3698191e
commit
dbcf51993d
6 changed files with 321 additions and 0 deletions
113
docs/vault-setup.md
Normal file
113
docs/vault-setup.md
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
# HashiCorp Vault: Secrets Management
|
||||
|
||||
Vault replaces `.env` files across all KiteStacks apps. Secrets live in Vault's encrypted storage; nothing sensitive is ever written to disk in plaintext or committed to git.
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
monk (T14s)
|
||||
└── Docker: hashicorp/vault:1.17
|
||||
├── Bound to 127.0.0.1:8200 only (never public)
|
||||
├── Storage: vault_data Docker volume (encrypted at rest)
|
||||
└── secret/kitestacks/<app>
|
||||
├── kitestacks/authentik → AUTHENTIK_SECRET_KEY, PG_PASS
|
||||
├── kitestacks/cloudflared → TUNNEL_TOKEN
|
||||
├── kitestacks/kite-ai → WEBUI_SECRET_KEY, ...
|
||||
└── kitestacks/openproject → OPENPROJECT_OIDC_SECRET
|
||||
|
||||
scripts/vault-env.sh pulls secrets at deploy time and injects them as env vars.
|
||||
No .env files. No secrets in git.
|
||||
```
|
||||
|
||||
## One-time setup
|
||||
|
||||
### 1. Install Vault CLI on monk
|
||||
|
||||
```bash
|
||||
curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
|
||||
echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
|
||||
sudo apt update && sudo apt install -y vault
|
||||
```
|
||||
|
||||
### 2. Start Vault
|
||||
|
||||
```bash
|
||||
cd ~/kitestacks-homelab/apps/vault
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
### 3. Initialize and unseal
|
||||
|
||||
```bash
|
||||
export VAULT_ADDR=http://127.0.0.1:8200
|
||||
# Needs GPG key set up: gpg --gen-key if you don't have one
|
||||
GPG_RECIPIENT=kenpat7177@gmail.com bash ~/kitestacks-homelab/scripts/vault-init.sh
|
||||
```
|
||||
|
||||
This saves encrypted keys to `~/.vault-keys.gpg` and creates a `kitestacks` policy token.
|
||||
|
||||
### 4. Write your first secrets
|
||||
|
||||
```bash
|
||||
export VAULT_ADDR=http://127.0.0.1:8200
|
||||
# Use the app token created by vault-init.sh
|
||||
# (or root token from: gpg --decrypt ~/.vault-keys.gpg | python3 -c "import json,sys; print(json.load(sys.stdin)['root_token'])")
|
||||
|
||||
vault kv put secret/kitestacks/authentik \
|
||||
AUTHENTIK_SECRET_KEY="$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | head -c 64)" \
|
||||
PG_PASS="your-postgres-password"
|
||||
|
||||
vault kv put secret/kitestacks/cloudflared \
|
||||
TUNNEL_TOKEN="your-cf-tunnel-token"
|
||||
|
||||
vault kv put secret/kitestacks/openproject \
|
||||
OPENPROJECT_OIDC_SECRET="your-oidc-secret"
|
||||
```
|
||||
|
||||
### 5. Write app token to ~/.vault-token
|
||||
|
||||
```bash
|
||||
# The app token was printed by vault-init.sh — paste it here:
|
||||
echo "hvs.YOURTOKEN" > ~/.vault-token
|
||||
chmod 600 ~/.vault-token
|
||||
```
|
||||
|
||||
## Deploying apps with Vault
|
||||
|
||||
Instead of `docker compose up -d`, use vault-env.sh:
|
||||
|
||||
```bash
|
||||
# Add scripts/ to PATH or use full path
|
||||
PATH="$HOME/kitestacks-homelab/scripts:$PATH"
|
||||
|
||||
vault-env.sh kitestacks/authentik -- \
|
||||
docker compose -f apps/authentik/docker-compose.yml up -d
|
||||
|
||||
vault-env.sh kitestacks/cloudflared -- \
|
||||
docker compose -f apps/cloudflared/docker-compose.yml up -d
|
||||
```
|
||||
|
||||
## After a reboot (unseal)
|
||||
|
||||
Vault is sealed after every restart. Unseal it before any deployments:
|
||||
|
||||
```bash
|
||||
export VAULT_ADDR=http://127.0.0.1:8200
|
||||
bash ~/kitestacks-homelab/scripts/vault-unseal.sh
|
||||
```
|
||||
|
||||
Or add to a post-boot script / systemd unit that runs after docker.
|
||||
|
||||
## Verifying secrets
|
||||
|
||||
```bash
|
||||
vault kv get secret/kitestacks/authentik
|
||||
vault kv list secret/kitestacks/
|
||||
```
|
||||
|
||||
## Why not just use Docker secrets?
|
||||
|
||||
Docker Swarm secrets are great but require Swarm mode. For a single-node compose setup, Vault gives you:
|
||||
- Central secret versioning and audit log
|
||||
- Rotation without touching compose files
|
||||
- Same pattern you'd use in a real Kubernetes/Nomad environment
|
||||
Loading…
Add table
Add a link
Reference in a new issue