Files
homelab/SECURITY.md
T
k.rennerandClaude 255c4e707e docs: Add SECURITY.md with RBAC and key rotation procedures
Created comprehensive security documentation including:
- Access control matrix for infrastructure and applications
- Authentication methods (Authentik SSO, SSH keys, API tokens)
- Secret management procedures (Ansible Vault, .envrc)
- SSH key rotation procedure with step-by-step guide
- API token management and rotation schedules
- Network security overview (VLANs, firewall, TLS)
- Incident response procedures
- Quarterly and annual security checklists

Resolves SEC-1 (SSH key rotation docs) and SEC-3 (RBAC documentation)
from infrastructure review.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-02-18 18:21:14 +01:00

7.5 KiB

Security Documentation

Last Updated: 2026-02-18 Next Review: 2026-05-18 (Quarterly)


Access Control Matrix

Infrastructure Access

User/Service Proxmox Admin Ansible Vault Gitea Admin RustFS S3 Production SSH Authentik Admin
krenner Full Read/Write Full Full Full Full
ansible-runner API Token Read - Write Deploy only -
CI/CD Pipeline API Token Read API Token Write Deploy only -

Service Access via Authentik SSO

Application Admin Group Editor Group Viewer Group Public Access
Grafana (dash.renner.uno) Grafana Admins Grafana Editors All authenticated No
Gitea (gitea.renner.uno) admins - All authenticated Read-only repos
Immich (immich.renner.uno) - - All authenticated No
Paperless (paperless.renner.uno) - - All authenticated No

Authentication Methods

Primary: Authentik SSO

Integrated Applications:

  • Grafana (dash.renner.uno)
  • Gitea (gitea.renner.uno)
  • Immich
  • Paperless
  • Home Assistant (optional)

Secondary: SSH Key Authentication

  • Key Type: Ed25519 (preferred), RSA 4096 (legacy)
  • Storage: opentofu/locals.tf (public keys only)
  • Private Keys: Never stored in repository

Infrastructure: API Tokens

  • Proxmox: Token-based auth (root@pam!ansible)
  • UniFi: Username/password (service account)
  • RustFS/MinIO: Access key/secret key

Secret Management

Ansible Vault

Location: ansible/inventory/group_vars/all/vault.yml

Access Method:

# Via environment variable (recommended)
export ANSIBLE_VAULT_PASSWORD="<password>"
ansible-playbook playbook.yml

# Via password script
ansible-playbook playbook.yml --vault-password-file vault-password.sh

Stored Secrets:

  • Proxmox API token secret
  • Cloudflared tunnel token
  • OAuth client secrets (Gitea, Grafana)
  • Database credentials
  • Service account passwords

Environment Variables (.envrc)

Loaded via: direnv

Contains:

  • ANSIBLE_VAULT_PASSWORD
  • TF_VAR_* variables for OpenTofu
  • AWS credentials for RustFS S3
  • UniFi controller credentials

Security: File is in .gitignore, loaded only in development environment


SSH Key Management

Current Keys

Key Name User Purpose Deployed To
krenner@fortress krenner Primary admin access All infrastructure
ansible-runner@ci-new CI/CD Automated deployments All infrastructure

Key Rotation Schedule

  • Frequency: Quarterly (every 3 months)
  • Next Rotation: 2026-05-01

Key Rotation Procedure

  1. Generate new keypair:

    ssh-keygen -t ed25519 -C "krenner@fortress-$(date +%Y%m)" -f ~/.ssh/id_ed25519_new
    
  2. Add new public key to infrastructure:

    # Update opentofu/locals.tf with new public key
    # Keep old key temporarily for rollback
    
  3. Deploy new key:

    cd opentofu && tofu apply
    
  4. Test access with new key:

    ssh -i ~/.ssh/id_ed25519_new root@jupiter "echo success"
    
  5. Update CI/CD secrets:

    • Gitea Repository Settings > Secrets
    • Update SSH_PRIVATE_KEY (base64 encoded)
  6. Remove old key after grace period (1 week):

    # Remove old key from locals.tf
    tofu apply
    
  7. Update local SSH config:

    mv ~/.ssh/id_ed25519_new ~/.ssh/id_ed25519
    

