Proxmox VEXVIII · Maintenance & LifecycleCompliance maintenance
Compliance maintenance: PCI-DSS, SOC 2, ISO 27001 evidence collection
What you'll learn
- Map common compliance frameworks to specific PVE cluster controls
- Build an evidence-collection pipeline that runs quarterly
- Automate as much of the audit response as possible
- Maintain continuous compliance between audits, not just at audit time
Prerequisites
Verified against Proxmox VE 9.2.4 · Proxmox Backup Server 4.2.5 · Ceph Squid / Tentacle · Debian 13 (Trixie) · Linux kernel 7.0 (PVE 9.2 default) · 2026-08-07
Compliance maintenance: PCI-DSS, SOC 2, ISO 27001 evidence collection
Compliance audits are expensive and disruptive. The way to survive them is to maintain continuous compliance — produce evidence continuously, not just at audit time. This lesson shows how to map common frameworks to PVE cluster controls and build an automated evidence pipeline.
The compliance frameworks in scope
Most clusters need to satisfy one or more of:
- PCI-DSS (Payment Card Industry Data Security Standard): any system that processes, stores, or transmits cardholder data
- SOC 2 (System and Organisation Controls): a trust-framework audit that B2B customers ask for
- ISO 27001: international information security management standard
- HIPAA: health information in the US
- GDPR: personal data of EU residents
The controls overlap heavily. Most clusters implement a “common controls framework” that satisfies all of them simultaneously.
The control mapping
For a PVE cluster, the controls cluster into:
Access control
- User accounts with unique credentials
- Role-based access (PVE roles: PVEAdmin, PVEAuditor, etc.)
- Multi-factor authentication for admin access
- Privileged access management (PAM) for break-glass admin
- Audit logging of all access events
Cryptographic controls
- TLS for all API and GUI traffic
- TLS for PBS replication
- Disk encryption for sensitive workloads (LUKS inside VMs, or ZFS native encryption for the pool)
- Key management (where do keys live, who can access them)
Network security
- Firewall rules (datacenter, node, VM levels)
- Network segmentation (VLAN isolation)
- Intrusion detection / prevention
- Wireless security (if applicable)
Vulnerability management
- Patch cadence (security patches within 30 days of release)
- Vulnerability scanning (OpenVAS, Nessus)
- Configuration hardening (CIS benchmarks)
Backup and recovery
- Daily backups with verified integrity
- Off-site / immutable backup copies
- Tested recovery procedure with documented RTO/RPO
Logging and monitoring
- Centralised audit log
- Tamper-evident storage
- Real-time alerting on critical events
- Log retention meeting compliance requirements (1+ year)
Change management
- Documented change process
- Pre-production testing
- Rollback procedure
Mapping controls to PVE features
| Control | PVE feature |
|---|---|
| User authentication | PVE users, PAM, optional MFA via external IdP |
| Role-based access | PVE roles (PVEAdmin, PVEAuditor, etc.) |
| Audit logging | journald, auditd, pveproxy access log |
| Network segmentation | VLAN-aware bridges, PVE firewall |
| Encryption in transit | TLS via pveproxy (configurable cipher list) |
| Encryption at rest | ZFS native encryption or LUKS inside VMs |
| Vulnerability management | apt upgrade, pveam update, OpenVAS scan |
| Backup integrity | PBS verify jobs, chunk checksums |
| Backup immutability | PBS datastore on ZFS with snapshots |
| Logging retention | logrotate, off-host log forwarding |
| Monitoring & alerting | Prometheus + Alertmanager |
| Change management | Documented via runbook + git history |
Building the evidence pipeline
A quarterly evidence collection script:
#!/bin/bash
# /usr/local/bin/collect-compliance-evidence.sh
# Run quarterly. Output: /evidence/<date>/
DATE=$(date +%Y-%m-%d)
OUT="/srv/evidence/$DATE"
mkdir -p "$OUT"
# === Access control ===
echo "## Users and roles" > "$OUT/access-control.md"
pvesh get /access/users --output-format json | \
jq -r '.[] | "- \(.userid) (\(.comment // "no comment")): \(.roleid // "(none)")"' \
>> "$OUT/access-control.md"
pvesh get /access/roles --output-format json | \
jq -r '.[] | "### Role: \(.roleid)\n\(.privs | to_entries | map("- \(.key): \(.value | join(", "))") | join("\n"))\n"' \
>> "$OUT/access-control.md"
# === MFA ===
echo "## MFA configuration" >> "$OUT/access-control.md"
pvesh get /access/tfa --output-format json | \
jq -r '.[] | "- User \(.userid): \(.type) (\(.description // ""))"' \
>> "$OUT/access-control.md"
# === Network security ===
echo "## Firewall rules" > "$OUT/firewall-rules.txt"
pvesh get /cluster/firewall/options >> "$OUT/firewall-rules.txt"
pvesh get /cluster/firewall/rules --output-format json | \
jq -r '.[] | "\(.action // "ACCEPT") \(.direction) \(.type) \(.source) -> \(.dest):\(.dport // "-") [\(if .enable // true then "ENABLED" else "DISABLED" end)]"' \
>> "$OUT/firewall-rules.txt"
# === Encryption ===
echo "## TLS configuration" > "$OUT/tls-config.txt"
openssl s_client -connect "$(hostname):8006" -tls1_3 </dev/null 2>&1 | \
grep -E 'Protocol|Cipher|subject|issuer' >> "$OUT/tls-config.txt"
openssl s_client -connect "$(hostname):8006" -tls1 </dev/null 2>&1 | \
head -1 | sed 's/^/TLS 1.0: /' >> "$OUT/tls-config.txt"
# === Patch status ===
echo "## Package versions" > "$OUT/packages.txt"
dpkg --list | grep -E 'proxmox|pve-|qemu|zfs' >> "$OUT/packages.txt"
# === Backup integrity ===
echo "## PBS verify history" > "$OUT/pbs-verify.txt"
ssh pbs.example.com "proxmox-backup-manager verify-job list --output-format json" | \
jq -r '.[] | "Job \(.id): last run \(.last-run) status=\(.status) chunks=\(.verified_chunks) errors=\(.errors)"' \
>> "$OUT/pbs-verify.txt"
# === Audit log ===
echo "## Audit log last 90 days" > "$OUT/audit-summary.txt"
journalctl --since "90 days ago" -u auditd --output json | \
jq -r '.MESSAGE' | wc -l | xargs echo "Total audit events:" >> "$OUT/audit-summary.txt"
journalctl --since "90 days ago" -u auditd -p err | wc -l | xargs echo "Error events:" >> "$OUT/audit-summary.txt"
# === Vulnerability scan ===
echo "## Vulnerability scan" > "$OUT/vuln-scan.txt"
if [ -f /var/log/openvas-last-scan.json ]; then
jq -r '.[] | "- \(.host): \(.name) (CVSS \(.cvss))"' \
/var/log/openvas-last-scan.json >> "$OUT/vuln-scan.txt"
else
echo "No OpenVAS scan found; run openvas-scan before collecting evidence" \
>> "$OUT/vuln-scan.txt"
fi
# === Bundle ===
tar czf "/srv/evidence/evidence-$DATE.tar.gz" -C /srv/evidence "$DATE"
echo "Evidence bundle: /srv/evidence/evidence-$DATE.tar.gz"
Run quarterly via cron. The bundle is what you hand to the auditor or attach to your SOC 2 portal.
Continuous compliance
The difference between annual audit mode and continuous compliance:
| Mode | Effort | Risk |
|---|---|---|
| Annual audit | Massive scramble before audit; gaps discovered late | High — non-compliance for most of the year |
| Continuous | Steady, automated, small effort | Low — always ready |
Practices for continuous compliance:
- Evidence pipeline runs daily or weekly, not quarterly. Saves point-in-time evidence you can correlate with incidents.
- Configuration as code. PVE firewall rules, sudo config, auditd rules — all in version control. Diff against the deployed config to find drift.
- Automated tests for controls. “Are audit rules active?” “Is MFA enforced for admins?” “Is PBS verify running weekly?” — write a script that checks and reports.
- Quarterly tabletop reviews. Walk through the audit scope with the team. Identify gaps. Fix them.
Specific framework mappings
PCI-DSS v4.0 essentials
For a cluster in PCI scope:
- Req 1: Network security controls — firewall, segmentation
- Req 2: Default credentials changed (no admin/admin)
- Req 3: Cardholder data not stored on the cluster (unless explicitly required)
- Req 4: TLS for transmission of cardholder data
- Req 6: Secure development and change management
- Req 7: Restrict access by business need-to-know
- Req 8: Unique user IDs, MFA for admin access
- Req 9: Physical access restrictions (data centre)
- Req 10: Logging and monitoring of all access
- Req 11: Vulnerability scanning, penetration testing
- Req 12: Information security policy
Most of these map to standard hardening + the evidence pipeline.
SOC 2 Trust Service Criteria
- CC6.1: Logical access controls
- CC6.6: Network security controls
- CC7.2: System monitoring and intrusion detection
- CC7.3: Incident response
- A1.1: Availability commitments and capacity planning
- C1.1: Confidentiality controls
A SOC 2 Type 2 audit covers a period (usually 6–12 months) and requires evidence that controls operated throughout.
ISO 27001:2022
- A.5.15: Access control
- A.5.16: Identity management
- A.5.17: Authentication information
- A.5.28: Collection of evidence
- A.8.9: Configuration management
- **A.8.15: Logging
- **A.8.16: Monitoring activities
- **A.8.24: Use of cryptography
Annex A controls map to the same PVE features as PCI and SOC 2.
Common mistakes
- Last-minute evidence gathering. Pulling evidence together the week before the audit is the worst time to find gaps.
- No version control on configs. A config drift between what was audited and what’s deployed invalidates the audit.
- Treating compliance as separate from operations. The same monitoring, patching, and access controls that keep the cluster running also satisfy compliance.
- Auditor-driven scope creep. The auditor asks for “evidence of X”. Push back on scope that isn’t in the original framework.
Production considerations
- Audit budget. SOC 2 audits cost $30k–$100k. ISO 27001 audits similar. Continuous compliance reduces audit effort by 30–50%.
- Internal vs external. Internal audits catch issues before the external auditor does. Run internal audits quarterly.
- Tooling. Use a GRC (Governance, Risk, Compliance) tool like Vanta, Drata, or Tugboat Logic to automate evidence collection and framework mapping.
- Time to remediation. Track MTTR for compliance findings. Internal: 2 weeks. External: 30–60 days.
Key takeaways
- Map controls once, automate evidence collection forever.
- Continuous compliance > annual scramble.
- Version-control all configurations.
- Quarterly internal audits catch issues before external auditors.
Knowledge check
Knowledge check · 4 questions
Q1. Which approach to compliance reduces audit effort most?
Q2. PCI-DSS, SOC 2, and ISO 27001 have completely different controls.
Q3. Which of these should be in a compliance evidence bundle? (Select all that apply)
Q4. Name the PVE API endpoint that returns the list of users and roles.
Passing score: 75%. Answers are checked in this browser.