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
| Category | Source | Sensitivity | Retention |
|---|
| Audit logs | audit_logs table (PostgreSQL) | High — governance record | 7 years minimum |
| Application logs | Pino → Vercel log drain | Medium — operational | 90 days |
| Error events | Sentry | Medium — operational | 90 days (Sentry default) |
| Access logs | Cloudflare | Low–Medium | 30 days (Cloudflare default) |
| Deployment logs | Vercel | Low | 60 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:
- No deletion policy — no
DELETE operation is permitted on the audit_logs table at any role level
- Neon PITR — point-in-time restore retains data within the backup window (7–30 days)
- 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
- 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;
- Encrypt the export with AES-256 before uploading to cold storage
- Upload to EU-based long-term storage with access logging enabled
- Verify the archive is readable before considering the export complete
- Document the archive in the operations log
Audit Log Integrity
Integrity controls ensure audit logs cannot be retroactively altered:
| Control | Implementation |
|---|
| Append-only at application layer | No 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 snapshots | previousState and newState stored as JSON blobs — not foreign keys |
| Cryptographic timestamps | timestamp 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).