Custom template permissions

This document outlines the permissions for Web custom templates.


Each permission is:

  • Checked by APIs that require them.
  • Automatically detected in sandboxed JavaScript, based on what APIs are used. This happens as edits are made in the custom template editor (for a fast feedback loop), and when code is compiled (to validate that the correct permissions are enforced).
  • Editable in the custom template editor, to make the permission more specific.
  • Queryable in sandboxed JavaScript via the queryPermission API.

access_globals

Display name: Accesses global variables

Description: Allows access to a global variable (potentially including sensitive APIs).

Configuration: List of keys that can be accessed. Each key is a dot separated path. For example: foo.bar The first token in each path must not be a predefined key on browser global scope, nor a JavaScript keyword. Has read, write, and execute checkboxes that govern access.

Required by: setInWindow, copyFromWindow, callInWindow, createQueue, createArgumentsQueue

Query signature: queryPermission('access_globals', 'read', <key to read from>) or queryPermission('access_globals', 'write', <key to write to>) or queryPermission('access_globals', 'readwrite', <key to read and write>) or queryPermission('access_globals', 'execute', <key of function to execute>)

Notes: Controls whether a custom template can read and/or write to global values.

Example code

const queryPermission = require('queryPermission');
const createQueue = require('createQueue');
if (queryPermission('access_globals', 'readwrite', 'dataLayer')) {
  const dataLayerPush = createQueue('dataLayer');
}

access_local_storage

Display name: Accesses local storage

Description: Allows access to the specified keys in local storage.

Configuration: List of local storage keys that can be accessed. This is a simple array of keys, with no wildcards. Has read and write checkboxes that govern access.

Required by: localStorage

Query signature: queryPermission('access_local_storage', 'read', <key to read from>) or queryPermission('access_local_storage', 'write', <key to write to>) or queryPermission('access_local_storage', 'readwrite', <key to read and write>)

Example code

const queryPermission = require('queryPermission');
const localStorage = require('localStorage');
const key = 'my_key';
if (queryPermission('access_local_storage', 'read', key)) {
  const value = localStorage.getItem(key);
}

access_template_storage

Display name: Accesses template storage

Description: Allows access to temporary storage for templates that can persist for the lifetime of the page.

Configuration: None

Required by: templateStorage

Query signature: queryPermission('access_template_storage')

Example code

const queryPermission = require('queryPermission');
const templateStorage = require('templateStorage');
const key = 'my_key';
if (queryPermission('access_template_storage')) {
  const value = templateStorage.getItem(key);
}

get_cookies

Display name: Reads cookie value(s)

Description: Reads the values of the cookies with the specified name.

Configuration: List of names of cookies permitted for reading.

Required by: getCookieValues

Query signature: queryPermission('get_cookies', <name>)

Notes: Governs whether a cookie can be read, depending on its name.

Example code

const queryPermission = require('queryPermission');
const getCookieValues = require('getCookieValues');
const cookieName = 'info';
let cookieValues;
if (queryPermission('get_cookies', cookieName)) {
  cookieValues = getCookieValues(cookieName);
}

get_referrer

Display name: Reads referrer URL

Description: Permits read access to narrowed portions of the referrer.

Configuration: The following booleans govern which part of the referrer can be read. A given part of the referrer can only be read if the corresponding part is true. The caller can call getReferrerUrl without a component specified to get the full referrer URL if all these booleans are set to true. If no value is set, the default value is all. If a value is set, the value must be an array of components where a component is one of the following: protocol, host, port, path, query, or extension.

queryKeys: If query is selected, then the template author may further limit the set of query keys they can read from. This is a simple array of keys, with no wildcards.

Required by: getReferrerUrl, getReferrerQueryParameters

Query signature: queryPermission('get_referrer', <url_component>)

Example code

const queryPermission = require('queryPermission');
const getReferrerUrl = require('getReferrerUrl');
let referrer;
if (queryPermission('get_referrer', 'query')) {
  referrer = getReferrerUrl('queryParams');
}

get_url

Display name: Reads URL

Description: Returns part or all of the URL of the current page.

Configuration: The following booleans govern which part of the URL can be read. A given part of the URL can only be read if the corresponding part is true. The caller can call getUrl without a component specified to get the entire URL if and only if all these booleans are set to true. If no value is set, the default value is all. If a value is set, the value must be an array of components where a component is one of the following: protocol, host, port, path, query, extension, or fragment.

queryKeys: If query is selected, then the template author may further limit the set of query keys they can read from. This is a simple array of keys, with no wildcards.

Required by: getUrl

Query signature: queryPermission('get_url', <optional url component>, <optional query key>)

If supplied, Url component should be one of 'protocol', 'host', 'port', 'path', 'query', 'extension', 'fragment'. If omitted, the permission query is a request for access to the whole URL.

If supplied, query key should be the query string argument that the template code wants to read.

Notes: Controls whether a custom template can read from the current location. Allows limiting to a specific part of the location.

Example code

const queryPermission = require('queryPermission');
const getUrl = require('getUrl');
if (queryPermission('get_url', 'query', 'gclid')) {
  const gclid = getUrl('query', false, null, 'gclid');
}

inject_hidden_iframe

Display name: Injects hidden iframes

Description: Injects an invisible iframe with a given URL.

Configuration: List of URL patterns

Required by: injectHiddenIframe

Query signature: queryPermission('inject_hidden_iframe', <url>)

Notes: Governs whether a custom template can inject an invisible iFrame, and from which origin it can do so.

Example code

