Global Privacy Control (GPC) implementer reference

last verified · against GPC W3C spec, MDN, and CCPA regs as of 2026-07

Global Privacy Control on one card: the Sec-GPC header, navigator.globalPrivacyControl, /.well-known/gpc.json, CCPA opt-out rules, and Google RDP behavior.

What this is

Global Privacy Control (GPC) is a signal by which a user notifies a business that it should not sell or share their personal data, exposed as an HTTP request header (Sec-GPC) and a matching DOM boolean (navigator.globalPrivacyControl). This card lists both surfaces, the exact values that count, the well-known discovery file, the US-state legal footing, and how a Google advertising stack responds.

The two signal surfaces

Surface Where it lives Type Value that means opt-out
Sec-GPC HTTP request header Browser-set, forbidden header name (Sec- prefix) Field-value exactly 1
navigator.globalPrivacyControl DOM, on Navigator and WorkerNavigator Read-only boolean true
/.well-known/gpc.json Origin well-known resource application/json gpc: true (site’s own intent, not the user’s signal)

The header and the JS boolean are two views of one state: navigator.globalPrivacyControl equals the top-level browsing context’s gpcAtNavigation, i.e. it reflects whether a Sec-GPC: 1 header would be sent. The .well-known file is the server’s published intent, a separate thing from an incoming user signal.

How to read each value

Observed Interpretation Source
Sec-GPC: 1 Opt-out of sale/share W3C GPC spec
Header absent No opt-out signal (there is no Sec-GPC: 0) W3C GPC spec
Any other Sec-GPC value Server MUST ignore it and process as if absent W3C GPC spec
navigator.globalPrivacyControl === true User explicitly does not consent to sell/share MDN
navigator.globalPrivacyControl === false Consent or no preference — ambiguous MDN
navigator.globalPrivacyControl === undefined Browser does not implement GPC MDN / gotcha

Rule of thumb: false and undefined never mean affirmative consent. Treat GPC as a one-way override — presence forces the do-not-sell/share state, absence leaves whatever consent the user set in your CMP untouched.

Header ABNF and the property WebIDL

sec-gpc.abnf
Sec-GPC-field-name = "Sec-GPC"
Sec-GPC-field-value = "1"

A user agent MUST send Sec-GPC: 1 when gpcAtNavigation is true, and MUST NOT send the header at all when it is false. A server MUST honor the header only when the field-value is exactly the character 1.

global-privacy-control.idl
interface mixin GlobalPrivacyControl {
readonly attribute boolean globalPrivacyControl;
};
Navigator includes GlobalPrivacyControl;
WorkerNavigator includes GlobalPrivacyControl;

Because the mixin is on WorkerNavigator too, the property is also readable inside Web Workers via WorkerNavigator.globalPrivacyControl.

The /.well-known/gpc.json resource

Served at exactly /.well-known/gpc.json relative to the origin, as application/json. Two members:

Member Type Required Meaning
gpc Boolean Yes true = the server intends to abide by GPC at least to the extent legally obligated
lastUpdate String, RFC3339 (YYYY-MM-DD or datetime) No If absent or not valid RFC3339, the last-update time is treated as “unknown”
gpc.json
{ "gpc": true, "lastUpdate": "2025-04-15" }

Publishing this file is a machine-readable claim of intent used by auditors and privacy tools; it is not a substitute for actually honoring the signal.

The GPC spec deliberately does not define the signal’s legal meaning: sending or receipt “may have legal effects, depending on factors such as the location of the individual sending the signal, the scope of the applicable law,” and GPC “is not necessarily intended to invoke every new privacy right in every jurisdiction.” Legal effect is jurisdiction-dependent. The rows below are facts attributed to their sources, not universal claims.

