# GTM consent settings

Where consent state enters a Google Tag Manager web container, how each tag's consent setting changes what it does, and how to audit those settings from an export or the API. Checked against Google's Tag Manager help and developer pages on 2026-10-17.

## Where the default and update come from

- Consent Initialization trigger:
  - Every web container has a "Consent Initialization - All Pages" trigger.
  - Google's Tag Manager help says this trigger runs before every other trigger, including Initialization ([consent help page](https://support.google.com/tagmanager/answer/10718549)).
  - Only the CMP tag and tags that set defaults belong on it. Any vendor tag on this trigger runs before consent exists.
- Consent template APIs:
  - A consent template should use `setDefaultConsentState` and `updateConsentState`.
  - `gtagSet` can set `url_passthrough`, `ads_data_redaction` and `developer_id`.
  - `wait_for_update` is in milliseconds. Google's sample template uses 500 and suggests at least 500 when the template does asynchronous work.
- `gtag('consent', ...)` from Custom HTML:
  - Google: gtag commands "are queued after all other pending messages and may not be processed before the next event begins".
  - Google says not to create templates that use the `gtag consent` command, and not to use `gtag('consent','update',...)` in place of `updateConsentState`.
  - Google's fallback when a template is not possible is on-page `gtag` code that runs before the container loads. A Custom HTML consent tag is not a documented pattern; record it as a timing finding even when the values are right.
- Defaults outside the container (Google tag settings):
  - These live in the Google tag's settings, reached from Google Analytics (Admin, Data streams, select the stream), from Google Ads (Tools, Data manager, Google tag, Manage) or from the Google tag in GTM. Select "Show all".
  - "Set consent mode override" overrides any default in the website code and sets denied for the regions chosen. It applies only to the tag it is configured on, and requires "Manage default consent settings" to be set to "No".
  - "Manage default consent settings" set to "Yes" labels all data sent to Google as consented. It is meant only for sites whose tags never load before consent.
  - Neither setting appears in a container export. Check them in the UI and list them as consent writers.

## Tag consent settings

Tag editor, Advanced Settings, Consent Settings, "Additional Consent Checks":

- "Not set": the default; the tag performs no additional consent checks.
- "No additional consent required": a reviewed tag that needs no extra consent.
- "Require additional consent for tag to fire": the tag fires only if every listed consent type is granted when the trigger evaluates.

Built-in consent checks: Google Ads, Google Analytics and Floodlight tags change their own behaviour with consent state (Cookiebot's guide adds the Conversion Linker). Most non-Google tags do not, whatever their template name says. Exceptions: a gallery template can read consent through `isConsentGranted` or `addConsentListener`, and Microsoft UET reads Google's consent state itself unless `enableAutoConsent: false` is set. Read each template's code or permissions before assuming either way.

Consent Overview: Admin, Container Settings, Additional Settings, "Enable consent overview". The Tags list then offers a consent overview that groups tags under "Consent Not Configured" (still "Not set") and "Consent Configured".

## Decision rules per mode

- Advanced mode for Google tags:
  - Google tags stay "Not set" or "No additional consent required" and carry no consent exception (blocking) triggers.
  - Google's "Unblock Google tags when using consent mode" help page warns that stacking additional consent checks on Google tags that already use consent mode stops them working properly, and tells you to set those tags to "Not set" or "No additional consent required".
  - A Google tag with "Require additional consent" or a consent blocking trigger makes that tag basic. It is a finding unless the specification asks for it.
- Basic mode for Google tags:
  - Google tags must be blocked until consent, through "Require additional consent" or a blocking trigger.
  - Because they are blocked at page load, they need a trigger that runs after the choice (see below), or the first page is lost.
  - Cookiebot's guide recommends this for anyone who does not want data sent before consent. Google's guide recommends the opposite for modelling. The specification decides; record which.
- Non-Google tags in any mode:
  - "Require additional consent" with the right types, or a blocking trigger that encodes the category.
  - "Not set" on a non-Google vendor tag means no consent control. If it sends in an opt-in region before a choice, that is S1.
  - "No additional consent required" on an advertising or analytics pixel: grade S3 when the pixel sends nothing in any tested opt-in case (another control holds it), and S1 when it sends. This matches gtm-container-audit, which grades the setting FAIL on an ad or analytics pixel; a documented exception in the specification is the only way to clear it.

## Triggers after a choice

- Cookiebot's GTM guide says a consent update does not re-run tags whose All Pages trigger has already been evaluated. A blocked tag left on All Pages never fires on the page where the visitor accepts.
- The CMP's own event is the replacement trigger:
  - Cookiebot: a Custom Event trigger on `cookie_consent_update`. It fires once the choice is known, from a previous visit or from the banner, so it replaces All Pages rather than sitting beside it.
  - OneTrust: a Custom Event trigger on `OneTrustGroupsUpdated` with the condition `OnetrustActiveGroups` matches RegEx `,C0002,` (your own category ID). It fires on page load and again on every consent change.
- Duplicates to test for:
  - A tag on both All Pages and the CMP event fires twice for returning visitors.
  - A tag on `OneTrustGroupsUpdated` fires again when the visitor changes the choice on the same page. Initialisation tags should fire once per page (API value `oncePerLoad`) or carry a condition.
- Business events never ride on a consent trigger. A purchase or lead tag fires on the business event only. If the event happened before consent, the specification decides whether it is dropped; GTM does not replay it, and adding a consent trigger to it invents conversions.
- Wildcard triggers: since Google's 8 October 2026 release, `gtag('config')` commands surface in the dataLayer as visible `gtag.config` events and may fire tags on wildcard custom event triggers. Any consent or vendor tag on a wildcard custom event trigger can now fire on `gtag.config` as well; check the Tags fired list for that event.

## Auditing from an export or the API

Tag Manager API v2 Tag resource fields (checked 2026-10-17):

- `consentSettings.consentStatus`: `notSet`, `notNeeded` or `needed`.
- `consentSettings.consentType`: the consent types checked when the status is `needed`.
- `blockingTriggerId`: if any listed trigger is true, the tag does not fire.
- `firingTriggerId`: the tag fires when any listed trigger is true.
- `tagFiringOption`: `unlimited`, `oncePerEvent` or `oncePerLoad`.

Checks to run on every tag:

- Vendor (non-Google) tags: `consentStatus` is `needed` with the right types, or a blocking trigger encodes the category.
- Google tags: consistent with the mode decision above.
- Tags on Consent Initialization: only the CMP and default tags.
- Tags blocked until consent: at least one firing trigger runs after the choice.
- After any API bulk edit or clone: `consentSettings` and `blockingTriggerId` are tag-level fields, separate from `parameter`. A create or clone that copies only the parameters silently drops the consent gate. Read every written tag back.

Tooling:

- A container export (JSON) or Tag Manager API read calls are enough for the audit.
- Google ships no official Tag Manager MCP server. Prefer a container export, or the Tag Manager API with the `tagmanager.readonly` scope, which cannot write.
- Stape's open-source GTM MCP server has no separate read tools. Each tool covers reads and writes through an `action` parameter: `gtm_tag` takes create, get, list, update, remove and revert; `gtm_version` can publish; `gtm_container` can remove and combine containers; `gtm_user_permission` changes access; `gtm_workspace` can createVersion, sync, quickPreview and bulkUpdate. A tool-name allowlist therefore cannot make it read-only.
  - If it is used at all, only the actions `get`, `list`, `live`, `latest` and `getStatus` are allowed (for example `gtm_tag` list and get, `gtm_version_header` list and latest).
  - Never use create, update, remove, revert, publish, setLatest, undelete, combine, createVersion, sync, quickPreview, bulkUpdate, resolveConflict, importFromGallery or any `gtm_user_permission` write.
- The gtm-container-audit skill covers the rest of the container. If it is not installed, run the tag checks above on the export and list the rest of the container as not covered in the write-up.
