Some of my Chrome extensions need access to the page you are looking at.
That sounds uncomfortable.
And it should.
If an extension can inspect a page before you submit a form, check a link before you open it, or look for personal information before you paste text into an AI chat, it needs enough access to do that job.
The interesting question is not:
“Can this extension read the page?”
It is:
“What happens to the data after it reads it?”
For Legacy Tools, I made that distinction a design rule.
The extensions may need to inspect page content.
They should not need to send that content to my server.
Permission is capability, not data flow
Chrome host permissions define what an extension is allowed to interact with.
For example, a content script may need access to a page so it can inspect a form field or intercept a click.
That permission tells you something important:
the extension has the capability to access that page.
But it does not tell you where the data goes afterward.
Two extensions can request similar page access and have completely different architectures.
One might:
Page
↓
Extension
↓
Remote API
↓
Analysis
↓
Result
Another can do:
Page
↓
Extension
↓
Local analysis
↓
Result
Legacy Tools tries to use the second shape whenever the task allows it.
A small example
Consider a tool that checks text before it is sent to an AI service.
It may need to see the text currently entered in the page.
The simplest server-based architecture would be:
- Read the text.
- Send it to an API.
- Analyze it on a server.
- Return detected personal information.
- Show the result.
That architecture can support powerful models.
But it creates a strange situation for a privacy tool:
to warn you about sending sensitive text somewhere, the tool first sends that text somewhere else.
So I chose a more limited architecture.
Text in the browser
↓
Local detection
↓
Show possible matches
↓
User decides what to do
No cloud model is required for that path.
The trade-off is real: local rules cannot understand every form of personal information.
That is acceptable.
The goal is not to promise perfect detection.
The goal is to provide one more chance to notice something before sending it.
I still try to reduce the permission itself
“Everything stays local” is not a reason to request unlimited permissions.
These are separate questions:
- What pages can the extension access?
- What does it do with the data it can access?
Both should be minimized.
Across the extensions I built, I ended up using several patterns.
Some tools genuinely need to work on many websites.
Some only need a fixed list of sites.
Some can request additional sites only when the user asks.
And one of my extensions can use activeTab, meaning it gets access only after the user explicitly invokes it on the current page.
I wrote about those permission patterns separately because choosing the smallest workable permission is part of the product design.
Local processing does not excuse broad access.
“No server” is a useful constraint
Not having a backend removes several things I would otherwise need to think about.
There is no database of user input to protect.
There is no API endpoint receiving page contents.
There is no retention policy for text that was never collected.
There is no account containing a history of what someone checked.
That does not make an extension automatically safe.
A local extension can still contain bugs.
It can request too much access.
A future update could change its behavior.
Another dependency could introduce a problem.
So I avoid saying:
“Local means safe.”
The more accurate statement is:
Local processing removes some classes of risk by removing unnecessary data movement.
That is a much smaller claim, but I think it is a more useful one.
AI-assisted development makes this rule more important
I use AI coding tools heavily.
That creates another failure mode.
An agent trying to solve a problem may reasonably decide that adding an API call, analytics package, external library, or broader host permission is the easiest implementation.
Technically, it may even be a good solution.
Architecturally, it may violate the product.
So I treat some things as boundaries rather than implementation details:
- Do not broaden host permissions without an explicit reason.
- Do not add external transmission just because it makes detection easier.
- Do not add telemetry by default.
- Do not replace a local implementation with a hosted service without reviewing the privacy change.
AI makes producing code cheaper.
It does not make architecture decisions cheaper.
If anything, those boundaries need to become more explicit.
Trust should come from constraints, not promises
A privacy policy can say:
“We respect your privacy.”
That is useful, but it is still a promise.
I prefer being able to say something more concrete:
“This feature does not require your text to leave the browser.”
That is an architectural property.
Users still have to trust the extension package and its updates, of course.
But every dependency or server you remove is one less thing they need to trust.
For small browser tools, that matters.
The uncomfortable permission warning is still useful
I used to think broad-looking Chrome permission warnings were mostly a UX problem.
Now I think the discomfort is healthy.
If an extension can read a page, users should know that.
The developer's job is not to make that capability sound harmless.
The job is to:
- request only the access the feature actually needs,
- explain why it needs that access,
- minimize what happens after access is granted,
- and avoid moving user data unless moving it provides enough value to justify the new risk.
So yes:
some of my Chrome extensions can read the page.
That is how they can help before you send, click, or submit something.
But being able to read the page does not mean the page needs to leave the browser.
For the kind of small safety tools I am building, that distinction has become one of the most important architectural decisions.
I build Legacy Tools, a small collection of browser tools designed to give people one more chance to check something before they act.
Previous article: 8 Shipped Chrome Extensions, 4 Ways to Declare Host Permissions
Top comments (0)