Statement Attribution
A user-enabled GPC is a legally valid CCPA request to opt out of the sale of data; under GDPR it conveys a general request to limit sale/sharing to other controllers globalprivacycontrol.org
Businesses must treat a GPC opt-out the same as a click on the “Do Not Sell My Personal Information” link California AG (Sephora settlement statement)
Sephora settled for $1.2M for failing to process opt-outs sent via user-enabled global privacy controls, in violation of the CCPA California AG press release, Aug 24 2022

US-state recognition (per GPC FAQ, as of Jan 15 2025)

Jurisdiction Status
California, Colorado, Connecticut, New Jersey Explicitly recognize GPC
~8 further states Entitle consumers to opt out via universal opt-out mechanisms

Treat the count as time-stamped; the list changes as new state laws take effect. Re-verify before quoting.

California 11 CCR § 7025 (opt-out preference signals)

Subsection numbers read via the Cornell LII mirror; the regulation does not name GPC by name. Confirm subsection numbering against the official CCPA text on cppa.ca.gov before citing verbatim.

Subsection Rule
§ 7025(b)(1) Signal must be in a format commonly used and recognized by businesses; example given is “an HTTP header field or JavaScript object”
§ 7025(c)(1) Business shall treat a compliant signal as a valid request to opt out of sale/sharing
§ 7025(c)(6) Business may display “Opt-Out Preference Signal Honored” when such a browser/device visits
§ 7025(f) Frictionless: no fee/consideration, no change to the consumer experience, and no notification/pop-up/text/graphic/animation/sound/video/interstitial in response to the signal

Posting a “Do Not Sell or Share” link does not let a business choose the link instead of honoring the signal — it only permits processing the signal in a non-frictionless manner.

Native browser support (per GPC FAQ)

Browser GPC behavior
Brave Sends by default
DuckDuckGo Sends by default
Firefox Available in settings (opt-in)
Chrome, Safari, Edge Extension only

The Chrome/Safari/Edge “extension only” row is inferred from the absence of native support in the FAQ rather than an affirmative per-browser statement; verify against a live compatibility table (MDN/caniuse) before quoting.

Google advertising stack behavior

Mechanism Behavior (per Google Ads Help)
Google in applicable US states Receives GPC directly; turns off ads targeting and activates Restricted Data Processing (RDP) for those ad requests
IAB GPP strings Google honors GPC sub-section signals inside GPP and activates RDP
GPP jurisdictions supported US-National, California, Virginia, Colorado, Connecticut, Florida
Other publisher opt-out inputs Google’s RDP parameter, or the IAB us_privacy string
First-party Consent Mode Not automatic — GPC does not flow into vendor tags; you must translate it yourself

Google frames GPC/RDP around advertising products. Whether GPC-driven RDP applies to GA4 specifically (versus only Ads/Ad Manager ad requests) was not confirmable from a single official GA4 page; Google places GA4 compliance responsibility on the customer.

