Writing a Privacy Policy for an Extension
Write an accurate privacy policy for an MV3 browser extension: inventory data flows from code, describe permissions in plain language, match store data-disclosure forms, cover analytics, retention and deletion, and keep it current.
Table of Contents
The Chrome Web Store rejects the submission: “Your product’s privacy practices disclosure does not match its behaviour” or “Privacy policy required”. The extension reads page content to summarise it, syncs settings, and sends crash reports — each of which is data handling that must be disclosed, consistently, in three places: the store’s privacy practices form, the privacy policy linked from the listing, and the extension’s actual behaviour. Reviewers compare them. A policy copied from a website template fails, because it does not mention what extensions uniquely touch: browsing activity, page content, tabs and installed permissions. This guide builds a policy from the code outward. It belongs to store submission and permissions compliance.
What makes extension privacy different
A website sees what users do on that website. An extension with host permissions can see what users do on every website it can access: URLs, page content, form input, selected text. Store policies therefore treat extensions strictly. The Chrome Web Store’s user data policy requires a privacy policy whenever an extension handles personal or sensitive user data, requires that collection be limited to what the extension’s single purpose needs, prohibits selling data and using it for unrelated purposes such as ads or creditworthiness, and requires a privacy-practices disclosure in the developer dashboard that matches the policy. AMO and Apple have comparable requirements. The policy is a factual description of data flows that reviewers can check against the code — not a legal shield written in the abstract.
Step-by-step: from code to policy
1. Inventory every data flow from the code
1# Where data can leave the device
2grep -rnE "fetch\(|sendBeacon|XMLHttpRequest|WebSocket\(|connectNative|sendNativeMessage" src
3# What sensitive data the code reads
4grep -rnE "tabs\.query|tab\.url|cookies\.|history\.|bookmarks\.|getSelection|innerText|textContent|storage\.(sync|local)" src | wc -l
Execution context: a terminal over your source. List each outbound request: its destination, what it carries, when it happens and why. Then list what the extension reads but keeps on the device. The distinction matters — reading page content locally to highlight words is different from sending it to a server — and both belong in the policy. Include third-party SDKs: error reporters, analytics, payment providers.
2. Classify each item
1data-inventory.md
2| Data | Read? | Leaves device? | Destination | Purpose | Retention |
3|-----------------------|-------|----------------|----------------------|--------------------|-----------|
4| Page text (on click) | Yes | Yes | api.readable.example | Summarise | Not stored|
5| Page URL (on click) | Yes | Yes | api.readable.example | Cache key | 30 days |
6| Settings | Yes | Via Chrome Sync| Google (sync) | Sync preferences | Until removed |
7| Crash reports | Yes | Yes (opt-in) | errors.readable.example | Fix bugs | 90 days |
8| Browsing history | No | — | — | — | — |
Execution context: a working document that becomes the policy’s backbone. Being explicit about what you do not collect is as valuable as what you do — “We never read your browsing history” answers a question users and reviewers will ask. Map each row to the store’s data categories (for Chrome: personally identifiable information, health, financial, authentication, personal communications, location, web history, user activity, website content).
3. Write the policy in the order users read it
1# Readable privacy policy (effective 2 October 2026)
2
3**In short:** Readable sends a page's text to our server only when you click "Summarise".
4We don't read your browsing history, sell data, or use it for advertising.
5
6## What Readable accesses and why
7- **Page text and address, when you click Summarise** — sent to api.readable.example to create
8 the summary. The text is processed and discarded; the address is kept for 30 days as a cache key.
9- **Your settings** — stored in your browser and synced by your browser's sync service if you use it.
10- **Crash reports (optional)** — error messages and the extension version, if you turn this on.
11
12## What Readable never does
13...
14## Permissions explained
15- "Read and change your data on websites you click": lets Readable read the page you're on when
16 you click the toolbar button (activeTab).
17...
18## Retention, deletion and your choices
19...
20## Contact
21privacy@readable.example
Execution context: a public web page linked from the listing. Lead with a plain-language summary, then details per data type, then permissions in user terms, then retention and deletion, then contact information. Name the exact permission warnings users saw at install and explain each. Avoid vague catch-alls (“we may collect information to improve our services”) — reviewers treat them as undisclosed collection.
4. Fill in the store disclosure to match
In the Chrome Web Store dashboard’s privacy tab, state the single purpose, justify each permission, tick the data categories you collect, and certify the limited-use requirements (no selling, no unrelated use, no human reading except where necessary). Every ticked category should appear in the policy; every item in the policy that leaves the device should have a ticked category. AMO asks for similar information and, for newer Firefox versions, a data-collection declaration in the manifest.
5. Get consent where policies require it
1// onboarding.js — opt-in before optional data collection
2consentBox.addEventListener("change", () => chrome.storage.sync.set({ crashReports: consentBox.checked }));
Execution context: an onboarding or options page. Collection that is not essential to the single purpose — analytics, crash reports with page context — should be opt-in, with a clear description at the point of consent. AMO requires opt-in for most data collection; Chrome requires prominent disclosure and consent for some categories. The policy should describe the consent and how to withdraw it.
6. Cover retention, deletion and contact
State how long each kind of data is kept, how users can delete it (an in-extension “Delete my data” action is best, an email address is the minimum), and what happens when the extension is uninstalled — browser-stored data is removed by the browser; server-side data needs your process. Provide a real contact address and respond to it.
7. Keep it current
Add a “privacy impact” checkbox to your pull request template: does this change add a new destination, read new data, or change retention? If yes, update the inventory, the policy and the store form in the same release. Date the policy and keep a changelog of material changes.
Common mistakes
- A generic website template. It omits browsing data and page content.
- Vague catch-all language. Treated as undisclosed collection.
- Form and policy disagree. The most common rejection reason.
- Forgetting third-party SDKs. Their requests are your data flows.
- Never updating. New features silently invalidate the policy.
Cross-browser variation
- Chrome / Edge: Chrome Web Store privacy practices tab and user data policy; Edge Add-ons asks for a privacy policy URL for extensions handling personal data.
- Firefox: AMO requires a privacy policy when data is transmitted, opt-in consent for most collection, and in newer versions a manifest data-collection declaration.
- Safari: the containing app’s App Store privacy “nutrition label” must cover the extension’s data collection.
Verification
- Use every feature with DevTools’ Network panel open on each context and confirm every request is described.
- Compare the store form’s ticked categories with the policy line by line.
- Ask someone outside the team to read the summary and explain what the extension sends; correct anything they get wrong.
- Confirm the policy URL is public, loads without login, and is linked from the listing.
FAQ
Do I need a policy if nothing leaves the device?
Many stores still require one if you handle personal data locally. A short policy saying so is easy and reassuring.
Should the policy mention browser sync?
Yes — settings synced through Chrome or Firefox Sync are processed by those providers. Name them.
Can I link my company’s general privacy policy?
Only if it specifically covers the extension’s data flows. Usually a dedicated page is clearer.
Related
- Writing a permission justification that passes — the permission side of the form.
- Privacy-preserving usage metrics — collecting less to disclose less.
- Reporting errors without breaking your privacy policy — crash reports that match the policy.
- Store submission and permissions compliance — the parent topic.