Skip to main content
PensionsPortal.ie generates two categories of logs: audit logs (compliance-critical, append-only) and operational logs (infrastructure and application telemetry). Each has distinct retention requirements driven by IORP II and GDPR obligations.

Log Categories

CategorySourceSensitivityRetention
Audit logsaudit_logs table (PostgreSQL)High — governance record7 years minimum
Application logsPino → Vercel log drainMedium — operational90 days
Error eventsSentryMedium — operational90 days (Sentry default)
Access logsCloudflareLow–Medium30 days (Cloudflare default)
Deployment logsVercelLow60 days (Vercel default)

Audit Log Retention

The audit_logs table is the primary compliance record. It must be retained for a minimum of 7 years to satisfy:
  • IORP II governance documentation requirements
  • GDPR Article 5(1)(e) storage limitation (balancing governance obligation against data minimisation)
  • Pensions Authority inspection readiness

Retention Implementation

Audit logs are stored in Neon PostgreSQL (AWS eu-west-2). Retention is managed by:
  1. No deletion policy — no DELETE operation is permitted on the audit_logs table at any role level
  2. Neon PITR — point-in-time restore retains data within the backup window (7–30 days)
  3. Annual archive — at the end of each calendar year, audit logs older than 1 year should be exported to a long-term store (e.g., S3 with Glacier tier, or equivalent EU-based cold storage)
Neon’s PITR window (default 7 days) does not by itself satisfy 7-year retention. An annual export process must be established and tested to ensure long-term audit log availability.

Annual Archive Process

  1. Export audit logs for the preceding year:
    COPY (
      SELECT * FROM audit_logs
      WHERE timestamp >= '2024-01-01' AND timestamp < '2025-01-01'
    ) TO '/tmp/audit_logs_2024.csv' CSV HEADER;
    
  2. Encrypt the export with AES-256 before uploading to cold storage
  3. Upload to EU-based long-term storage with access logging enabled
  4. Verify the archive is readable before considering the export complete
  5. Document the archive in the operations log

Audit Log Integrity

Integrity controls ensure audit logs cannot be retroactively altered:
ControlImplementation
Append-only at application layerNo service code calls UPDATE or DELETE on audit_logs
Row-Level Security (RLS)PostgreSQL RLS policy denies UPDATE and DELETE at the database role level
Immutable snapshotspreviousState and newState stored as JSON blobs — not foreign keys
Cryptographic timestampstimestamp recorded at insert time using $defaultFn(() => new Date()) — cannot be backdated

Operational Log Retention

Application logs (Pino) and error events (Sentry) are operational — they contain technical data useful for incident investigation but not required for long-term compliance. The 90-day retention window is sufficient for post-incident review while limiting unnecessary personal data retention under GDPR.

Sentry Retention

Sentry’s EU data retention policy applies. Events are stored for 90 days by default on standard plans. Sentry logs must not contain PPS numbers, plaintext passwords, or database connection strings — this is enforced by code review and automated security tests.

Cloudflare Log Retention

Cloudflare access logs are available for 30 days via the Cloudflare dashboard. Extended retention is available via Cloudflare Logpush to an external store (e.g., R2, S3). Configure Logpush if WAF investigation history beyond 30 days is required.

GDPR Considerations

Operational logs may contain IP addresses and user agent strings (personal data under GDPR). Retention should be minimised to what is operationally necessary. The 90-day window for application logs and 30-day window for Cloudflare access logs are considered proportionate. Audit logs contain actor IDs and may reference personal data (via previousState/newState). The 7-year retention is justified by the governance obligation under IORP II — this constitutes a legitimate legal basis under GDPR Article 6(1)(c) (compliance with a legal obligation).