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>
113 lines
3.4 KiB
Markdown
113 lines
3.4 KiB
Markdown
# 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
|