From 6b63dc92953cf3f4ae5e752909abd8a86019e453 Mon Sep 17 00:00:00 2001 From: Graham McIntire Date: Sun, 1 Feb 2026 17:05:55 -0600 Subject: [PATCH] encryption updates --- README.md | 64 +++++++++++++++++++++++++++++++++++++++ k8s/deployment.yaml | 5 +++ priv/static/changelog.txt | 5 +++ 3 files changed, 74 insertions(+) diff --git a/README.md b/README.md index 17260a83..d1baaadf 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,70 @@ See [TIMESCALEDB.md](TIMESCALEDB.md) for detailed installation and configuration **How it works**: Migrations detect the environment (`MIX_ENV`) and only enable TimescaleDB features (hypertables, compression, retention policies, continuous aggregates) in production. +## Encryption Setup (Production) + +TowerOps uses AES-256-GCM encryption for sensitive data (SNMP communities, MikroTik API passwords, etc.). + +### Development/Test + +Encryption keys are pre-configured in `config/dev.exs` and `config/test.exs`. No action required. + +### Production + +Set the `CLOAK_KEY` environment variable with a base64-encoded 32-byte key: + +```bash +# Generate encryption key +openssl rand -base64 32 +``` + +**Important**: +- Store the generated key securely in 1Password or your secrets manager +- **Never commit the production key to version control** +- Losing the encryption key makes encrypted data unrecoverable + +#### Kubernetes Deployment + +**If secret doesn't exist yet** (new deployment): + +```bash +# Generate CLOAK_KEY (store in 1Password first!) +CLOAK_KEY=$(openssl rand -base64 32) + +# Create towerops-secrets with all required keys +kubectl create secret generic towerops-secrets \ + --from-literal=RELEASE_COOKIE=$(openssl rand -base64 32) \ + --from-literal=SECRET_KEY_BASE=$(mix phx.gen.secret) \ + --from-literal=CLOAK_KEY="$CLOAK_KEY" \ + -n towerops +``` + +**If secret already exists** (add CLOAK_KEY to existing secret): + +```bash +# Store new key in 1Password first! +# Bash/Zsh: +CLOAK_KEY=$(openssl rand -base64 32) + +# Fish shell: +set CLOAK_KEY (openssl rand -base64 32) + +# Method 1: Using kubectl create with dry-run and apply +kubectl create secret generic towerops-secrets \ + --from-literal=CLOAK_KEY="$CLOAK_KEY" \ + --dry-run=client -o yaml | \ + kubectl apply -f - -n towerops + +# Method 2: Direct inline generation (works in all shells) +kubectl create secret generic towerops-secrets \ + --from-literal=CLOAK_KEY="$(openssl rand -base64 32)" \ + --dry-run=client -o yaml | \ + kubectl apply -f - -n towerops + +# Restart pods to pick up new key +kubectl rollout restart deployment/towerops -n towerops +``` + ## Development ### Database diff --git a/k8s/deployment.yaml b/k8s/deployment.yaml index 2e04b6c4..48c0cdc4 100644 --- a/k8s/deployment.yaml +++ b/k8s/deployment.yaml @@ -99,6 +99,11 @@ spec: secretKeyRef: name: towerops-secrets key: SECRET_KEY_BASE + - name: CLOAK_KEY + valueFrom: + secretKeyRef: + name: towerops-secrets + key: CLOAK_KEY - name: DATABASE_SSL value: "true" - name: DATABASE_SSL_VERIFY diff --git a/priv/static/changelog.txt b/priv/static/changelog.txt index 4179a2fe..f971d3b1 100644 --- a/priv/static/changelog.txt +++ b/priv/static/changelog.txt @@ -3,6 +3,11 @@ Devices Tested & Working * Ubiquiti AC, LTU, AirFiber * Cambium ePMP +2026-02-01 +* Firmware version fetching and notification for Mikrotik devices +* UI cleanup +* Check passwords against Have I been pwned database + 2026-01-31 * Small ui tweaks * Backend refactoring