# 8 Shipped Chrome Extensions, 4 Ways to Declare Host Permissions

> Source: <https://dev.to/k-wada/8-shipped-chrome-extensions-4-ways-to-declare-host-permissions-3n1c>
> Published: 2026-08-21 17:16:55+00:00

I ship eight small Chrome extensions under Legacy Tools. They are all

Manifest V3, and they all need some form of access to the pages you

visit — that is what tools that check things before you send them do.

I have written before about [the rules I give AI agents](https://dev.to/k-wada/after-shipping-8-chrome-extensions-these-are-the-5-rules-i-always-give-ai-agents-13al)

so they never broaden permissions on their own. This post is about the

other side of that: the shapes the declarations themselves take.

Recently I put all eight manifests side by side (the versions shipped to

the Chrome Web Store as of 2026-08-22) and realized they ended up using

four different shapes to declare that access. None of this was planned

up front; each shape fell out of what the tool is. Here is the survey.

**1. Everywhere, all the time — five extensions.**

Safe Privacy Gate, Safe Attachment Check, Safe Mail Link Check, Site

Operator Check, Find My Age. These step in right before a send or a

click, and there is no way to know in advance which site that will

happen on. Interesting detail: only two of the five actually write

`<all_urls>`

into `host_permissions`

. The other three get the same

breadth from `content_scripts.matches`

alone.

**2. One fixed site — one extension.**

Safe Night Check is a Gmail-only tool, so the whole declaration is a

single pattern: `https://mail.google.com/*`

.

**3. A fixed list plus optional grants — one extension.**

Safe Privacy Mask enumerates thirty `matches`

patterns for the AI chat

sites it supports, and puts `<all_urls>`

into

`optional_host_permissions`

so that any other site is granted only when

the user adds it, one prompt at a time.

**4. activeTab only — one extension.**

While checking what these declarations look like from the user's side

(on `chrome://extensions`

, with the extensions side-loaded into

Chromium), two things stood out:

`storage`

,
`scripting`

, `contextMenus`

and `activeTab`

— none of those produces
a line in that box. "The permissions list is blank, so it must be
harmless" is not a read you can make.`matches`

counts as a host permission.`host_permissions`

at all, and its site-access wording
was character-for-character identical to Safe Privacy Gate, which
declares `<all_urls>`

explicitly. You cannot shrink the warning by
moving breadth out of `host_permissions`

and into `content_scripts`

.Permission declarations are not configuration. They are UI — shown to

the user, in their words, at install time and on the details page. The

shape you choose is a product decision: `<all_urls>`

is honest for a

tool that must work everywhere, a fixed list is honest for a

single-site tool, and `activeTab`

is worth the extra design work when

"only when I ask" is the actual contract.

I wrote up the longer versions of both halves of this:
