Secure, test, and publish
Review permissions and data
Audit every requested capability, stored value, transmitted field, and website interaction before asking users to trust the extension.
Before asking anyone to install Page Notes, we audit it. A permission that took you five seconds to add can take a user five minutes to justify.
The audit has two parts: what we ask for, and where data goes.
Three kinds of permission, again
Keep them separate in the review:
storageenables an API. No user data involved.activeTabgrants access to one tab, after a gesture, for a while.host_permissionsgrant ongoing access to every URL matching a pattern, and Chrome warns about them at install.
Page Notes has no host permissions, and I want to keep it that way. When "<all_urls>" would make something more convenient, the answer is still no.
If a future feature needs more, use optional permissions. Declare them under optional_permissions and request them with chrome.permissions.request() from a user gesture, when the user turns that feature on. If they say no, the rest of the extension must keep working.
Follow the data, not the manifest
The manifest lists capabilities. It doesn’t tell you where data flows. Trace that by hand:
- The active URL becomes a storage key.
- Note text goes from the popup into
storage.local. - Note text goes from a trusted context into an untrusted page DOM.
- An extension update changes what future versions do with all of it.
For each step, answer three questions. Who can read this value? How long does it stay? What happens when the user deletes the note or uninstalls the extension?
For Page Notes: the URL key and the note stay on this device, in extension storage, until the user clears them or removes the extension. Nothing else reads them. That sentence goes in the store listing.
“Local-only” has to be true
Saying data stays local means nothing if the code has an analytics script, a crash reporter, or a <script> from a CDN. Any of those can carry a URL or a note out.
Check it two ways. Search the source for fetch, XMLHttpRequest, navigator.sendBeacon, and remote URLs. Then open the Network panel in every context, use the extension end to end, and confirm it stays empty. If you add a network call later, the store disclosures change first, then the release.
Write it down
Make a table with one row per feature. Columns: user gesture, context, data fields, destination, retention, deletion, install warning, and what happens when access is denied.
Then remove scripting from the manifest and check that saving and loading notes still work. A feature should fail only where the permission was actually used. Keep a screenshot of the empty Network panel as evidence that no note or URL leaves the browser.
Lesson completed