API Token Management

Proxmox API Token

  • Token ID: root@pam!ansible
  • Permissions: Full (PVEAdmin)
  • Rotation: Annually or after suspected compromise

Rotation Procedure:

  1. Generate new token in Proxmox UI (Datacenter > Permissions > API Tokens)
  2. Update Ansible vault: vault_pve_token_secret
  3. Update Gitea secrets: PROXMOX_TOKEN_SECRET
  4. Update .envrc: TF_VAR_proxmox_token_secret
  5. Test: tofu plan
  6. Revoke old token

RustFS/MinIO Access Keys

  • Access Key: Stored in vault
  • Rotation: Annually

OAuth Client Secrets

  • Gitea: vault_gitea_authentik_client_secret
  • Grafana: vault_grafana_authentik_client_secret
  • Rotation: When compromised or annually

Network Security

Firewall Rules (UniFi)

  • Default: Deny all inbound
  • Allowed Inbound:
    • SSH (22) from management VLAN only
    • HTTP/HTTPS (80/443) to Caddy ingress
    • Cloudflare Tunnel (outbound only)

VLANs

VLAN Name Purpose Access Level
40 v40srv Service network Internal services
45 v42ing Ingress/DMZ Public-facing
50 v50pri Private Workstations

TLS/SSL

  • Certificates: Let's Encrypt via Caddy
  • Renewal: Automatic (ACME)
  • Internal Services: Proxmox self-signed (TODO: internal CA)

Incident Response

Security Incident Procedure

  1. Identify & Contain:

    • Isolate affected systems (disable network interface)
    • Preserve logs before rotation
  2. Assess Impact:

    • What systems were accessed?
    • What data was exposed?
    • How did attacker gain access?
  3. Eradicate:

    • Rotate all potentially compromised credentials
    • Patch vulnerability if known
    • Rebuild compromised systems from IaC
  4. Recover:

    • Restore from known-good backups
    • Re-enable services incrementally
    • Monitor for re-compromise
  5. Post-Incident:

    • Document timeline and actions
    • Update security procedures
    • Implement preventive measures

Emergency Credential Rotation

If widespread compromise suspected:

# 1. Rotate Proxmox API token (via UI)
# 2. Rotate all vault secrets
ansible-vault rekey inventory/group_vars/all/vault.yml

# 3. Generate new SSH keys
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_emergency

# 4. Update and deploy
# Update locals.tf, vault, .envrc
tofu apply
ansible-playbook plays/update-ssh-keys.yml

# 5. Invalidate old Authentik sessions
# Via Authentik Admin UI: Sessions > Terminate All

Compliance Checklist

Quarterly Security Review

  • Review access control matrix for accuracy
  • Verify no orphaned accounts/keys
  • Check all secrets are vault-encrypted
  • Review Wazuh security alerts
  • Run Trivy vulnerability scan
  • Test backup restore procedure
  • Verify MFA enabled for all admin accounts
  • Review and update this document

Annual Security Audit

  • Full credential rotation
  • Penetration testing (external)
  • Review firewall rules
  • Audit Proxmox permissions
  • Review Authentik policies
  • Update security documentation
  • Disaster recovery drill

Security Tools

Deployed

Tool Purpose Location
Wazuh SIEM/Security monitoring LXC 222
Trivy Vulnerability scanning CI/CD weekly
Authentik Identity provider LXC 130-133
Fail2ban Brute-force protection All SSH hosts
  • CrowdSec (collaborative security)
  • Internal CA for service-to-service TLS
  • Hardware security key support (FIDO2)

Contact

Security Issues: Create private issue in Gitea or contact infrastructure owner directly.

Emergency: If active compromise detected, isolate systems first, then contact.


Document maintained by infrastructure team. Review quarterly.