diff --git a/src/common/options/optionsPermissions.js b/src/common/options/optionsPermissions.js
new file mode 100644
index 0000000..f005131
--- /dev/null
+++ b/src/common/options/optionsPermissions.js
@@ -0,0 +1,212 @@
+import actionApi from '../actionApi.js';
+import {optionsPrototype} from './optionsPrototype';
+import {getOptions} from './optionsUtils.js';
+
+// Required permissions, including host permissions.
+//
+// IMPORTANT: This should be kept in sync with the "permissions",
+// "host_permissions" and "content_scripts" keys in //templates/manifest.gjson.
+const requiredPermissions = {
+  permissions: new Set([
+    'storage', 'alarms',
+    // #!if browser_target == 'chromium_mv3'
+    'scripting',
+    // #!endif
+  ]),
+  origins: new Set([
+    // Host permissions:
+    'https://support.google.com/*',
+
+    // Content scripts matches:
+    'https://support.google.com/s/community*',
+    'https://support.google.com/*/threads*',
+    'https://support.google.com/*/thread/*',
+    'https://support.google.com/*/community-guide/*',
+    'https://support.google.com/*/community-video/*',
+    'https://support.google.com/*/profile/*',
+    'https://support.google.com/profile/*',
+  ]),
+};
+
+const permissionTypes = ['origins', 'permissions'];
+
+// Returns an array of optional permissions needed by |feature|.
+export function requiredOptPermissions(feature) {
+  if (!(feature in optionsPrototype)) {
+    console.error('"' + feature + '" feature doesn\'t exist.');
+    return [];
+  }
+
+  return optionsPrototype[feature]?.requiredOptPermissions ?? [];
+}
+
+// Returns a promise resolving to the optional permissions needed by all the
+// current enabled features.
+export function currentRequiredOptPermissions() {
+  return getOptions(null, /* requireOptionalPermissions = */ false)
+      .then(options => {
+        let permissions = {
+          origins: [],
+          permissions: [],
+        };
+
+        // For each option
+        for (const [opt, optMeta] of Object.entries(optionsPrototype))
+          // If the option is enabled
+          if (options[opt])
+            // Add its required optional permissions to the list
+            for (const type of permissionTypes)
+              permissions[type].push(
+                  ...(optMeta.requiredOptPermissions?.[type] ?? []));
+
+        return permissions;
+      });
+}
+
+// Ensures that all the optional permissions required by |feature| are granted,
+// and requests them otherwise. It returns a promise which resolves specifying
+// whether the permissions were granted or not.
+export function ensureOptPermissions(feature) {
+  return new Promise((resolve, reject) => {
+    let permissions = requiredOptPermissions(feature);
+
+    chrome.permissions.contains(permissions, isAlreadyGranted => {
+      if (isAlreadyGranted) return resolve(true);
+
+      chrome.permissions.request(permissions, granted => {
+        // If there was an error, reject the promise.
+        if (granted === undefined)
+          return reject(new Error(
+              chrome.runtime.lastError.message ??
+              'An unknown error occurred while requesting the permisisons'));
+
+        // If the permission is granted we should maybe remove the warning
+        // badge.
+        if (granted) cleanUpOptPermissions(/* removeLeftoverPerms = */ false);
+
+        return resolve(granted);
+      });
+    });
+  });
+}
+
+// Returns a promise resolving to the currently granted optional permissions
+// (i.e. excluding required permissions).
+export function grantedOptPermissions() {
+  return new Promise((resolve, reject) => {
+    chrome.permissions.getAll(response => {
+      if (response === undefined)
+        return reject(new Error(
+            chrome.runtime.lastError.message ??
+            'An unknown error occurred while calling chrome.permissions.getAll()'));
+
+      let optPermissions = {};
+      for (const type of permissionTypes)
+        optPermissions[type] =
+            response[type].filter(p => !requiredPermissions[type].has(p));
+      resolve(optPermissions);
+    });
+  });
+}
+
+// Returns a promise resolving to an object with 2 properties:
+//   - missingPermissions: optional permissions which are required by enabled
+//     features and haven't been granted yet.
+//   - leftoverPermissions: optional permissions which are granted but are no
+//     longer needed.
+export function diffPermissions() {
+  return Promise
+      .all([
+        grantedOptPermissions(),
+        currentRequiredOptPermissions(),
+      ])
+      .then(perms => {
+        let diff = {
+          missingPermissions: {},
+          leftoverPermissions: {},
+        };
+        for (const type of permissionTypes) {
+          diff.missingPermissions[type] =
+              perms[1][type].filter(p => !perms[0][type].includes(p));
+          diff.leftoverPermissions[type] =
+              perms[0][type].filter(p => !perms[1][type].includes(p));
+        }
+        return diff;
+      })
+      .catch(cause => {
+        throw new Error(
+            'Couldn\'t compute the missing and leftover permissions.', {cause});
+      });
+}
+
+// Returns a promise which resolves to the required optional permissions of
+// |feature| which are missing.
+//
+// Accepts an argument |grantedPermissions| with the granted permissions,
+// otherwise the function will call grantedOptPermissions() to retrieve them.
+// This can be used to prevent calling chrome.permissions.getAll() repeteadly.
+export function missingPermissions(feature, grantedPermissions = null) {
+  let grantedOptPermissionsPromise;
+  if (grantedPermissions !== null)
+    grantedOptPermissionsPromise = new Promise((res, rej) => {
+      res(grantedPermissions);
+    });
+  else
+    grantedOptPermissionsPromise = grantedOptPermissions();
+
+  return Promise
+      .all([
+        grantedOptPermissionsPromise,
+        requiredOptPermissions(feature),
+      ])
+      .then(perms => {
+        let missingPerms = {};
+        for (const type of permissionTypes)
+          missingPerms[type] =
+              perms[1][type].filter(p => !perms[0][type].includes(p))
+          return missingPerms;
+      })
+      .catch(cause => {
+        throw new Error(
+            'Couldn\'t compute the missing permissions for "' + feature + '",',
+            {cause});
+      });
+}
+
+// Returns true if permissions (a chrome.permissions.Permissions object) is
+// empty (that is, if their properties have empty arrays).
+export function isPermissionsObjectEmpty(permissions) {
+  for (const type of permissionTypes) {
+    if ((permissions[type]?.length ?? 0) > 0) return false;
+  }
+  return true;
+}
+
+// Deletes optional permissions which are no longer needed by the current
+// set of enabled features (if |removeLeftoverPerms| is set to true), and sets a
+// badge if some needed permissions are missing.
+export function cleanUpOptPermissions(removeLeftoverPerms = true) {
+  return diffPermissions()
+      .then(perms => {
+        let {missingPermissions, leftoverPermissions} = perms;
+
+        if (!isPermissionsObjectEmpty(missingPermissions)) {
+          actionApi.setBadgeBackgroundColor({color: '#B71C1C'});
+          actionApi.setBadgeText({text: '!'});
+          actionApi.setTitle({
+            title: chrome.i18n.getMessage('actionbadge_permissions_requested')
+          });
+        } else {
+          actionApi.setBadgeText({text: ''});
+          actionApi.setTitle({title: ''});
+        }
+
+        if (removeLeftoverPerms) {
+          chrome.permissions.remove(leftoverPermissions);
+        }
+      })
+      .catch(err => {
+        console.error(
+            'An error ocurred while cleaning optional permissions: ', err);
+      });
+}
