On this page
You’re building a knowledge base that documents your whole lab. The temptation to paste “the Proxmox token, so it’s handy” into a note is enormous. Resist it completely, from your very first commit — because a knowledge base is the worst place to keep a secret. This is a ⚠️-flagged post in the series for a reason: this is a mistake that’s genuinely painful to undo.
Never commit a secret value to your vault. Store the value in a purpose-built secret store; put only a pointer — the variable name and its location — in your notes. Git never forgets, so a secret committed once is a secret you must rotate.
The examples use stand-ins — replace them with your own. /root/.myofficelab-secrets → wherever you keep your secret store; PROXMOX_API_TOKEN_ID/_SECRET → your actual variable names; CHANGE_ME and the-leaked-secret-value → your real values (which live in the store, never in a note). Never paste a real secret into an example just because a placeholder is sitting there.
Why a knowledge base is uniquely bad for secrets
The whole point of the vault is that it gets copied and projected everywhere. That’s a feature for knowledge and a catastrophe for credentials. This isn’t a niche concern — hard-coded credentials are catalogued as CWE-798 by MITRE, and OWASP’s Secrets Management Cheat Sheet gives the same guidance this post does: keep secrets out of source and reference them from a dedicated store. Trace where a single note travels:
Delete the secret from the note tomorrow and it still lives in Git history, in last night’s backup, and possibly in a search index that already embedded it. One paste, five places to clean.
The right pattern: pointers, not values
Keep credentials in a purpose-built store and reference them by name. In my lab the store is a single root-only file on one host, and every note that needs a credential names the variable, never the value.
# /root/.myofficelab-secrets — chmod 600, outside any repo
PROXMOX_API_TOKEN_ID=youruser@pve!app-token
PROXMOX_API_TOKEN_SECRET=CHANGE_ME
GRAFANA_API_KEY=CHANGE_ME
## Proxmox API access
Token lives as PROXMOX_API_TOKEN_ID / PROXMOX_API_TOKEN_SECRET
in /root/.myofficelab-secrets on the ops host. PVEAdmin role.
Do not paste the secret here.
If an app reads the vault-documented service, store its secret in an OS keystore (libsecret / GNOME Keyring on Linux, Keychain on macOS) or a dedicated manager like Vaultwarden. The note still only records the variable name and which store holds it.
Legitimate access resolves the pointer in seconds; the note stays safe to mount, mirror, publish, and index.
Prevention: a guard that refuses the commit
Make it hard to commit a secret by accident. A pre-commit hook that greps staged content for obvious secret shapes turns a silent mistake into a blocked commit.
cat > .git/hooks/pre-commit <<'EOF'
#!/bin/bash
# Block commits that look like they contain secrets.
if git diff --cached -U0 | grep -nEi \
'(api[_-]?key|token|secret|password|passwd|BEGIN [A-Z ]*PRIVATE KEY)[[:space:]]*[:=]' \
| grep -v 'CHANGE_ME'; then
echo "✋ Possible secret in staged changes — commit blocked."
echo " Store the value in your secret store; commit only a variable-name pointer."
exit 1
fi
EOF
chmod +x .git/hooks/pre-commit
This catches the obvious mistakes — an assignment that looks like a credential. It won’t catch a bare high-entropy string with no label. Use a dedicated scanner like gitleaks for real coverage; the hook is your cheap first line.
⚠️ Recovery: you already committed a secret
If a secret is already in your history, deleting it in a new commit is not enough — it’s still one command away in the history. You must rewrite history and rotate the credential. GitHub’s own guidance on removing sensitive data says exactly this: purge every commit and treat the credential as compromised.
Before touching Git, invalidate the exposed secret at its source — regenerate the API token, change the password. Assume it leaked. This is the step people skip and regret.
git-filter-repo is the modern, recommended tool for rewriting history:
# Install (Debian/Ubuntu): sudo apt-get install -y git-filter-repo
# Replace every occurrence of the leaked value across ALL commits
echo 'the-leaked-secret-value==>REDACTED' > /tmp/replacements.txt
git filter-repo --replace-text /tmp/replacements.txt
To remove an entire file that should never have been tracked:
git filter-repo --path secrets.env --invert-paths
git push --force --all
git push --force --tags
Every existing clone and mount now has divergent history — re-clone them fresh. Anyone who pulled the bad history must discard their copy. This blast radius is exactly why prevention beats recovery.
The full copy-paste recovery sequence is in the paired playbook: Vault Secret Store + History Scrub.
The swap-in box
GitHub/GitLab hosted: enable native push protection / secret scanning — it blocks known secret formats at push time. Any Git host: gitleaks as a pre-commit hook or CI step is tool-agnostic. Secret store choice: a root-only file is the minimum; HashiCorp Vault, Bitwarden/Vaultwarden, or your OS keystore are all valid — the note-side rule (pointer, never value) is identical regardless.
What you have now
A vault that is safe to copy, mirror, publish, and index — because the one class of content that must never spread is structurally kept out of it. With the substrate solid and secure, the next post makes the vault smart: turning a flat pile of pages into a connected graph, modeling knowledge as a brain.
Related posts:
- Never Lose a Homelab Note Again: A Git + Markdown Vault — the substrate this discipline protects
- Your Homelab Needs a Second Brain — Here’s Why — why the vault gets copied everywhere in the first place
- Turn a Pile of Notes Into a Connected Brain — the next step: connect the pages into a graph
- Why Auto-Syncing Your Notes Repo Will Corrupt It — where the commit-time secret scan is enforced
- Already Made a Mess of Your Notes? Here’s the Fix — the rotate-and-purge step as part of a full cleanup
- Vaultwarden on Proxmox LXC: Self-Hosted Password Manager — a real secret store to point your notes at
- Proxmox Security Hardening — securing the hosts your secret store lives on
Comments
Comments are powered by GitHub Discussions — sign in with a GitHub account to join the conversation.