Unified Extensions Button and how to handle permissions in Manifest V3

Manifest V3 (MV3) is bringing new user-facing changes to Firefox, including the Unified Extensions Button to manage installed and enabled browser extension permissions (origin controls), providing Firefox users control over extension access to their browsers. The first building blocks of this button were added to Nightly in Firefox 107 and will become available with the general release of MV3 in Firefox 109.

Unified Extensions Button

The Unified Extensions button will give Firefox users direct control over website specific extension permissions.

In MV2, host permissions are granted by the user at the time of install and there’s no elegant way for the user to change this setting (short of uninstalling/reinstalling and choosing different permissions). But with the new Unified Extensions Button in MV3 in Firefox, users will have easy access and persistent control over which extensions can access any web page, at any time. Users are free to grant ongoing access to a website, or make a choice per visit. To enable this, MV3 treats host permissions (listed in the extension manifest) as opt-in.

The button panel will display the user’s installed and enabled extensions and their current permission state. In addition to managing host permissions, the panel also allows the user to manage, remove, or report the extension. Extensions with browser actions will behave similarly in the toolbar as in the panel.

Manifest V2 (MV2) extensions will also display in the panel; however users can’t take actions for MV2 host permissions since those were granted at installation and this choice cannot be reversed in MV2 without uninstalling the extension and starting again.

How to deal with opt-in permissions in extension code

The Permissions API provides a way for developers to read and request permissions.

With permissions.request(), you can request specific permissions that have been defined as optional permissions in the manifest:

const permissionsToRequest = {
  permissions: ["bookmarks", "history"],
  origins: ["https://developer.mozilla.org/"]
}

async function requestPermissions() {
  function onResponse(response) {
    if (response) {
      console.log("Permission was granted");
    } else {
      console.log("Permission was refused");
    }

    return browser.permissions.getAll();
  }

  const response = await browser.permissions.request(permissionsToRequest);
  const currentPermissions = await onResponse(response);

  console.log(`Current permissions:`, currentPermissions);
}

This is handy when the request for permissions is tied to a user action like selecting a context menu item. Note that you cannot request for a permission that is not defined in the manifest.

Other times, you’ll want to react to a permission being granted or removed. This can be done with permissions.onAdded and permissions.onRemoved respectively.


function handleAdded(permissions) {
  console.log(`New API permissions: ${permissions.permissions}`);
  console.log(`New host permissions: ${permissions.origins}`);
}

browser.permissions.onAdded.addListener(handleAdded);

Finally, you can check for already existing permissions in two different ways: permissions.getAll() returns a list of all granted permissions and permissions.contains(permissionsToCheck) checks for specific permissions and resolves to true if, and only if, all checked permissions are granted.


// Extension permissions are:
// "webRequest", "tabs", "*://*.mozilla.org/*"

let testPermissions1 = {
  origins: ["*://mozilla.org/"],
  permissions: ["tabs"]
};

const testResult1 = await browser.permissions.contains(testPermissions1);
console.log(testResult1); // true

We always encourage feedback from our developer community, so don’t hesitate to get in touch:

3 responses

Post a comment

  1. Max wrote on :

    I am not a fan of a unified extensions button. I like my extensions lined up on the extensions toolbar where I can see them and interface with them and I want them to stay there. If that bar goes away, I will stop updating Firefox at that version. Humbly yours, FF user since FF 31.8.0.

    Reply

    1. Juha-Matti Santala wrote on :

      The toolbar isn’t going away. You will still be able to pin your extensions to the toolbar and interact with them.

      You can have your most used extensions in the toolbar for easy access while having a convenient way to provide permissions for all extensions through the Unified Extensions Button.

      Reply

  2. Habi wrote on :

    So if a user installs an add-on that for example changes the background color of all websites. Nothing will work out of the box and no permission request dialog or anything similar will appear even if the user opens a website, right? Users somehow need to know that they have to manually grant the permission through the new extension button.

    I really would like a system were Firefox automatically asks if the user wants to allow the add-on to run on a website when visiting it the first time. There could be an option like “don’t ask again” to avoid spamming this dialog. This would make the user aware that the extension has additional requirements. Otherwise I can already see a lot of users complaining that the add-on does not work while the reason is simply an uncommunicated missing host permission.

    Reply

Post Your Comment