Delegate audience management to a third-party

Learn how to control audience management by using a Permissions Policy or delegate to a third party by configuring a .well-known permissions URL.

The origin of the calling context for joinAdInterestGroup() must match the interest group owner's origin, so joinAdInterestGroup() will need to be called from an iframe (for example, from a DSP) unless the origin of the interest group owner matches the origin of the current document (for example, a website with its own interest groups).

joinAdInterestGroup() requires permission from:

This means it's not possible for malicious.example to call joinAdInterestGroup() for an interest group owned by, without granting permission.

Permission from the visited site

Permission can be granted from the same origin or cross-origin.

By default, permission is granted for joinAdInterestGroup() calls from the same origin as the site visited, (in other words, from the same origin as the top-level frame of the current page). Sites can use the join-ad-interest-group permissions policy header to disable joinAdInterestGroup() calls.

Calling joinAdInterestGroup() cross-origin (origins that are different from the current page) can only succeed if the site being visited has set a permissions policy that allows calls to joinAdInterestGroup() from cross-origin iframes.

Permission from the interest group owner

Interest group owner permission is implicitly granted by calling joinAdInterestGroup() from an iframe with the same origin as that of the interest group's owner. For example, a iframe can call joinAdInterestGroup() for interest groups owned by

In essence, joinAdInterestGroup() can run in a page or iframe on the owner's domain, or be delegated to other domains provided using a list at a .well-known URL.

When a frame navigated to one domain calls joinAdInterestGroup(), leaveAdInterestGroup(), or clearOriginJoinedAdInterestGroups() for an interest group with a different owner, the browser will fetch the URL https://owner.domain/.well-known/interest-group/permissions/?origin=frame.origin, where owner.domain is the domain that owns the interest group and frame.origin is the origin of the frame. The fetch uses the omit credentials mode, using the Network Partition Key of the frame that invoked the method. To avoid leaking cross-origin data through the returned Promise unexpectedly, the fetch uses the cors mode. The fetched response should have a JSON MIME type and be of the format:

{ "joinAdInterestGroup": true/false,
  "leaveAdInterestGroup": true/false

Indicating whether the origin in the path has permissions to join or leave interest groups owned by the domain the request is sent to. Missing permissions are assumed to be false. Since calling navigator.joinAdInterestGroup() with a lifetimeMs of 0 effectively leaves an interest group, joinAdInterestGroup: true also allows an origin to call navigator.leaveAdInterestGroup(), even if leaveadInterestGroup is missing or is set to false. Note that both leaveAdInterestGroup() and clearOriginJoinedAdInterestGroups() check the leaveAdInterestGroup permission.