Secrets Management for Homelabs: Redaction, Scanning, and Rehydration

By Anas Semesmieh · May 10, 2026 · Homelab · Security

The moment you push a config file to a public Git repo, every password, API key, and token in it is compromised. Even if you delete the commit, it lives in Git history forever. My homelab backup repo is public — and it's safe — because every secret passes through a three-stage lifecycle: redact, scan, rehydrate.

Full secrets catalog: docs/SECRETS.md

The Secrets Inventory

My homelab manages secrets across 9 services. Here's what gets redacted:

ServiceSecretsLocation
PlexOnlineToken, Username, MailPreferences.xml
Pi-holeAdmin session tokenpihole.toml
TautulliAPI key, admin passwordconfig.ini
HomepageWidget API keys (Portainer, Tautulli, Traefik, Glances)services.yaml
TraefikWildcard TLS cert + private keytls.yaml, certs/
Arr StackProwlarr/Radarr/Sonarr API keysconfig.xml
GluetunWireGuard private keydocker-compose.yml
ImmichPostgreSQL password.env (not tracked)
Home AssistantLong-lived access tokensRuntime only

Stage 1: Automated Redaction

The redact-secrets.sh script uses sed to replace sensitive values with REDACTED. It targets two categories:

Generic Patterns

Case-insensitive matching for common secret field names:

password, passwd, api_key, api-key, token, secret, client_secret, passkey

Service-Specific Patterns

Targeted replacements for known config formats:

Stage 2: Leak Scanning Gate

Even with automated redaction, new services or config format changes can introduce secrets the patterns don't catch. The scan-secrets.sh script is the safety net:

grep -RInE '(password|api_?key|token|secret)[[:space:]]*[:=][[:space:]]*[^#[:space:]]+' configs/

If any match is found, the script exits with code 1 and the backup pipeline stops — no commit, no push. This has caught secrets from newly added services more than once.

Stage 3: Rehydration on Restore

When restoring from backup, every REDACTED placeholder must be replaced with real values. The workflow:

  1. Create ~/.homelab-secrets.env with all actual values (chmod 600, never in Git)
  2. Source the file: source ~/.homelab-secrets.env
  3. Run sed commands to inject each secret into its config file
  4. Verify: grep -r "REDACTED" configs/ — must return nothing

The SECRETS.md catalog documents each secret with:

Rotation Practices

Security Rules I Follow

  1. Never commit unredacted secrets to Git — always run scan-secrets.sh before pushing manual changes
  2. Store .env.secrets locally only — file permissions 600, added to .gitignore
  3. Test service connectivity after rehydration — check logs for auth errors
  4. Validate secrets after injection — grep -r "REDACTED" configs/ must return empty

What I Learned

Back to the series: Start Here · Backup Automation · Docker Compose Stack · Disaster Recovery