Skip to content We're live on Product Hunt today Upvote
install

notes 5 min privacy

note

Why this extension asks for no website permissions

Every browser extension you install shows you a list before it runs. Most inspection tools ask for access to all your data on all websites, because it is the easiest thing to ask for. It is also the thing that makes people close the tab.

The permission list is the last honest moment between a user and an extension. After the install it is invisible; before it, it is the only thing that describes the code's reach. So the design question is not how to explain a broad permission well. It is whether the extension can be built without one.

This one is. host_permissions is empty in both the Chrome and the Firefox build. Four permissions are declared, and none of them names a website:

activeTab
One tab, from a click, until it navigates away.
storage
Settings and saved output, on this machine.
scripting
The mechanism that puts the inspection code into that one tab.
contextMenus
The right-click entry that opens it.

What activeTab actually grants #

activeTab gives an extension access to one tab, starting from a user gesture, ending when the tab navigates away. It is not a weaker version of host access. It is a different shape: host access is standing permission to every matching page whether anybody is looking or not, and activeTab is a key that turns once.

Concretely: nothing runs until you click. The inspection code is injected into the tab you are on, at the moment you ask, and the grant dies with the navigation. There is no content script sitting in every page you open, and there is no background process reading tabs because they happened to be open.

The trade is real:

  • It cannot act on page load.
  • It cannot watch a page it was not invited into.
  • It has to re-establish itself every single time.
  1. you click
  2. code enters this one tab
  3. you read it
  4. the tab navigates — gone

host permission, for comparison: granted at install, never revoked

The whole lifetime of the grant. It begins at a click, covers one tab, and ends at the next navigation - at which point the extension has to be invited again.

Those are features here rather than costs — but they are constraints on what the product can be, and they were chosen before the code was written rather than worked around afterwards.

The three things that genuinely need more #

Three settings cannot work under that model: opening the panel automatically on page load, a User-Agent switcher, and a WebRTC address control. Each needs a permission the four above do not cover.

So each one asks at the moment it is switched on, from the click that switches it, and hands the permission back when it is switched off. An optional permission is a different object from a declared one: it does not appear on the install screen, it is granted by a person who is looking at what they are enabling, and it is revocable without uninstalling.

A reader who never turns those on never grants them. That is the whole reason to build it this way rather than declaring the broad origin once and being done.

What the manifest looks like, and what to compare it against #

The claim is checkable in about ten seconds, and it is worth knowing how — for this extension and for the next one you install.

the four lines that decide the install screen
{
  "permissions": ["activeTab", "storage", "scripting", "contextMenus"],
  "host_permissions": [],
  "optional_permissions": ["privacy"],
  "optional_host_permissions": ["*://*/*"]
}

The distinction that matters is between the second line and the fourth. host_permissions is granted at install, silently, forever. optional_host_permissions is an offer the browser will only accept from a click, it does not appear on the install screen, and it can be handed back without uninstalling anything.

Read your browsing history
Means tabs or a broad host match. An inspector does not need it: activeTab gives the URL of the tab you asked about, and nothing about the others.
Read and change all your data on all websites
Means <all_urls> or *://*/* in host_permissions. This is the one to refuse. It is standing access to every page, whether the extension is being used or not.
Read and change your data on sites you visit
The wording Firefox uses for the same thing. Softer sentence, identical grant.
No website permissions listed
What activeTab alone looks like on the install screen. It is rare, and it is the thing to look for.

What a page reading actually sends #

Permissions describe reach; they say nothing about what leaves the machine. Those are separate promises and both have to be kept.

Inspection, extraction and the live editing tools run entirely in the browser and send nothing. A few readings do ask a server, each behind its own button. An audit sends counts rather than content — the hostname, the heading text and a set of numbers, with email addresses and long identifier strings redacted before anything leaves the page. Vulnerability dating sends detected package names and versions, with no hostname at all. The server-side readings send the page address with its query string removed, because asking a server to fetch a page cannot be done without naming it.

Input field values and body copy are never read. The field-by-field list is on the privacy page, and it is a list rather than a paragraph on purpose: a promise you cannot check is a slogan.

What it costs to build this way #

Worth saying plainly, because an architecture described only by its benefits is a sales page.

  • Nothing can be measured until you ask. No load-time metrics, no first-paint capture, no watching a page settle — anything that happened before the click did not happen for us.
  • Every session starts cold. The panel re-injects on each invocation and rebuilds its view of the page, which costs milliseconds a resident content script would not spend.
  • Some things are simply impossible. A feature that needs to observe a page it was not invited into cannot exist here, and several proposed ones did not.
  • It is harder to explain than to do. "We only read the tab you asked about" takes a paragraph; "we can read every page" takes none, and most users never read either.

The trade is accepted because the alternative is unfalsifiable. A promise about what an extension does with broad access cannot be checked by the person granting it. A permission list can.

How to check any of this #

Do not take the claim. The permission list on the store page is generated by the store from the manifest, not written by us, and it is visible before you install. If an extension's stated architecture and its permission list disagree, the list is the one telling the truth.

That applies to this one as much as to any other.

Written by Ján Turský

Building LoupeKit and other browser tools out of Bratislava, under Apptiary.

tools in this note