← Back to blog
Deep Dive · 9 min read

Chrome Extension Permissions Explained (and How to Ask for Fewer)

Every Chrome extension declares permissions. Asking for too many gets you rejected — and scares users. Here's how to ask for less.

Illustration for the ManifestGo article: Chrome Extension Permissions Explained (and How to Ask for Fewer)

Permissions are the single biggest reason Chrome extensions get rejected or uninstalled. The good news: most extensions ask for far more than they actually need.

The permission types

  • API permissions — `storage`, `alarms`, `tabs`, `scripting`. Required to call those Chrome APIs.
  • Host permissions — `https://example.com/*` or `<all_urls>`. Required to read/modify a site's pages.
  • Optional permissions — requested at runtime, not install time. Far less scary for users.

How to ask for less

  1. Use `activeTab` instead of `<all_urls>` when you only need the current tab on user action.
  2. Use `host_permissions` scoped to specific domains, not the universal wildcard.
  3. Move non-essential permissions to `optional_permissions` and request them on demand.
  4. Use the `scripting` API instead of declaring content scripts for every page.

ManifestGo defaults to the narrowest permissions that satisfy your prompt. If you describe a YouTube tweak, you get host access to youtube.com — not the entire web.

The full permission-warning tiers Chrome shows users

Chrome buckets permissions into warning severities at install time. High-warning permissions like <all_urls>, tabs (combined with host access), or debugger show a red-flagged 'can read and change all your data on all websites' message. Mid-tier permissions like a single host_permissions domain show 'can read and change your data on example.com'. Low-risk permissions like storage or alarms alone produce no visible warning at all — this is why narrowing scope isn't just a review-approval trick, it directly changes what users see before installing.

Permissions that require a written justification even when narrow

  • tabs — even without host_permissions, tabs exposes URLs and titles of every open tab, which counts as browsing-activity data collection under Chrome's Privacy Practices policy.
  • cookies — always needs justification, since reading cookies is treated as sensitive regardless of domain scope.
  • geolocation — rarely needed for extensions since the Geolocation Web API already prompts users directly from content scripts.
  • management — lets an extension inspect or disable other installed extensions; almost always flagged for manual review given its power.

Optional permissions: the runtime request flow

  1. List the permission under optional_permissions (or optional_host_permissions) in manifest.json instead of permissions.
  2. Call chrome.permissions.request({ permissions: [...] }) from a user gesture, like a button click in the popup.
  3. Chrome shows a small runtime prompt scoped to just that permission, not the broader install-time warning.
  4. Check chrome.permissions.contains before using the API each time, since users can later revoke it from chrome://extensions.

Common permission-related rejection messages

"Your extension requests but does not appear to use the following permissions" fires when static analysis of your code finds no matching chrome.* call for a declared permission — often left over from a copy-pasted manifest template. "You must provide a privacy policy because your item requests the following permissions" applies to tabs, history, webNavigation, and any host permission beyond a small allowlist.

A before/after example

A prompt like 'summarize any page' naively maps to host_permissions: ["<all_urls>"]. A better-scoped version uses activeTab plus scripting, since the summarizer only needs the page the user is currently viewing when they click the icon — no persistent background access to every site required. ManifestGo defaults to this narrower pattern whenever a prompt describes an on-click, single-page action rather than continuous background monitoring.

If a permission only matters when the user clicks your icon, it belongs behind activeTab, not a standing host_permissions grant.

Frequently asked questions

Does removing a permission in an update require re-review?

Removing permissions is low-risk and typically doesn't trigger the deeper manual review that adding new powerful permissions does, though the update still goes through standard automated checks.

What's the difference between activeTab and a host_permissions entry for the same site?

activeTab grants access only after a user gesture like clicking the toolbar icon and only for that tab, while a host_permissions entry grants standing access to that domain across all tabs and at all times without requiring a click.

Can users see which permissions an extension actually uses versus what it declares?

Not directly in the Chrome UI — users only see the install-time or runtime warning generated from declared permissions; mismatches between declared and used permissions are caught by Web Store review, not visible to end users.

Keep reading