# Separate consent per channel (email, SMS, push)

- **Pattern:** `ab-001251` (`email-sms-compliance.consent.separate-consent-per-channel`)
- **Severity:** low
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-001251
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-001251)

## Why it matters

GDPR Art. 7 requires consent to be 'specific' — consent for email marketing does not cover SMS marketing, and a single `marketingOptIn` boolean that authorizes all channels conflates legally distinct consent decisions. TCPA §227(b)(1)(A) requires 'prior express written consent' specifically for SMS, which is a higher bar than CAN-SPAM email consent. ePrivacy Art. 13 applies channel by channel. Practically: a user who opts into email newsletters may not want SMS promotions — collapsing both into one flag generates TCPA exposure on every marketing SMS sent to users who only checked the email box.

## Severity rationale

Low because the violation requires both email and SMS marketing to be active simultaneously, but when it is, every marketing SMS sent without separate SMS consent is an independent TCPA violation.

## Remediation

Add per-channel consent columns to the database and expose per-channel controls in the notification preferences UI.

```sql
-- Per-channel consent columns (default false per GDPR)
ALTER TABLE users ADD COLUMN email_marketing_opt_in BOOLEAN NOT NULL DEFAULT false;
ALTER TABLE users ADD COLUMN sms_marketing_opt_in   BOOLEAN NOT NULL DEFAULT false;
ALTER TABLE users ADD COLUMN push_marketing_opt_in  BOOLEAN NOT NULL DEFAULT false;
```

```tsx
// Notification preferences — granular per channel
<form>
  <label><input type="checkbox" name="emailMarketing" /> Email updates and newsletters</label>
  <label><input type="checkbox" name="smsMarketing" /> SMS promotions (msg & data rates may apply; reply STOP to opt out)</label>
  <label><input type="checkbox" name="pushMarketing" /> In-app promotional notifications</label>
</form>
```

Every outbound SMS send must check `sms_marketing_opt_in`, not the shared `marketingOptIn` column.

## Detection

- **ID:** `separate-consent-per-channel`
- **Severity:** `low`
- **What to look for:** Enumerate every relevant item. Consent for one channel does not imply consent for another. Opting into marketing email does not constitute consent for marketing SMS — this is both a GDPR requirement (granular, specific consent) and a TCPA requirement (specific prior express written consent for SMS). Check signup forms and notification preference pages: is there a single "I want to receive marketing" checkbox, or separate checkboxes per channel? Check the database schema: is there a single `marketingOptIn` boolean, or separate fields for `emailMarketingOptIn`, `smsMarketingOptIn`, `pushMarketingOptIn`? Check notification preference pages for channel granularity.
- **Pass criteria:** At least 1 of the following conditions is met. Consent is tracked and obtained separately for each marketing channel. A user who opts into email marketing has not automatically consented to SMS marketing (or push notifications). The database schema reflects per-channel opt-in status. Notification preferences UI allows per-channel control.
- **Fail criteria:** A single `marketingOptIn` flag covers all channels. Email opt-in at signup is used as authorization for sending marketing SMS. No per-channel granularity in consent storage or UI.
- **Skip (N/A) when:** Application uses only one marketing channel (e.g., only email, no SMS or push).
- **Detail on fail:** Example: `"Single marketingOptIn boolean in users table used to authorize both email and SMS marketing sends. No separate SMS consent captured."` or `"Notification preferences page has email toggle but no separate SMS or push toggle — all channels share one setting."`.
- **Remediation:** Add per-channel consent fields and separate UI controls:

  ```sql
  -- Add per-channel consent columns to your subscribers/users table
  ALTER TABLE users ADD COLUMN email_marketing_opt_in BOOLEAN NOT NULL DEFAULT false;
  ALTER TABLE users ADD COLUMN sms_marketing_opt_in   BOOLEAN NOT NULL DEFAULT false;
  ALTER TABLE users ADD COLUMN push_marketing_opt_in  BOOLEAN NOT NULL DEFAULT false;
  ```

  ```tsx
  // Notification preferences page — per-channel controls
  export function NotificationPreferences() {
    return (
      <form>
        <h3>Marketing preferences</h3>
        <label>
          <input type="checkbox" name="emailMarketing" />
          Email — product updates, offers, and newsletters
        </label>
        <label>
          <input type="checkbox" name="smsMarketing" />
          SMS — promotional text messages (message & data rates may apply; reply STOP to opt out)
        </label>
        <label>
          <input type="checkbox" name="pushMarketing" />
          Push notifications — in-app promotional messages
        </label>
        <button type="submit">Save preferences</button>
      </form>
    )
  }
  ```

---

## External references

- gdpr Art. 7
- external TCPA-§227(b)(1)(A) — https://www.fcc.gov/consumers/guides/stop-unwanted-robocalls-and-texts
- eprivacy Art. 13

Taxons: privacy-consent, regulatory-conformance

HTML version: https://auditbuffet.com/patterns/ab-001251
