docs(audit): create comprehensive security audit report with critical findings and remediation steps
12 KiB
Security Audit Report: Homelab Infrastructure
Report Date: April 12, 2026
Auditor: FrankGPT Security Analysis
Scope: Complete repository scan for exposed secrets, credentials, and security vulnerabilities
Status: 🔴 CRITICAL ISSUES FOUND
Executive Summary
A comprehensive security audit of the homelab repository has identified 1 critical vulnerability and 3 high-priority security enhancements needed to align with industry best practices. While the infrastructure demonstrates strong GitOps practices with environment variable usage in most services, several hardcoded credentials and exposed ports present immediate security risks.
Risk Level: 🔴 HIGH (Immediate remediation required)
🔴 Critical Findings
1. Hardcoded Plex Claim Token in Git Repository
Severity: 🔴 CRITICAL
File: nodes/waldorf/plex/compose.yaml (Line 12)
Issue: Plex claim token committed directly to version control
# CURRENT (INSECURE)
environment:
- PLEX_CLAIM=claim-sxFpsPTDzzF-9RZAxtUL
Risk Assessment:
- Impact: Anyone with repository access can claim/hijack your Plex server
- Exposure: Token visible in Git history, even if removed from HEAD
- Validity: Plex claim tokens typically expire after 4 minutes, but this pattern indicates potential for other secrets
Remediation Required:
-
Immediate Action:
# Revoke/invalidate this claim token in Plex # Visit: https://www.plex.tv/claim/ -
Code Fix:
# CORRECTED (SECURE) environment: - PLEX_CLAIM=${PLEX_CLAIM} # Placeholder -
Komodo Configuration:
- Add via Komodo UI → Stack → Environment Variables
- Variable:
PLEX_CLAIM=claim-NEW_TOKEN_HERE
-
Git History Cleanup (Optional but Recommended):
# WARNING: Rewriting history affects all collaborators git filter-branch --force --index-filter \ "git rm --cached --ignore-unmatch nodes/waldorf/plex/compose.yaml" \ --prune-empty --tag-name-filter cat -- --all
Status: ⏳ PENDING REMEDIATION
🟡 High-Priority Security Enhancements
2. Redis Exposed Without Authentication
Severity: 🟡 HIGH
File: nodes/heimdall/core/compose.yaml (Line 40)
Issue: Redis cache exposed on host port 6379 without password protection
# CURRENT (INSECURE)
redis:
image: redis:7-alpine
ports:
- "6379:6379" # ⚠️ Publicly exposed on LAN
command: redis-server --appendonly yes
# NO PASSWORD CONFIGURED
Risk Assessment:
- Impact: Unauthorized access to cached session data, potential data manipulation
- Attack Surface: Any device on LAN (10.0.0.x) can connect to Redis
- Exploitability: HIGH (Redis has no default authentication)
Remediation Options:
Option A: Remove Public Port Binding (Recommended)
redis:
image: redis:7-alpine
# ports: # REMOVED - Only accessible via Docker network
# - "6379:6379"
networks:
- proxy-net # Internal-only access
command: redis-server --appendonly yes --requirepass ${REDIS_PASSWORD}
environment:
- REDIS_PASSWORD=${REDIS_PASSWORD}
Option B: Add Password Authentication (If external access needed)
redis:
image: redis:7-alpine
ports:
- "127.0.0.1:6379:6379" # Bind to localhost only
command: redis-server --appendonly yes --requirepass ${REDIS_PASSWORD}
environment:
- REDIS_PASSWORD=${REDIS_PASSWORD}
Komodo Environment Variable:
- Add
REDIS_PASSWORD=<strong-random-password>via Komodo UI
Status: 🟡 RECOMMENDED
3. Docker Socket Proxy Configured with Broad Write Access
Severity: 🟡 MEDIUM
File: nodes/heimdall/core/compose.yaml (Lines 28-33)
Issue: Docker socket proxy allows POST operations and container lifecycle management
# CURRENT
environment:
- POST=1
- ALLOW_START=1
- ALLOW_STOP=1
- ALLOW_RESTARTS=1
Risk Assessment:
- Impact: Compromised Traefik or Komodo could manipulate all containers
- Mitigation: Proxy runs as privileged (
privileged: true), limiting lateral movement - Trade-off: Required for Komodo's container orchestration functionality
Recommendation:
- Accept Risk: This configuration is required for Komodo Core functionality
- Monitoring: Enable Docker audit logging to track container lifecycle events
- Network Isolation: Ensure
proxy-netis not exposed beyond trusted services
Status: ✅ ACCEPTED RISK (Required for functionality)
4. MongoDB Credentials Use Environment Variables (GOOD)
Severity: ✅ LOW (Best Practice Followed)
File: nodes/heimdall/core/compose.yaml (Lines 109-110)
# ✅ CORRECT IMPLEMENTATION
environment:
MONGO_INITDB_ROOT_USERNAME: ${KOMODO_DATABASE_USERNAME}
MONGO_INITDB_ROOT_PASSWORD: ${KOMODO_DATABASE_PASSWORD}
Assessment:
- Status: ✅ SECURE - No hardcoded credentials found
- Verification: Confirm
.envfile is excluded from Git (see.gitignoresection below)
5. Traefik Cloudflare API Tokens Use Environment Variables (GOOD)
Severity: ✅ LOW (Best Practice Followed)
File: nodes/heimdall/core/compose.yaml (Lines 66-67)
# ✅ CORRECT IMPLEMENTATION
environment:
- CLOUDFLARE_DNS_API_TOKEN=${CF_API_TOKEN}
- CLOUDFLARE_ZONE_API_TOKEN=${CF_ZONE_TOKEN}
Assessment:
- Status: ✅ SECURE - No hardcoded tokens found
- Recommendation: Rotate Cloudflare API tokens quarterly
🔒 Secret Management Options for This Environment
Current State: Komodo UI Environment Variables
How It Works:
- Define placeholders in
compose.yaml:${VARIABLE_NAME} - Store actual secrets in Komodo UI → Stack → Environment Variables
- Komodo injects secrets at container runtime
Pros:
- ✅ Simple to configure via web UI
- ✅ Secrets not committed to Git
- ✅ Supports per-stack secret isolation
Cons:
- ⚠️ No centralized secret rotation
- ⚠️ Manual backup of secrets required
- ⚠️ No audit trail for secret access
Recommended Enhancements
Option 1: .env File (Quick Win)
Implementation:
-
Create
.envfile in stack directory:# /nodes/heimdall/core/.env CF_API_TOKEN=your_cloudflare_api_token_here CF_ZONE_TOKEN=your_zone_token_here KOMODO_DATABASE_USERNAME=komodo_admin KOMODO_DATABASE_PASSWORD=strong_random_password_here KOMODO_ONBOARDING_KEY_HEIMDALL=onboarding_key_here REDIS_PASSWORD=another_strong_password -
Update
compose.yaml:services: komodo-core: env_file: .env # Individual environment vars still supported -
Critical: Add to
.gitignore:# Create/update .gitignore at repository root echo "**/.env" >> .gitignore echo "**/*.env" >> .gitignore git add .gitignore git commit -m "chore(security): prevent .env file commits"
Pros:
- ✅ Quick to implement
- ✅ Standard Docker Compose pattern
- ✅ Easy to backup (manual copy)
Cons:
- ⚠️ File must exist on host (NFS or local)
- ⚠️ No encryption at rest
- ⚠️ Risk of accidental Git commit
Option 2: Docker Secrets (Recommended for Production)
Implementation:
-
Create secrets on each node:
# On Heimdall echo "your_cloudflare_token" | docker secret create cf_api_token - echo "your_database_password" | docker secret create komodo_db_password - -
Update
compose.yaml:services: traefik: secrets: - cf_api_token environment: - CLOUDFLARE_DNS_API_TOKEN_FILE=/run/secrets/cf_api_token secrets: cf_api_token: external: true
Pros:
- ✅ Encrypted at rest and in transit
- ✅ Native Docker Swarm integration
- ✅ Secret rotation without container restart
Cons:
- ⚠️ Requires Docker Swarm mode (or transition to Kubernetes)
- ⚠️ More complex to configure
- ⚠️ May not integrate seamlessly with Komodo
Option 3: HashiCorp Vault (Enterprise-Grade)
Implementation:
-
Deploy Vault container:
vault: image: hashicorp/vault:latest ports: - "8200:8200" environment: - VAULT_DEV_ROOT_TOKEN_ID=myroot # CHANGE THIS -
Store secrets in Vault:
vault kv put secret/homelab/cloudflare api_token=xxx zone_token=yyy -
Use Vault Agent for injection or API calls in startup scripts
Pros:
- ✅ Centralized secret management
- ✅ Audit logging and access control
- ✅ Automatic secret rotation
- ✅ Encryption at rest
Cons:
- ⚠️ Significant operational overhead
- ⚠️ Requires learning curve
- ⚠️ Another service to maintain
Option 4: Ansible Vault (Hybrid Approach)
Implementation:
-
Encrypt variables file:
ansible-vault create ansible/vars/secrets.yml -
Store secrets:
# ansible/vars/secrets.yml (encrypted) cf_api_token: your_token_here plex_claim: your_claim_here -
Deploy with Ansible playbook:
ansible-playbook -i hosts deploy.yml --ask-vault-pass
Pros:
- ✅ Works with existing
ansible/directory structure - ✅ Encrypted at rest (AES-256)
- ✅ Can commit encrypted file to Git safely
Cons:
- ⚠️ Requires Ansible expertise
- ⚠️ Not integrated with Komodo workflow
- ⚠️ Manual decryption for ad-hoc changes
📋 Recommended Action Plan
Immediate Actions (Within 24 Hours)
| Priority | Action | Effort | Impact |
|---|---|---|---|
| 🔴 CRITICAL | Remove hardcoded PLEX_CLAIM from Git | 15 min | HIGH |
| 🔴 CRITICAL | Create .gitignore to prevent .env commits |
5 min | HIGH |
| 🟡 HIGH | Remove Redis public port binding OR add authentication | 10 min | MEDIUM |
| 🟡 HIGH | Audit all compose files for other hardcoded secrets | 30 min | MEDIUM |
Short-Term Actions (Within 1 Week)
| Priority | Action | Effort | Impact |
|---|---|---|---|
| 🟡 MEDIUM | Standardize on .env files for all stacks |
2 hours | MEDIUM |
| 🟡 MEDIUM | Document secret rotation procedures in SOP | 1 hour | MEDIUM |
| 🟢 LOW | Set calendar reminder for quarterly API token rotation | 5 min | LOW |
Long-Term Actions (Optional)
| Priority | Action | Effort | Impact |
|---|---|---|---|
| 🟢 LOW | Evaluate Docker Secrets vs. Vault for centralized management | 4 hours | HIGH |
| 🟢 LOW | Implement automated secret scanning in CI/CD pipeline | 3 hours | MEDIUM |
🛡️ Security Best Practices Checklist
✅ Already Implemented
- Most services use environment variable placeholders (
${VAR_NAME}) - Komodo UI used for secret injection at runtime
- Docker socket access mediated through proxy (not direct mount)
- Traefik handles SSL termination with Cloudflare DNS challenge
- Network segmentation via Docker networks (
proxy-net)
⏳ Needs Implementation
.gitignoreconfigured to exclude.envfiles- All hardcoded secrets removed from compose files
- Redis authentication enabled or port binding removed
- Secret rotation schedule documented
- Backup strategy for Komodo-stored environment variables
🔮 Future Enhancements
- Centralized secret management (Vault or similar)
- Automated secret scanning (pre-commit hooks)
- Audit logging for sensitive operations
- Encrypted backups of configuration data
📚 Related Documentation
- SOP-001: Migrate Stack from UI to Git - Section on Secrets Management
- TECHNICAL_RUNBOOK.md - Credential Management section
- Repository Memory: Active Tasks
🔍 Audit Methodology
Scan Coverage:
- ✅ All
compose.yamlfiles innodes/directory - ✅ Documentation files for exposed patterns
- ✅ README files for accidental credential leakage
- ✅ Repository structure for
.envor secret files
Tools Used:
- Pattern matching for common secret keywords:
password|token|secret|api_key|claim - Manual inspection of environment variable usage
- Cross-reference with Komodo UI documentation
Exclusions:
- Scripts directory (no compose files found)
- Ansible directory (no active playbooks with secrets)
Report Version: 1.0
Next Review Date: July 12, 2026 (Quarterly)
Validation Status: Ready for Implementation ✅