You finished the extension. The listing is written, the screenshots look great, you hit Submit for review - and a few days later the Chrome Web Store rejects it over something that has nothing to do with your code: the privacy policy.
It's one of the most common non-code rejection reasons, it blocks Firefox and Edge submissions too, and it's entirely avoidable. This post covers when you actually need a policy, what reviewers look for, and two ways to produce one - by hand, or generated from your manifest.json in about two minutes.
Do you actually need one?
Shorter answer than you'd hope: almost certainly yes.
The Chrome Web Store requires a privacy policy whenever your extension collects or transmits user data. The trigger is the actual data handling, not the mere presence of a permission in your manifest - but in practice these are the capabilities that usually mean you're collecting something:
-
storage- if you persist data tied to a user (purely local, non-personal settings don't trigger the requirement on their own) - host permissions (
<all_urls>,*://*.example.com/*) - you can read personal page content, and reviewers treat broad host access as a strong signal that you need a policy -
tabs,history,bookmarks,cookies- browsing data - any analytics, crash reporting, or error tracking (yes, self-hosted counts)
- accounts, sync, or anything that touches an email address
- data users type into the extension - form fields, notes, saved content, or messages are user data even when no permission appears in your manifest
On top of the policy URL itself, Chrome makes you fill out the privacy practices disclosure in the Developer Dashboard - a per-item form where you declare what data you collect and certify compliance with the Limited Use policy (purpose limitation, plus no selling, no advertising or data-broker transfer, and no human reading of the data outside a few narrow exceptions). Firefox no longer makes you host a privacy policy on AMO - that requirement was
dropped in August 2025; you now declare data collection with the
browser_specific_settings.gecko.data_collection_permissions manifest key and Firefox shows users a built-in consent prompt (mandatory for new add-ons since November 2025, rolling out to all add-ons through 2026). Microsoft Edge Add-ons still asks for a privacy policy URL in Partner Center for anything handling personal information.
So unless your extension requests no permissions and phones home to nothing, plan on shipping a policy with v1 - and plan for the rules getting stricter, not looser. From August 1, 2026, the Chrome Web Store limits data collection to what's strictly necessary for your extension's single stated purpose, and requires that collection to be disclosed prominently in the product itself, not only in the store listing.
What reviewers actually check
A privacy policy for an extension isn't a legal essay - it's a short document that answers five questions without contradicting your listing:
- What do you collect? Named concretely: "the text of the current tab", "the URLs you visit", "your email address", not "certain information".
- Why? Each data point maps to a feature. Collecting without a stated purpose is what the Limited Use policy exists to kill.
- Where does it go? On-device only? Your server? Third parties (analytics, payment processors)? Name them.
- How long do you keep it, and how does someone get it deleted?
- Who do I email about this? A working contact.
Two structural requirements trip people up more than the content:
- The URL has to work. A policy link that 404s, redirects to your homepage, or points at a Google Doc with restricted access is an instant rejection.
- It has to match your disclosure form. If the privacy practices tab says "collects website content" and your policy says "we collect nothing", a human reviewer notices the contradiction.
The policy is necessary, but it isn't the whole requirement
Here's the part most guides skip. If your extension collects any user data, the Chrome Web Store also wants a prominent disclosure and the user's affirmative consent inside the extension's own UI, shown before you collect anything - and it explicitly cannot live only in your privacy policy. In practice that's a first-run screen (or an options-page section) that names what you collect and why, with a control the user actively clicks to agree.
So a complete answer is two things: a hosted policy (the rest of this article) and an in-product consent step. The rule that ties them together: your policy, the privacy disclosures you fill in on the Developer Dashboard, and what your extension actually does must all say the same thing. Contradictions between them are treated as a policy violation and can take down every extension on the account, not just the one under review.
The manual route: a skeleton that passes
If you'd rather write it yourself, this outline covers what the stores expect.
Fill every section, delete nothing silently:
# Privacy Policy - <Extension Name>
_Last updated: <date>_
## What we collect
- <data point> - used for <feature>
- <data point> - used for <feature>
## What we do NOT collect
<the reassuring part - browsing history, page content, etc., if true>
## Where your data is processed
<on-device / our servers (location) / third parties, named>
## Data retention & deletion
<how long, and how a user requests deletion>
## Your rights
<GDPR basics if you have EU users - which, on a global store, you do>
## Contact
<a real email>
Budget 30-60 minutes to do this honestly: the slow part isn't writing, it's auditing your own manifest and dependencies to figure out what you actually collect. An extension with <all_urls> and a fetch to your API collects more than most authors think.
The 2-minute route: generate it from your manifest
The audit step is mechanical - your manifest.json already declares most of what your extension can touch. That's the idea behind the privacy policy generator we built at Extenshi. It's free and doesn't ask you to sign up - generation runs in your browser.
Step 1 - Select your permissions. The same set as your manifest
(storage, host permissions, tabs, webRequest, ...). Each permission you toggle adds the matching, correctly-scoped data-practice language.
Step 2 - Declare your data practices. Extension name, contact email, whether you run analytics, accounts, or payments, and what users provide directly: form input, content they create, personal communications, health information. That last group is the one manifest-only tools miss - it has no permission to derive from.
Step 3 - Pick your legal coverage. GDPR is on by default (store extensions are global, so EU users are a given), with CCPA/CPRA and child-directed (COPPA) toggles if they apply to you.
Step 4 - Export as Markdown or HTML. The preview updates live, so you can read exactly what you're shipping.
Because the sections are derived from your permissions and declared practices, the failure mode from the previous section - a policy that contradicts what the extension really does - mostly disappears. The tool also flags the part most people learn from a rejection email: it reminds you that the policy alone isn't enough and links the in-product disclosure-and-consent requirement covered above. If you're starting a new extension and want the same treatment for the manifest itself, there's a Manifest V3 generator that validates against store policies as you build it.
Hosting the policy (the 5-minute part everyone forgets)
The stores want a stable, public URL that doesn't require a sign-in. Google doesn't bless any specific host, so the bar is just that: reachable by anyone, and not going anywhere. Cheapest options:
-
GitHub Pages - drop the exported HTML into a repo, enable Pages, done. A
github.ioURL is public and stable, which is all reviewers need. -
A page on your existing site -
/privacynext to your landing page. - Avoid: Google Docs (access settings rot), Notion links behind "continue with Notion", URL shorteners.
Then wire it up in each store:
| Store | Where |
|---|---|
| Chrome Web Store | Developer Dashboard -> item -> Privacy tab (paste the URL + fill the practices disclosure) |
| Firefox Add-ons | Declare data collection via the data_collection_permissions manifest key; hosting a policy URL is now optional (still recommended) |
| Edge Add-ons | Partner Center -> extension property -> Privacy policy URL |
Rejection traps that survive a "valid" policy
Seen in the wild, all of these pass a casual read and still get flagged:
- Website policy, not extension policy. You reused your SaaS privacy page; it talks about cookies and newsletters and never mentions the extension's permissions. Reviewers read it as missing.
-
Over-collection mismatch. Manifest requests
<all_urls>; policy says "we do not collect browsing data". One of those is wrong - either narrow the permission or fix the policy. (Narrow the permission. It also improves your install-prompt.) - Stale after a feature. You added an analytics SDK in v1.4 and the policy still reflects v1.0. Updates get re-reviewed too - this is a common way for a previously-approved extension to pick up a violation.
-
Policy hosted inside the extension. A
chrome-extension://URL or a page only reachable after install doesn't count. It must be a public web URL.
Wrap-up
A privacy policy is the cheapest rejection to prevent: one honest page, hosted anywhere public, consistent with your manifest and your disclosure form. Write it by hand with the skeleton above, or generate it from your permissions in a couple of minutes and spend the time you saved on the listing screenshots.
The policy is one of several review axes, though. Risky permission combinations, vulnerable dependencies, and remote-code patterns get extensions rejected (and taken down) just as reliably - that side we cover with a pre-publish scan you can run in CI: npx @extenshi/cli scan ./dist/extension.zip. Fair warning on both tools: they're an automated signal, not a professional audit - for anything high-stakes, have a human lawyer read the final text.
If this saved you a rejection round-trip, follow to catch new ways to boost your workflow.




Top comments (0)