Sanitized mirror from private repository - 2026-03-26 12:32:56 UTC
This commit is contained in:
203
docs/admin/credential-rotation-checklist.md
Normal file
203
docs/admin/credential-rotation-checklist.md
Normal file
@@ -0,0 +1,203 @@
|
||||
# Credential Rotation Checklist
|
||||
|
||||
**Last audited**: March 2026
|
||||
**Purpose**: Prioritized list of credentials that should be rotated, with exact locations and steps.
|
||||
|
||||
> After rotating any credential, update it in **Vaultwarden** (collection: Homelab) as the source of truth before updating the compose file or Portainer stack.
|
||||
|
||||
---
|
||||
|
||||
## Priority Legend
|
||||
|
||||
| Symbol | Meaning |
|
||||
|--------|---------|
|
||||
| 🔴 CRITICAL | Live credential exposed in git — rotate immediately |
|
||||
| 🟠 HIGH | Sensitive secret that should be rotated soon |
|
||||
| 🟡 MEDIUM | Lower-risk but should be updated as part of routine rotation |
|
||||
| 🟢 LOW | Default/placeholder values — change before putting service in production |
|
||||
|
||||
---
|
||||
|
||||
## 🔴 CRITICAL — Rotate Immediately
|
||||
|
||||
### 1. OpenAI API Key
|
||||
- **File**: `hosts/vms/homelab-vm/hoarder.yaml:15`
|
||||
- **Service**: Hoarder AI tagging
|
||||
- **Rotation steps**:
|
||||
1. Go to [platform.openai.com/api-keys](https://platform.openai.com/api-keys)
|
||||
2. Delete the old key
|
||||
3. Create a new key
|
||||
4. Update `hosts/vms/homelab-vm/hoarder.yaml` — `OPENAI_API_KEY`
|
||||
5. Save new key in Vaultwarden → Homelab → Hoarder
|
||||
6. Redeploy hoarder stack via Portainer
|
||||
|
||||
### 2. Gmail App Password — Authentik + Joplin SMTP (see Vaultwarden → Homelab → Gmail App Passwords)
|
||||
- **Files**:
|
||||
- `hosts/synology/calypso/authentik/docker-compose.yaml` (SMTP password)
|
||||
- `hosts/synology/atlantis/joplin.yml` (SMTP password)
|
||||
- **Rotation steps**:
|
||||
1. Go to [myaccount.google.com/apppasswords](https://myaccount.google.com/apppasswords)
|
||||
2. Revoke the old app password
|
||||
3. Create a new app password (label: "Homelab SMTP")
|
||||
4. Update both files above with the new password
|
||||
5. Save in Vaultwarden → Homelab → Gmail App Passwords
|
||||
6. Redeploy both stacks
|
||||
|
||||
### 3. Gmail App Password — Vaultwarden SMTP (see Vaultwarden → Homelab → Gmail App Passwords)
|
||||
- **File**: `hosts/synology/atlantis/vaultwarden.yaml`
|
||||
- **Rotation steps**: Same as above — create a separate app password per service
|
||||
1. Revoke old, create new
|
||||
2. Update `hosts/synology/atlantis/vaultwarden.yaml` — `SMTP_PASSWORD`
|
||||
3. Redeploy vaultwarden stack
|
||||
|
||||
### 4. Gmail App Password — Documenso SMTP (see Vaultwarden → Homelab → Gmail App Passwords)
|
||||
- **File**: `hosts/synology/atlantis/documenso/documenso.yaml:47`
|
||||
- **Rotation steps**: Same pattern — revoke, create new, update compose, redeploy
|
||||
|
||||
### 5. Gmail App Password — Reactive Resume SMTP (see Vaultwarden → Homelab → Gmail App Passwords)
|
||||
- **File**: `hosts/synology/calypso/reactive_resume_v5/docker-compose.yml`
|
||||
- **Rotation steps**: Same pattern
|
||||
|
||||
### 6. Gitea PAT — retro-site.yaml (now removed)
|
||||
- **Status**: ✅ Hardcoded token removed from `retro-site.yaml` — now uses `${GIT_TOKEN}` env var
|
||||
- **Action**: Revoke the old token `REDACTED_GITEA_TOKEN` in Gitea
|
||||
1. Go to `https://git.vish.gg/user/settings/applications`
|
||||
2. Revoke the token associated with `retro-site.yaml`
|
||||
3. The stack now uses the `GIT_TOKEN` Gitea secret — no file update needed
|
||||
|
||||
### 7. Gitea PAT — Ansible Playbook (now removed)
|
||||
- **Status**: ✅ Hardcoded token removed from `ansible/automation/playbooks/setup_gitea_runner.yml`
|
||||
- **Action**: Revoke the old token `REDACTED_GITEA_TOKEN` in Gitea
|
||||
1. Go to `https://git.vish.gg/user/settings/applications`
|
||||
2. Revoke the associated token
|
||||
3. Future runs of the playbook will prompt for the token interactively
|
||||
|
||||
---
|
||||
|
||||
## 🟠 HIGH — Rotate Soon
|
||||
|
||||
### 8. Authentik Secret Key
|
||||
- **File**: `hosts/synology/calypso/authentik/docker-compose.yaml:58,89`
|
||||
- **Impact**: Rotating this invalidates **all active sessions** — do during a maintenance window
|
||||
- **Rotation steps**:
|
||||
1. Generate a new 50-char random key: `openssl rand -base64 50`
|
||||
2. Update `AUTHENTIK_SECRET_KEY` in the compose file
|
||||
3. Save in Vaultwarden → Homelab → Authentik
|
||||
4. Redeploy — all users will need to re-authenticate
|
||||
|
||||
### 9. Mastodon SECRET_KEY_BASE + OTP_SECRET
|
||||
- **File**: `hosts/synology/atlantis/mastodon.yml:67-68`
|
||||
- **Impact**: Rotating breaks **all active sessions and 2FA tokens** — coordinate with users
|
||||
- **Rotation steps**:
|
||||
1. Generate new values:
|
||||
```bash
|
||||
docker run --rm tootsuite/mastodon bundle exec rake secret
|
||||
docker run --rm tootsuite/mastodon bundle exec rake secret
|
||||
```
|
||||
2. Update `SECRET_KEY_BASE` and `OTP_SECRET` in `mastodon.yml`
|
||||
3. Save in Vaultwarden → Homelab → Mastodon
|
||||
4. Redeploy
|
||||
|
||||
### 10. Grafana OAuth Client Secret (Authentik Provider)
|
||||
- **File**: `hosts/vms/homelab-vm/monitoring.yaml:986`
|
||||
- **Rotation steps**:
|
||||
1. Go to Authentik → Applications → Providers → Grafana provider
|
||||
2. Edit → regenerate client secret
|
||||
3. Copy the new secret
|
||||
4. Update `GF_AUTH_GENERIC_OAUTH_CLIENT_SECRET` in `monitoring.yaml`
|
||||
5. Save in Vaultwarden → Homelab → Grafana OAuth
|
||||
6. Redeploy monitoring stack
|
||||
|
||||
---
|
||||
|
||||
## 🟡 MEDIUM — Routine Rotation
|
||||
|
||||
### 11. Watchtower HTTP API Token (`REDACTED_WATCHTOWER_TOKEN`)
|
||||
- **Files** (must update all at once):
|
||||
- `hosts/synology/atlantis/watchtower.yml`
|
||||
- `hosts/synology/atlantis/grafana_prometheus/prometheus.yml`
|
||||
- `hosts/synology/atlantis/grafana_prometheus/prometheus_mariushosting.yml`
|
||||
- `hosts/synology/calypso/grafana_prometheus/prometheus.yml`
|
||||
- `hosts/synology/setillo/prometheus/prometheus.yml`
|
||||
- `hosts/synology/calypso/watchtower.yaml`
|
||||
- `common/watchtower-enhanced.yaml`
|
||||
- `common/watchtower-full.yaml`
|
||||
- **Rotation steps**:
|
||||
1. Choose a new token: `openssl rand -hex 32`
|
||||
2. Update `WATCHTOWER_HTTP_API_TOKEN` in all watchtower stack files
|
||||
3. Update `bearer_token` in all prometheus.yml scrape configs
|
||||
4. Save in Vaultwarden → Homelab → Watchtower
|
||||
5. Redeploy all affected stacks (watchtower first, then prometheus)
|
||||
|
||||
### 12. Shlink API Key
|
||||
- **File**: `hosts/vms/homelab-vm/shlink.yml:41`
|
||||
- **Rotation steps**:
|
||||
1. Log into Shlink admin UI
|
||||
2. Generate a new API key
|
||||
3. Update `DEFAULT_API_KEY` in `shlink.yml`
|
||||
4. Save in Vaultwarden → Homelab → Shlink
|
||||
5. Redeploy shlink stack
|
||||
|
||||
### 13. Spotify Client ID + Secret (YourSpotify)
|
||||
- **Files**:
|
||||
- `hosts/physical/concord-nuc/yourspotify.yaml`
|
||||
- `hosts/vms/bulgaria-vm/yourspotify.yml`
|
||||
- **Rotation steps**:
|
||||
1. Go to [developer.spotify.com/dashboard](https://developer.spotify.com/dashboard)
|
||||
2. Select the app → Settings → Rotate client secret
|
||||
3. Update both files with new `SPOTIFY_CLIENT_ID` and `SPOTIFY_CLIENT_SECRET`
|
||||
4. Save in Vaultwarden → Homelab → Spotify API
|
||||
5. Redeploy both stacks
|
||||
|
||||
### 14. SNMPv3 Auth + Priv Passwords
|
||||
- **Files**:
|
||||
- `hosts/synology/atlantis/grafana_prometheus/snmp.yml` (exporter config)
|
||||
- `hosts/vms/homelab-vm/monitoring.yaml` (prometheus scrape config)
|
||||
- **Note**: Must match the SNMPv3 credentials configured on the target devices (Synology NAS, switches)
|
||||
- **Rotation steps**:
|
||||
1. Change the SNMPv3 user credentials on each monitored device (DSM → Terminal & SNMP)
|
||||
2. Update `auth_password` and `priv_password` in `snmp.yml`
|
||||
3. Update the corresponding values in `monitoring.yaml`
|
||||
4. Save in Vaultwarden → Homelab → SNMP
|
||||
5. Redeploy monitoring stack
|
||||
|
||||
---
|
||||
|
||||
## 🟢 LOW — Change Before Production Use
|
||||
|
||||
These are clearly placeholder/default values that exist in stacks but are either:
|
||||
- Not currently deployed in production, or
|
||||
- Low-impact internal-only services
|
||||
|
||||
| Service | File | Credential | Value to Replace |
|
||||
|---------|------|-----------|-----------------|
|
||||
| NetBox | `hosts/synology/atlantis/netbox.yml` | Superuser password | see Vaultwarden |
|
||||
| Paperless | `hosts/synology/calypso/paperless/docker-compose.yml` | Admin password | see Vaultwarden |
|
||||
| Seafile | `hosts/synology/calypso/seafile-server.yaml` | Admin password | see Vaultwarden |
|
||||
| Gotify | `hosts/vms/homelab-vm/gotify.yml` | Admin password | `REDACTED_PASSWORD` |
|
||||
| Invidious (old) | `hosts/physical/concord-nuc/invidious/invidious_old/invidious.yaml` | PO token | Rotate if service is active |
|
||||
|
||||
---
|
||||
|
||||
## Post-Rotation Checklist
|
||||
|
||||
After rotating any credential:
|
||||
|
||||
- [ ] New value saved in Vaultwarden under correct collection/folder
|
||||
- [ ] Compose file updated in git repo
|
||||
- [ ] Stack redeployed via Portainer (or `docker compose up -d --force-recreate`)
|
||||
- [ ] Service verified healthy (check Uptime Kuma / Portainer logs)
|
||||
- [ ] Old credential revoked at the source (Google, OpenAI, Gitea, etc.)
|
||||
- [ ] `.secrets.baseline` updated if detect-secrets flags the new value:
|
||||
```bash
|
||||
detect-secrets scan --baseline .secrets.baseline
|
||||
git add .secrets.baseline && git commit -m "chore: update secrets baseline after rotation"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- [Secrets Management Strategy](secrets-management.md)
|
||||
- [Headscale Operations](../services/individual/headscale.md)
|
||||
- [B2 Backup Status](b2-backup-status.md)
|
||||
Reference in New Issue
Block a user