Chrome Extension Permissions Explained
Chrome Extension Permissions: What Each Field Tells You
Separate API permissions from website access and optional grants. Then check whether each request fits a feature you actually want to use.
Open the permissions in manifest.json
Extract the extension's ZIP and open its root manifest.json in a text editor. You can obtain a currently available public package through CRXFile. Our manifest reading guide covers the file structure. Review the downloaded version rather than relying on the listing's description alone.
Chrome's permission declaration guide distinguishes the fields below. These are Manifest V3 fields from an original teaching example of a page-note tool. This is an excerpt, not a complete extension; its domains and script filename are placeholders. We checked the JSON syntax on October 20, 2026, without an installation test.
{
"permissions": [
"storage",
"scripting",
"activeTab"
],
"host_permissions": [
"https://api.example.com/*"
],
"optional_permissions": [
"downloads"
],
"optional_host_permissions": [
"https://*.example.org/*"
],
"content_scripts": [
{
"matches": [
"https://docs.example.com/*"
],
"js": [
"annotate.js"
]
}
]
}A Chrome extension permission review table
| Field | What this example requests | Review question |
|---|---|---|
| permissions | Extension storage, scripting, and temporary access through activeTab. | Which feature uses each API or grant? |
| host_permissions | Access to the HTTPS host api.example.com. | What requests go there, and what data leaves the browser? |
| optional_permissions | A later request for the downloads API. | Can the tool work if export permission is refused? |
| optional_host_permissions | A later request for example.org or its subdomains over HTTPS. | Which user action asks for that access? |
| content_scripts.matches | A declared script on HTTPS pages at docs.example.com. | What page content does annotate.js read or change? |
Read across the fields. The example can have a declared content script on one host, make service-worker requests to another, and ask for an optional integration elsewhere. A single list of domain names would hide those differences.
API permissions describe different kinds of access
storage grants use of Chrome's extension storage API. It doesn't mean access to every website's saved data. Search for chrome.storage.local and chrome.storage.sync to see what the extension keeps and where. The Storage API reference explains the available storage areas.
scripting permits use of the scripting API, but injecting code into a page also requires suitable host access, which can come from activeTab. Check the scripting API requirements before treating that declaration as permission to run anywhere.
One common trap is tabs. It concerns sensitive tab properties, including URLs and titles. Many operations, such as opening a tab, don't require it. The Tabs API reference spells out the distinction. Match a permission to an actual operation, rather than guessing from its name.
For cookies, inspect both layers. The cookies API requires its named permission plus host permission for the sites whose cookies it accesses. A host declaration alone doesn't grant that API. Check which cookie values the extension reads or changes, then follow any messages or requests carrying them.
Host permissions and content script matches
In host_permissions, https://api.example.com/* names a host the extension can interact with, subject to the APIs it uses. Read its network calls to learn whether it retrieves public settings or sends page content. The manifest alone won't answer that.
Host permission paths are ignored. Writing /public/* instead of /* doesn't restrict host permission to that directory. <all_urls> covers permitted URL schemes across hosts; it doesn't override Chrome's restricted pages. Use the match pattern reference to check the scope.
content_scripts.matches has a different job: choosing pages for declared scripts. Those scripts don't need duplicate host permissions for their declared injection. Open the listed files and inspect their DOM access, messages, and data use. Chrome's content script guide covers the injection methods.
Optional permissions are requests for later
A name in optional_permissions isn't automatically granted at installation. In our example, an export button might request downloads. Find chrome.permissions.request and check what happens if the user refuses. The same review applies to optional_host_permissions for an additional website integration.
Check the grant, too. An installed extension can use chrome.permissions.contains to test a specific grant, or getAll to list the permissions it currently holds. Users can withhold site access, so a downloaded manifest cannot tell you what a particular user approved. The Permissions API reference documents runtime requests and permission checks.
activeTab is temporary, user-triggered access
activeTab grants temporary host access after a qualifying action, such as clicking the extension's toolbar button. It doesn't continuously cover every open tab. Access can survive navigation within the same origin, but ends when the user moves to a different origin or closes the tab. Chrome's activeTab guide explains the lifetime and restricted pages.
For a tool that acts only when clicked, check whether that temporary grant fits the feature. A content blocker that works throughout browsing may need a different access model. Broad access deserves an explanation; it isn't evidence of malicious intent by itself.
Compare host permissions vs activeTab with two complete Manifest V3 examples to see how the same feature can request different access.
Warnings help, but they aren't a safety verdict
Chrome combines some warnings, and some permissions show no warning at all. You can't reconstruct the whole manifest from an installation dialog. Chrome's warning guidelines also explain why adding a permission that triggers a warning can require renewed approval after an update.
Keep a short review record: package version, declared access, the feature that needs it, and the code you checked. Our backup workflow includes a record template. If a host or permission still has no clear purpose, write down that exact question and follow the relevant code using our source inspection guide. Then audit the extension's network requests to connect its declared hosts to actual destinations and request payloads.