const queryPermission = require('queryPermission');
const injectHiddenIframe = require('injectHiddenIframe');
const url = 'https://www.example.com/iframes';
if (queryPermission('inject_hidden_iframe', url)) {
  injectHiddenIframe(url);
}

inject_script

Display name: Injects scripts

Description: Injects a script into the page.

Configuration: List of URL patterns

Required by: injectScript

Query signature: queryPermission('inject_script', <url>)

Notes: Governs whether a custom template can inject JavaScript, and from what origin it can do so.

Example code

const queryPermission = require('queryPermission');
const injectScript = require('injectScript');
const url = 'https://www.example.com?api.js';
if (queryPermission('inject_script', url)) {
  injectScript(url);
}

logging

Display name: Logs to console

Description: Logs to the developer console and GTM's preview mode.

Configuration: Option to enable logging in production. Defaults to only enable logging in debug/preview. If permission is denied, logToConsole will not throw an error, but will suppress the log message.

Required by: logToConsole

Query signature: queryPermission('logging')

Notes: Controls whether a custom template can log to the developer console.

Example code

const queryPermission = require('queryPermission');
const logToConsole = require('logToConsole');
// Note that it's fine to call log, since the log call will be ignored if
// logging isn't permitted in the current environment.
logToConsole('diagnostic info');

read_data_layer

Display name: Reads data layer

Description: Reads data from the dataLayer.

Configuration: Set of key match expressions, where a key match can be a leading series of dotted references, with a trailing wildcard. Key match expressions govern which properties may be read from the data layer.

Required by: copyFromDataLayer

Query signature: queryPermission('read_data_layer', <data layer key to read from>)

Notes: Controls whether a custom template can read from the data layer.

Example code

const queryPermission = require('queryPermission');
const copyFromDataLayer = require('copyFromDataLayer');
const dlKey = 'foo.bar';
if (queryPermission('read_data_layer', dlKey)) {
  const dlContents = copyFromDataLayer(dlKey);
}

read_character_set

Display name: Reads document character set

Description: Reads document.characterSet.

Configuration: None

Required by: readCharacterSet

Query signature: queryPermission('read_character_set')

Notes: Governs whether a custom template can read document.characterSet.

Example code

const queryPermission = require('queryPermission');
const readCharacterSet = require('readCharacterSet');
if (queryPermission('read_character_set')) {
  const characterSet = readCharacterSet();
}

read_container_data

Display name: Reads container data

Description: Reads data about the container.

Configuration: None

Required by: getContainerVersion

Query signature: queryPermission('read_container_data')

Notes: Controls whether a custom template can read data about the container.

Example code

const queryPermission = require('queryPermission');
const getCookieValues = require('getContainerVersion');
let version;
if (queryPermission('read_container_data')) {
  version = getContainerVersion();
}

read_event_metadata

Display name: Reads event metadata

Description: Reads event metadata in Event Callbacks

Configuration: None

Required by: addEventCallback

Query signature: queryPermission('read_event_metadata')

Notes: Controls whether a custom template can read event metadata in callbacks.

Example code

const queryPermission = require('queryPermission');
const addEventCallback = require('addEventCallback');
if (queryPermission('read_event_metadata')) {
  addEventCallback((containerId, eventMetadata) => {
    // Read event metadata.
  });
}

read_title

Display name: Reads document title

Description: Reads document.title.

Configuration: None

Required by: readTitle

Query signature: queryPermission('read_title')

Notes: Governs whether a custom template can read the document.title.

Example code

const queryPermission = require('queryPermission');
const readTitle = require('readTitle');
if (queryPermission('read_title')) {
  const title = readTitle();
}

send_pixel

Display name: Sends pixels

Description: Sends a GET request to a specified URL. Response is not processed.

Configuration: List of allowed URL patterns.

Required by: sendPixel

Query signature: queryPermission('send_pixel', <url>)

Notes: Governs whether a custom template can send a GET request, and to which origin it can do so.

Example code

const queryPermission = require('queryPermission');
const sendPixel = require('sendPixel');
const url = 'https://www.example.com?foo=3';
if (queryPermission('send_pixel', url)) {
  sendPixel(url);
}

set_cookies

Display name: Sets a cookie

Description: Sets a cookie with the specified name and parameters.

Configuration: A table of allowed cookie names, each with optional restrictions on name, domain, path, secure attribute, and expiration.

Required by: setCookie

Query signature: queryPermission('set_cookies', <name>, <options>)

Notes: Governs whether a cookie can be written, depending on the cookie name, domain, path, secure attribute, and expiration.

Example code

const queryPermission = require('queryPermission');
const setCookie = require('setCookie');
const options = {
  'domain': 'www.example.com',
  'path': '/',
  'max-age': 60*60*24*365,
  'secure': true
};
if (queryPermission('set_cookies', 'info', options)) {
  setCookie('info', 'xyz', options);
}

write_data_layer

Display name: Writes data layer

Description: Writes data to the dataLayer.

Configuration: Set of key match expressions, where a key match can be a leading series of dotted references, with a trailing wildcard. Key match expressions govern which properties may write to the data layer.

Required by: gtagSet

Query signature: queryPermission('write_data_layer', <data layer key to write from>)

Notes: Controls whether a custom template can write to the data layer.

Example code

const queryPermission = require('queryPermission');
const gtagSet = require('gtagSet');
const dlKey = 'foo.bar';
if (queryPermission('write_data_layer', dlKey)) {
  gtagSet({dlKey: 'baz'});
}