# Application honors Global Privacy Control (GPC) browser signal

- **Pattern:** `ab-000629` (`ccpa-readiness.opt-out.global-privacy-control`)
- **Severity:** high
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-000629
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-000629)

## Why it matters

The California Attorney General's 2022 enforcement guidance confirmed that businesses must treat the Global Privacy Control (GPC) signal as a valid opt-out of sale and sharing under CCPA § 1798.120. GPC is a browser-level HTTP header (`Sec-GPC: 1`) and JavaScript property (`navigator.globalPrivacyControl`) sent automatically by Brave, Firefox with privacy settings, and the Privacy Badger extension. If your middleware doesn't read this header before any third-party pixels initialize, you are sharing PI with advertising platforms before the consumer's opt-out signal is honored — a per-page-load violation. Unlike a manual opt-out form, GPC arrives on every qualifying request without any user action on your site.

## Severity rationale

High because GPC is a legally mandated opt-out signal under CCPA § 1798.120 — failing to honor it has the same legal weight as ignoring a manually submitted opt-out form, and it affects all GPC-enabled browsers automatically.

## Remediation

Implement GPC detection in `middleware.ts` so the opt-out cookie is set before any client JavaScript runs, then gate all pixel initialization on the combined preference check.

```ts
// middleware.ts — intercept GPC before client-side code loads
import { NextRequest, NextResponse } from 'next/server'

export function middleware(req: NextRequest) {
  const gpc = req.headers.get('Sec-GPC')
  const response = NextResponse.next()
  if (gpc === '1') {
    response.cookies.set('ccpa_opt_out', '1', {
      path: '/', maxAge: 60 * 60 * 24 * 365, sameSite: 'lax',
    })
  }
  return response
}

// lib/analytics.ts — combined GPC + cookie check
function isOptedOut(): boolean {
  if (typeof navigator !== 'undefined' && navigator.globalPrivacyControl === true) return true
  if (typeof document !== 'undefined') return document.cookie.includes('ccpa_opt_out=1')
  return false
}

export function initializeThirdPartyPixels() {
  if (isOptedOut()) return
  loadFacebookPixel()
  loadGoogleAdsRemarketing()
}
```

Add to your privacy policy: "We honor the Global Privacy Control (GPC) signal. A GPC-enabled browser is automatically treated as an opt-out of sale or sharing." This disclosure is required by CPRA regulations.

## Detection

- **ID:** `global-privacy-control`
- **Severity:** `high`
- **What to look for:** The California Attorney General has confirmed that businesses subject to CCPA must honor the Global Privacy Control (GPC) signal as a valid opt-out of sale/sharing. Search the codebase for handling of `navigator.globalPrivacyControl` (client-side) and the `Sec-GPC: 1` HTTP header (server-side, sent by GPC-enabled browsers). In Next.js, Nuxt, or SvelteKit, check middleware files for Sec-GPC header reading. Look for any logic that automatically sets the user's opt-out preference when GPC is detected. Check whether the GPC detection runs before any third-party pixels or sharing behavior is triggered. Verify that GPC-based opt-outs are treated as equivalent to a user-submitted opt-out — they should persist for the session and, if the user can be identified, be stored server-side. Count every third-party sharing pathway (advertising pixels, server-side API calls, analytics identify calls) and enumerate which are gated on GPC vs. which fire unconditionally.
- **Pass criteria:** The application detects the GPC signal (client-side `navigator.globalPrivacyControl === true` or server-side `Sec-GPC: 1` header) and automatically treats the consumer as having opted out of sale/sharing. Third-party advertising pixels and data sharing are suppressed when GPC is active. The privacy policy discloses that GPC is honored. At least 1 implementation must be confirmed.
- **Fail criteria:** No GPC signal detection found anywhere in the codebase. GPC check exists but does not actually gate third-party sharing. GPC check only runs after third-party pixels have already initialized. Do NOT pass if GPC detection exists but runs after third-party pixels have already initialized on the same page load.
- **Skip (N/A) when:** Application does not sell or share personal information with any third parties (including for cross-context behavioral advertising) — no pixels, no behavioral ad targeting, no data broker sharing.
- **Detail on fail:** Example: `"No GPC signal handling found. No check for navigator.globalPrivacyControl or Sec-GPC header in any middleware, layout, or analytics initialization code."` or `"GPC check found in lib/analytics.ts but executes after Facebook Pixel has already initialized on the same page load."`.
- **Remediation:** Implement GPC detection in middleware and analytics initialization:

  ```ts
  // middleware.ts (Next.js) — server-side GPC detection
  import { NextRequest, NextResponse } from 'next/server'

  export function middleware(req: NextRequest) {
    const gpc = req.headers.get('Sec-GPC')
    const response = NextResponse.next()

    if (gpc === '1') {
      // Signal opt-out to client via cookie
      response.cookies.set('ccpa_opt_out', '1', {
        path: '/',
        maxAge: 60 * 60 * 24 * 365, // 1 year
        sameSite: 'lax',
      })
    }

    return response
  }

  // lib/analytics.ts — client-side GPC check before loading any pixels
  function isOptedOut(): boolean {
    // Check GPC signal first (browser signal takes precedence)
    if (typeof navigator !== 'undefined' && navigator.globalPrivacyControl === true) {
      return true
    }
    // Then check stored preference
    if (typeof document !== 'undefined') {
      return document.cookie.includes('ccpa_opt_out=1')
    }
    return false
  }

  export function initializeThirdPartyPixels() {
    if (isOptedOut()) {
      console.debug('[ccpa] Opt-out active — third-party sharing suppressed')
      return
    }
    loadFacebookPixel()
    loadGoogleAdsRemarketing()
    // etc.
  }
  ```

  Add to your privacy policy: "We honor the Global Privacy Control (GPC) signal. If your browser sends a GPC signal, we will treat it as a request to opt out of the sale or sharing of your personal information."

---

## External references

- ccpa §1798.120
- external GPC-Spec-1.0 — https://globalprivacycontrol.github.io/gpc-spec/
- eprivacy Art. 5(3)

Taxons: privacy-consent, regulatory-conformance

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