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>
3.4 KiB
3.4 KiB
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
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
cd ~/kitestacks-homelab/apps/vault
docker compose up -d
3. Initialize and unseal
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
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
# 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:
# 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:
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
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