Implementing a Permissions Policy in Gecko

Adding a permissions policy (previously “feature policy”) to Gecko is pretty straight forward, thankfully. We have a great API that makes adding permissions policies really easy – see FeaturePolicy.h.

A Permissions Policy has a name and an “allowlist”. For instance, gamepad’s permission name is “gamepad” and its allow list is “self” (only allow same origin).

In Gecko, we can declare the above is FeaturePolicyUtils.cpp in either ” sSupportedFeatures[]” or “sExperimentalFeatures[]”. We treat “gamepad” as experimental for now:

static FeatureMap sExperimentalFeatures[] = {
  ... other permissions...
  {"gamepad", FeaturePolicyUtils::FeaturePolicyValue::eSelf},
  ... 
}

Generally, Permissions Policy affect the functionality of APIs in the platform. If a permissions policy is denied to an iframe then calling a method, for instance, will cause that method to throw.

Here is an example from the Gamepad API, which is in navigator.cpp:

// Check if we are "allowed to use" some feature
// in this case, "gamepad" 
if (!FeaturePolicyUtils::IsFeatureAllowed(mWindow->GetExtantDoc(),
u"gamepad"_ns))) {
  aRv.ThrowSecurityError(
   "Document's Permission Policy does not allow calling "
   "getGamepads() from this context.");
  return;
}

In JS, then, the following would throw in any third-party context (e.g., a remote iframe that doesn’t have an allowed=”gamepad” attribute declared):

navigator.getGamepads(); // throws SecurityError DOM Exception