Gotchas

  1. Almost no test traffic sends GPC. Cause: most mainstream browsers do not send it natively — only Brave and DuckDuckGo default-on, Firefox behind a setting; default Chrome shows navigator.globalPrivacyControl === undefined. Fix: test in Brave or DuckDuckGo, or install a GPC extension; treat undefined and false identically as “no opt-out”.
  2. A === false check misclassifies unsupported browsers. Cause: the property is undefined (not false) where GPC is unimplemented, and false itself means consent or no preference. Fix: detect only the positive case, navigator.globalPrivacyControl === true; never infer consent from false/undefined.
  3. Setting or spoofing Sec-GPC from client JS fails. Cause: it is a Sec-prefixed forbidden request header, set by the browser and unwritable by page scripts. Fix: read it server-side from the request and read the boolean client-side; do not forge it, and do not trust a proxied value unless your own edge added it.
  4. Server honors any non-empty Sec-GPC, or looks for Sec-GPC: 0 / true. Cause: the spec allows exactly one field-value, 1; servers MUST ignore otherwise, and the header is absent (not 0) when off. Fix: check value === '1' exactly; absence = no signal.
  5. A posted “Do Not Sell or Share” link is treated as an excuse to ignore browser signals. Cause: under § 7025 the link does not exempt you — compliant signals must be processed as valid opt-outs; the link only permits non-frictionless processing. Fix: detect GPC and apply do-not-sell/share regardless — this exact gap produced the $1.2M Sephora settlement.
  6. On detecting GPC the site shows a banner or confirmation pop-up “to be safe”. Cause: § 7025(f) prohibits any notification, pop-up, text, graphic, animation, sound, video, or interstitial in response to the signal. Fix: apply the opt-out silently; the only permitted UI is an unobtrusive “Opt-Out Preference Signal Honored” (§ 7025(c)(6)).
  7. GPC is detected but Google tags still behave as consented. Cause: GPC does not auto-flow into vendor tags; Google triggers RDP directly only for applicable-US-state users (and via GPP sub-sections). Fix: in your CMP, map a detected GPC to the do-not-sell/share state and set the appropriate gtag('consent','update', ...) and/or us_privacy/GPP opt-out; verify in Tag Assistant.
  8. gpc.json returns 404 or the wrong content type; verifiers report non-compliant. Cause: the resource must be at exactly /.well-known/gpc.json, served application/json, with gpc: true; a typo’d path, HTML 404, or missing Content-Type breaks discovery. Fix: serve it as application/json; lastUpdate is optional but should be valid RFC3339. Publishing is a claim of intent, not proof of honoring.

Quick recipes

gpc-edge.js
// At the edge / origin the Sec-GPC request header is authoritative and
// available before any page JS runs. Only the exact value "1" is an opt-out.
export default {
fetch(request) {
const optOut = request.headers.get('Sec-GPC') === '1';
// optOut === true -> set a first-party do-not-sell flag on this request
// header absent / other -> no opt-out signal (there is no "Sec-GPC: 0")
return new Response(optOut ? 'opt-out' : 'no-signal');
}
};
gpc-detect.js
// Client-side: detect ONLY the positive case. false and undefined are not consent.
const optOut = navigator.globalPrivacyControl === true;
// true -> user explicitly refuses sale/share
// false -> consent OR no preference (ambiguous — do not treat as consent)
// undefined -> browser does not implement GPC
.well-known/gpc.json
{
"gpc": true,
"lastUpdate": "2025-04-15"
}
gpc-to-consent-mode.js
// IMPLEMENTATION GUIDANCE, not a verbatim Google mapping table.
// Translate a detected GPC into denied advertising signals so downstream
// Google tags see the opt-out. Verify the result in Tag Assistant.
if (navigator.globalPrivacyControl === true) {
gtag('consent', 'update', {
ad_storage: 'denied',
ad_user_data: 'denied',
ad_personalization: 'denied'
});
}
gpc-worker.js
// The property is available inside a Web Worker via WorkerNavigator.
self.onmessage = () => {
const optOut = navigator.globalPrivacyControl === true;
postMessage({ optOut });
};

Sources

Official pages these values were read from (read 2026-07-20):

Honesty notes. The GPC spec deliberately does not define the signal’s legal meaning, so “GPC = a legally binding opt-out” holds only within specific state regimes (notably California), not universally. Native support for Chrome/Safari/Edge (extension-only) is inferred from the FAQ’s silence, not an affirmative per-browser statement. The four-plus-eight US-state count is time-stamped to the FAQ as of Jan 15 2025 and drifts as laws take effect. The GPC-to-Consent-Mode mapping in the recipes is engineering guidance synthesized from Google’s RDP behavior, not a verbatim Google mapping table, and whether RDP applies to GA4 specifically was not confirmable. The § 7025 subsection numbers were read via the Cornell LII mirror; confirm against cppa.ca.gov before citing verbatim.

Changelog

  • — Initial version, verified against official documentation.

dataLayer

0 events · 0 sent

    • home /
      writing /writing
      guides /guides
      work /#work
      about /about
      colophon /colophon
      toggle analyst mode ctrl+.
      print session receipt /#receipt