GDPR and Your Nginx Logs — What PII Are You Accidentally Logging?
Most developers know GDPR applies to their databases and forms. Few realise their nginx access logs may already be GDPR non-compliant — logging personal data without consent, no retention policy, no protection.
Here is what your default nginx log line looks like:
185.22.30.11 - - [26/Mar/2026:08:20:00 +0000] "GET /reset-password?token=abc123&email=john.doe@example.com HTTP/1.1" 200 512
You just logged an email address. That is personal data under GDPR Article 4. And it is sitting in a plaintext file on your server.
What PII Ends Up in Nginx Logs?
1. Email addresses in query parameters
Password resets, magic links, email verification — all commonly pass email as a URL parameter:
GET /verify?email=user@example.com&token=xyz
GET /unsubscribe?email=user@example.com
GET /invite?ref=user@example.com
2. Names and usernames in URLs
GET /profile/john.doe
GET /u/jane_smith/settings
GET /invoices/acme-corp-march-2024
3. Session tokens and auth tokens
GET /api/data?session=eyJhbGciOiJSUzI1NiJ9...
GET /download?token=sk_live_abc123
4. IP addresses
Under GDPR, IP addresses are considered personal data in most EU member states (CJEU ruling, 2016). Your nginx access log logs every IP by default.
5. Health and sensitive data in URLs
GET /doctors/oncology/book?patient=john-doe
GET /therapy/session?user_id=4421
Health-related data is special category data under GDPR Article 9 — even stricter rules apply.
Why This Matters
- Log retention: GDPR requires data minimisation. Keeping access logs for 90 days "just in case" may not have a lawful basis.
- Log access: Who can read your access logs? If it is everyone on your team, you may be over-sharing personal data.
- Log storage: Are logs encrypted at rest? GDPR Article 32 requires appropriate technical measures.
- Breach notification: If your log files are exfiltrated, that is a personal data breach requiring notification within 72 hours.
What You Can Do
Option 1: Strip PII from log format
map $remote_addr $remote_addr_masked {
~^(\d+\.\d+\.\d+)\. $1.0;
default $remote_addr;
}
log_format gdpr_safe '$remote_addr_masked - $remote_user [$time_local] '
'"$request_method $uri $server_protocol" '
'$status $body_bytes_sent';
Option 2: Exclude sensitive URL patterns
map $request_uri $log_it {
~*email= 0;
~*token= 0;
default 1;
}
access_log /var/log/nginx/access.log combined if=$log_it;
Option 3: Redact PII from existing logs
#!/bin/bash
# Run daily via cron
LOG=/var/log/nginx/access.log.1
sed -i -E 's/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/[REDACTED]/g' $LOG
Option 4: Set a log retention policy
/var/log/nginx/*.log {
daily
rotate 30
compress
missingok
notifempty
}
Building a GDPR-Ready Log Pipeline
The goal is privacy by design (GDPR Article 25):
- Collect only what you need — strip PII at ingestion
- Retain only as long as needed — 30-day rotation as default
- Encrypt logs at rest
- Restrict access to log files
- Scan regularly for PII that slips through
Quick Checklist
- [ ] Review nginx log format for PII fields
- [ ] Check if query parameters contain emails or tokens
- [ ] Set log rotation to 30 days max
- [ ] Encrypt log storage
- [ ] Document lawful basis for log retention in your DPIA
- [ ] Set up automated PII scanning
GDPR compliance is not just about your database. Your logs are data too. Tools like LogAudit scan nginx logs automatically for PII exposure, API key leaks, and compliance issues — so you catch problems before your next audit.
Top comments (0)