Suppression list maintained; unsubscribed users never emailed
Why it matters
CAN-SPAM §5(a)(4), GDPR Art. 21, and CCPA §1798.120 all require that opt-out requests result in permanent cessation of marketing communications. Tracking opt-out status only as a boolean on the user record — rather than in a dedicated suppression table — creates a structural fragility: account reactivation, user import, or a provider migration can silently re-subscribe opted-out addresses. A dedicated suppression table that is append-only and provider-agnostic survives provider changes, list exports, and bulk data operations without losing the opt-out record.
Severity rationale
Info because the gap only causes harm if a specific data operation (provider migration, import, account reactivation) coincides with the missing suppression table — but that event, when it occurs, re-subscribes all opted-out users simultaneously.
Remediation
Maintain a dedicated, append-only email_suppressions table in your primary database and filter every campaign send against it — never rely solely on the provider's suppression list.
-- Append-only suppression table — never delete rows
CREATE TABLE email_suppressions (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
email TEXT NOT NULL,
reason TEXT NOT NULL CHECK (reason IN ('unsubscribe', 'bounce', 'complaint', 'manual')),
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
UNIQUE (email)
);
CREATE INDEX idx_email_suppressions_email ON email_suppressions (email);
// Filter every bulk send against the suppression table
const suppressed = new Set(
(await db.$queryRaw<{ email: string }[]>`SELECT email FROM email_suppressions`)
.map(r => r.email)
)
const eligible = recipients.filter(r => !suppressed.has(r.email))
Sync provider-side bounces and complaints back into this table (via webhook) so suppression is complete regardless of the send path.
DetectionPro
The detection method for this pattern is part of AuditBuffet Pro.
The full method (what to look for, pass and fail conditions, and how results get reported) ships inside the Email & SMS Compliance Audit. The pattern definition, severity rationale, and remediation remain openly licensed under CC-BY-4.0.
External references
- external · CAN-SPAM-§5(a)(4) — CAN-SPAM Act §5(a)(4) — Suppression list must be maintained
- gdpr · Art. 21 — GDPR Art. 21 — Right to object; controller must maintain records of objections
- ccpa · §1798.120 — CCPA §1798.120 — Opt-out records must be maintained
Taxons
History
- 2026-04-18·v1.0.0·Initial import from email-sms-compliance·automated