From ac8d2f548b84aae80fa6d3702d6dacd03d833a04 Mon Sep 17 00:00:00 2001 From: Viktor Barzin Date: Sat, 25 Apr 2026 16:48:53 +0000 Subject: [PATCH] paperless-ngx: migrate to proxmox-lvm-encrypted Document scans (receipts, contracts, IDs) are unambiguously sensitive PII. Storage decision rule defaults sensitive data to `proxmox-lvm-encrypted`, but paperless-ngx had been left on plain `proxmox-lvm` by an abandoned migration attempt that left a dormant, non-Terraform-managed encrypted PVC sitting unbound for 11 days. Cleaned up the orphan, added the encrypted PVC properly via Terraform, rsynced data with deployment scaled to 0, swapped claim_name. Plain `proxmox-lvm` PVC retained for a 7-day soak before removal. Co-Authored-By: Claude Opus 4.7 --- docs/architecture/storage.md | 4 +++- stacks/paperless-ngx/main.tf | 24 +++++++++++++++++++++++- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/docs/architecture/storage.md b/docs/architecture/storage.md index 69b32a1a..28ab28ca 100644 --- a/docs/architecture/storage.md +++ b/docs/architecture/storage.md @@ -129,7 +129,9 @@ graph TB 5. **Passphrase management**: ExternalSecret syncs passphrase from Vault KV (`secret/viktor/proxmox_csi_encryption_passphrase`) → K8s Secret. Backup key at `/root/.luks-backup-key` on PVE host. **Services on encrypted storage (2026-04-15 migration):** -vaultwarden, dbaas (mysql+pg+pgadmin), mailserver, nextcloud, forgejo, matrix, n8n, affine, health, hackmd, redis, headscale, frigate, meshcentral, technitium, actualbudget, grampsweb, owntracks, paperless-ngx, wealthfolio, monitoring (alertmanager) +vaultwarden, dbaas (mysql+pg+pgadmin), mailserver, nextcloud, forgejo, matrix, n8n, affine, health, hackmd, redis, headscale, frigate, meshcentral, technitium, actualbudget, grampsweb, owntracks, wealthfolio, monitoring (alertmanager) + +**Services migrated later** (post-audit catch-up): paperless-ngx (2026-04-25 — sensitive document scans had been left on plain `proxmox-lvm` by an abandoned attempt; rsync swap cleaned up the orphan and re-did via Terraform). **CSI node plugin memory**: Requires 1280Mi limit for LUKS2 Argon2id key derivation (~1GiB). Set via `node.plugin.resources` in Helm values (not `node.resources`). diff --git a/stacks/paperless-ngx/main.tf b/stacks/paperless-ngx/main.tf index bceafaf2..4bafe6ce 100644 --- a/stacks/paperless-ngx/main.tf +++ b/stacks/paperless-ngx/main.tf @@ -86,6 +86,28 @@ resource "kubernetes_persistent_volume_claim" "data_proxmox" { } } +resource "kubernetes_persistent_volume_claim" "data_encrypted" { + wait_until_bound = false + metadata { + name = "paperless-ngx-data-encrypted" + namespace = kubernetes_namespace.paperless-ngx.metadata[0].name + annotations = { + "resize.topolvm.io/threshold" = "80%" + "resize.topolvm.io/increase" = "100%" + "resize.topolvm.io/storage_limit" = "5Gi" + } + } + spec { + access_modes = ["ReadWriteOnce"] + storage_class_name = "proxmox-lvm-encrypted" + resources { + requests = { + storage = "1Gi" + } + } + } +} + resource "kubernetes_deployment" "paperless-ngx" { metadata { @@ -196,7 +218,7 @@ resource "kubernetes_deployment" "paperless-ngx" { volume { name = "data" persistent_volume_claim { - claim_name = kubernetes_persistent_volume_claim.data_proxmox.metadata[0].name + claim_name = kubernetes_persistent_volume_claim.data_encrypted.metadata[0].name } } }