Overview
Quick Commands
# edit + deploy
git status
git add -A
git commit -m "docs: update"
git push
# rebuild static blog output (local)
cd site
npm ci --no-audit --no-fund
npm run build
# VPS: pull only
# (on server)
git pull --ff-only
Big picture (external gateway → test/prod proxy → apps)
[ Internet / external main gateway ]
|
v
+--------------------+
| proxy.test/prod | (your NGINX/sidecar, keeps CA chain in sync from Vault)
+--------------------+
| |
v v
[App A] [App B] ... (each app has its own agent)
| |
(secrets) (leaf certs/secrets)
Vault runs separately and is reachable as vault.test.local (test) and vault.prod.local (prod).
All agents (proxy + apps) talk to Vault over mTLS.
1) One-time base initialization (per environment)
Do this once per env (test / prod) before connecting proxies and apps.
- Offline Root CA erzeugen
- Script:
01_make_offline_root_ca.sh --env test - Purpose: create the offline root CA key/cert.
- Script:
- Create the Vault intermediate & sign it with the offline root
- Script:
02_intermediate_in_vault_sign_with_root.sh --env test --config ./config/apps.yaml - Purpose: enable PKI mount in Vault, sign the intermediate, set CA URLs.
- Script:
- Issue the Vault server certificate
-
Script:
03_issue_vault_server_cert.sh --env test --config ./config/apps.yaml \ --cn vault.test.local \ --dns "vault.test.local,localhost,host.containers.internal" \ --ips "127.0.0.1,::1,<public-ip>" -
Important:
--cnmust match what clients verify (SNI).
If your agents connect via IP, keepaddress=https://<public-ip>:22300and settls_server_name="vault.test.local"(hostname check against the cert).
-
- Switch Vault to HTTPS
- Script:
04_enable_https_in_compose.sh --env test --port 22300 --cn vault.test.local - Result: Vault config uses
tls_cert_file=.../fullchain.crt,tls_key_file=.../server.key.
- Script:
(Optional) 5. Admin mTLS client cert
- Script:
05_issue_admin_client_cert.sh --env test - For the
vaultCLI: setVAULT_CLIENT_CERT/VAULT_CLIENT_KEY.
2) Connect proxy test/prod to Vault (CA chain only)
For your proxy.test/prod NGINX instances so they keep the CA chain updated.
- Script:
setup-vault-agent-proxy-config2.sh --env test --config ./config/apps.yaml - Liefert:
- mTLS-Client (agent.crt/key + ca.pem)
- Agent config that renders only the chain (no leaf certs)
- Post-hook
scripts/vault-agent-post.shcan triggernginx -s reloadon updates (via labeltls=true).
When?
- Once during proxy setup.
- After that, rotation runs automatically (agent renews auth and re-renders the chain).
3) Onboard a new app (secrets and/or leaf certs)
Two typical paths:
A) Container app with a sidecar agent (e.g. Nextcloud + DB password)
- Create AppRole + KV/policies
- Script:
bootstrap_secret_agent.sh --env test --config ./config/apps.yaml nctest - Result:
- Policies (KV-read, optional PKI-Issue)
- AppRole (RoleID/SecretID) → stored at
/home/<appuser>/vault/creds/(0400)
- Script:
- Start the sidecar agent in Compose
- In your
docker-compose.yml(likevault-agent-nctest) - The agent reads
role_id/secret_id, logs in, and renders secrets into/vault/secrets/...(tmpfs volume).
- In your
When?
- Every time you set up a new container app.
- SecretID rotation: either re-run
bootstrap_secret_agent.shwith a new SecretID option or runvault write auth/approle/role/<role>/secret-id.
B) Host app (Unix service) needs a leaf certificate (mTLS)
- mTLS client for the agent
- Script:
setup-vault-agent-mtls-client-config2.sh --env test --config ./config/apps.yaml - Result:
~/vault/mtls/{agent.key,agent.crt,ca.crt}
- Script:
- App agent that renders leaf certificates
- Script:
setup-vault-agent-app-config2.sh --env test --config ./config/apps.yaml - Result: a systemd user unit
~/.vault-agent-<app>/...that fetches and rotates the leaf (<app>.key+fullchain.pem).
- Script:
When?
- Once during onboarding.
- Rotation runs automatically via the agent (renew + re-render).
4) Which scripts for which event?
| Event | Goal | Scripts / action | Order | Key checks |
|---|---|---|---|---|
| Fresh Vault setup (per env) | PKI + HTTPS ready | 01 → 02 → 03 → 04 (→ 05 optional) |
1→2→3→4 | vault status, agent login works, CN/SAN correct |
| Connect proxy.test/prod | CA chain stays current | setup-vault-agent-proxy-config2.sh |
1 | Agent logs “rendered chain…”, NGINX reload ok |
| New container app | Secrets + optional PKI | bootstrap_secret_agent.sh → Compose sidecar |
1→2 | Agent logs “authentication successful”, secret files present |
| New host app (mTLS leaf) | Leaf cert + rotation | setup-vault-agent-mtls-client-config2.sh → setup-vault-agent-app-config2.sh |
1→2 | Leaf files exist, systemd unit active, app starts |
| SecretID rotation | Refresh AppRole SecretID | bootstrap_secret_agent.sh (new option) or vault write auth/approle/.../secret-id |
– | New secret_id in app path, reload agent |
| Vault server cert expiring | New server cert | 03_issue_vault_server_cert.sh (same CN/SAN) → reload/restart Vault |
1→(2) | Clients connect, tls_server_name matches |
| Intermediate/root rotation | New CA hierarchy | 02 (new intermediate) + redeploy chains |
1 | Proxies/apps receive new chain (agents handle it) |
| DNS broken in container | Fix connectivity | In agent config: use address=https://<ip>:22300 and keep tls_server_name=vault.test.local |
– | No “no such host” in logs |
| “no known role ID” | Fix AppRole login | Check /vault/creds/role_id and secret_id (0400, readable, correct) |
– | Agent shows “authentication successful” |
| x509 CN mismatch | Fix TLS hostname | Re-issue cert or adjust tls_server_name (must match CN/SAN) |
– | No “certificate is valid for … not …” |
5) Which auth is used where?
- Container sidecar (secrets): AppRole (RoleID/SecretID from
bootstrap_secret_agent.sh). - Proxy agent (CA chain only): mTLS client cert (from
setup-vault-agent-mtls-client-config2.sh). - Host app agent (leaf): mTLS client cert plus PKI role to issue a leaf cert.
Yes: you can replace AppRole with mTLS if you want client-cert distribution everywhere. In containers AppRole is often more convenient (no long-lived private key files). Mixed mode is fine.
6) Minimal commands (copy/paste, test environment)
Base setup (one-time):
./01_make_offline_root_ca.sh --env test
./02_intermediate_in_vault_sign_with_root.sh --env test --config ./config/apps.yaml
./03_issue_vault_server_cert.sh --env test --config ./config/apps.yaml \
--cn vault.test.local \
--dns "vault.test.local,localhost,host.containers.internal" \
--ips "127.0.0.1,::1,<public-ip>"
./04_enable_https_in_compose.sh --env test --port 22300 --cn vault.test.local
Attach proxy test to Vault (CA chain only):
./setup-vault-agent-proxy-config2.sh --env test --config ./config/apps.yaml
# check: systemctl --user status vault-agent-<proxy>-ca.service (if a unit was created)
New container app (e.g. nctest):
./bootstrap_secret_agent.sh --env test --config ./config/apps.yaml nctest
# then start your docker/podman compose with the vault-agent-nctest sidecar
New host app (leaf cert):
./setup-vault-agent-mtls-client-config2.sh --env test --config ./config/apps.yaml
./setup-vault-agent-app-config2.sh --env test --config ./config/apps.yaml
7) Logging notes (short)
- Container best practice: log to stdout/stderr; avoid writing log files under
/var/log/...inside containers (permission problems). For MariaDB: disable file logging in.cnfor route to stderr; debug viapodman logs. - Agents: everything is visible in the logs; key lines:
authentication successfulrendered "<template>" => "<destination>"renewed auth token
If you want, I can turn this into a one-page checklist—but for now you have the key events and the matching scripts in one place.