Data collection consent in Firefox extensions: how to implement Mozilla's new manifest requirement
Mozilla now requires all Firefox extensions to declare data collection in manifest.json. Here's exactly how to implement data_collection_permissions correctly.
If you ship a Firefox extension and you haven't added data_collection_permissions to your manifest yet, you're running out of time. Mozilla has required this field for all new extensions since November 3, 2025. Existing extensions get a grace period — the official deadline window is "the first half of 2026," and as of May 2026 Mozilla has not narrowed that further on the Add-ons Blog. With H1 closing on June 30, you should treat the deadline as imminent rather than waiting for a more specific date. Miss it, and AMO will reject your submissions.
I've been tracking this change since it hit Nightly back in May 2025, and honestly — the implementation is straightforward once you understand the data categories. The problem is that Mozilla's documentation is spread across three different pages, and the edge cases aren't obvious. So here's everything you need in one place.
What changed and why it matters
Mozilla introduced a built-in data consent framework that moves data collection declarations from vague privacy policy pages into the manifest itself. Instead of users having to dig through a privacy policy to figure out what your extension collects, Firefox now shows data collection information in three places:
- The installation prompt (before the user even installs)
- The extension listing on addons.mozilla.org
- The
about:addonspage under "Permissions and Data"
This is a significant shift. It means your extension's data practices are visible to users at every touchpoint, not buried in a legal document nobody reads. From a developer perspective, it also means the manifest is now the source of truth for your data collection practices — not just your privacy policy.
According to Mozilla's Add-ons Blog announcement, "In the first half of 2026, Mozilla will require all extensions to adopt this framework." If your extension is already on AMO, you have a grace period. But once you start using the keys in any version, every subsequent version must include them too. There's no going back.
The manifest structure
The declaration lives under browser_specific_settings.gecko.data_collection_permissions. Here's what a basic implementation looks like for an extension that requires browsing activity data and optionally collects technical metrics:
{
"manifest_version": 3,
"name": "My Extension",
"version": "1.0",
"browser_specific_settings": {
"gecko": {
"id": "[email protected]",
"strict_min_version": "140.0",
"data_collection_permissions": {
"required": ["browsingActivity"],
"optional": ["technicalAndInteraction"]
}
}
}
}Two arrays: required and optional. That's the core of it. But the distinction between them is important, and getting it wrong will frustrate your users.
Required vs. optional: getting the split right
Required data collection means the user must accept it to use your extension. There's no opt-out. If someone declines your required data collection at install time, they can't install the extension.
Optional data collection is exactly what it sounds like — the user can decline it and still use your extension. Firefox shows these as toggleable options.
Here's the practical rule I follow: if your extension literally cannot function without a data type, put it in required. Everything else goes in optional.
For example, a tab manager that needs to know which tabs are open? browsingActivity is arguably required. But if you also want to collect anonymous usage telemetry to improve the product, that's technicalAndInteraction in the optional array — because the tab manager still works without it.
One special case: technicalAndInteraction can only be optional, never required. Mozilla's framework enforces this at submission time.
The complete data categories
Here are all the data types you can declare, based on Mozilla's official documentation:
Personal data categories (can be required or optional):
| Category | What it covers |
|---|---|
authenticationInfo |
Credentials, tokens, session data |
bookmarksInfo |
Browser bookmark data |
browsingActivity |
URLs visited, browsing history, page content |
financialAndPaymentInfo |
Payment details, financial data |
healthInfo |
Health or medical data |
locationInfo |
Geographic or location data |
personalCommunications |
Emails, messages, chat content |
personallyIdentifyingInfo |
Names, emails, addresses, phone numbers |
searchTerms |
User search queries |
websiteActivity |
Interaction data from specific websites |
websiteContent |
Content from websites the user visits |
Technical data category (optional only):
| Category | What it covers |
|---|---|
technicalAndInteraction |
Browser settings, platform info, hardware properties, interaction telemetry |
Most extensions will use a small subset of these. If you're building a content blocker, you probably need browsingActivity. A password manager might need authenticationInfo and personallyIdentifyingInfo. A simple theme or toolbar extension might need none at all.
The "no data collection" declaration
If your extension doesn't collect or transmit any personal data — and plenty of extensions genuinely don't — you still need to declare it explicitly:
{
"browser_specific_settings": {
"gecko": {
"data_collection_permissions": {
"required": ["none"],
"optional": []
}
}
}
}Setting "required": ["none"] is not the same as omitting the field. Omitting it means you haven't declared your practices. Setting it to ["none"] means you've explicitly stated that your extension doesn't collect personal data. Users see this as a positive signal, and it's good practice even for extensions where data collection isn't relevant.
Common pitfalls I've seen
1. Forgetting backward compatibility
If your extension supports Firefox versions prior to 140 (Desktop) or 142 (Android), those older versions don't understand the data_collection_permissions key. They'll ignore it, which means users on older Firefox won't see the consent UI.
Mozilla's requirement here is clear: if you support pre-140 Firefox, you must provide your own post-installation data control options. That means a settings page or popup where users can opt in or out of data collection — independent of Firefox's built-in consent flow.
Here's a pattern that works:
// Check if Firefox handled consent natively
async function hasNativeConsent() {
const info = await browser.runtime.getBrowserInfo();
const majorVersion = parseInt(info.version.split('.')[0], 10);
return majorVersion >= 140;
}
// Fall back to custom consent for older Firefox
async function initDataConsent() {
if (await hasNativeConsent()) {
// Firefox 140+ handles consent through the manifest
return;
}
// Show your own consent dialog for older versions
await browser.tabs.create({
url: browser.runtime.getURL('consent.html')
});
}2. Over-declaring data categories
I've seen developers list every possible data type "just to be safe." Don't do this. Declaring healthInfo or financialAndPaymentInfo when you don't collect them makes your extension look invasive at install time. Users see those categories and think twice.
Declare exactly what you collect — nothing more, nothing less. You can see how other extensions handle their permission declarations by browsing the Extenshi catalog.
3. Mixing up required and optional
If you put something in required that could be optional, you're forcing users into an all-or-nothing choice. They might skip your extension entirely because they don't want to agree to required browsing activity collection when your core feature doesn't actually need it.
Be honest about what's truly required for your extension to function. A recommendation engine that "works better" with browsing data but still functions without it? That's optional, not required.
4. The one-way door
Once you ship a version with data_collection_permissions, every subsequent version must include them. You can change the categories (if your data practices change), but you can't remove the keys entirely. Plan your implementation before you ship.
Cross-browser considerations
If you ship on both Chrome and Firefox (and you probably should), the browser_specific_settings key is Firefox-specific. Chrome ignores it. Your manifest can include both Firefox-specific and Chrome-specific fields without conflict.
That said, Chrome has its own privacy declarations in the Web Store dashboard — they're just not manifest-level yet. And with Mozilla pushing this standard, there's a reasonable chance Chrome will follow with something similar. Getting your data practices documented now makes you ready for whatever comes next. The Extenshi security reports already surface permission and privacy data for both Chrome and Firefox extensions, so you can compare how your cross-browser extension presents itself on each platform.
For cross-browser extensions, keep your data collection logic consistent across browsers even if the declaration mechanisms differ. If you tell Firefox users you collect browsingActivity, your Chrome version shouldn't be doing the same thing without equivalent disclosure in the CWS privacy practices tab.
Testing your implementation
Before submitting to AMO, validate your manifest:
- Load it in Firefox Nightly or Developer Edition (140+) — the consent UI should appear on install
- Check
about:addons— your extension should show data categories under "Permissions and Data" - Try submitting to AMO staging — the validation will catch missing or malformed keys
- Test the opt-out flow — if you have
optionaldata types, verify that declining them doesn't break your extension
If you're using web-ext, the linting step will catch basic manifest issues, but it may not validate all data_collection_permissions edge cases yet. Manual testing against a real Firefox build is still worth doing.
If you'd rather not hand-write the manifest, my free Manifest V3 generator builds the data_collection_permissions block (and the Firefox-specific browser_specific_settings) with live store-policy validation, and the privacy-policy generator turns those same declarations into a GDPR- and AMO-aligned policy — both run in your browser, no sign-up. Closer to shipping, @extenshi/cli (npx @extenshi/cli) scans the packaged build for permission and privacy red flags before AMO does: 5 scans a month are free, with prepaid packs past that.
What this means for the ecosystem
This is Mozilla pushing the extension ecosystem toward genuine transparency. Privacy policies are self-regulated legal documents. Manifest-level declarations are machine-readable, enforceable, and visible to users before they install. That's a meaningful difference.
For developers who are already privacy-conscious, this is mostly just documentation. For those who've been vague about their data practices... it's time to get specific.
You can check how your extension stacks up on privacy transparency by searching the Extenshi catalog — it's a good way to see how your extension compares to alternatives in your category.
This article is based on publicly available security research and news reporting. Extenshi does not independently verify all claims made by third-party researchers. References to specific companies or products reflect the findings of cited sources and do not constitute accusations of intentional wrongdoing. If you believe any information is inaccurate, please contact us at [email protected].
Related Articles
AI extension data collection explained: what your Chrome AI tools can really access
52% of AI Chrome extensions collect user data, a 2026 study found. Here's what permissions like scripting actually let them see and how to check yours.
declarativeNetRequest in browser extensions: what a peer-reviewed study says about MV3 ad blocking
A Goethe University study found MV3 ad blockers match MV2 effectiveness. Here's what declarativeNetRequest means for developers building content filters.
The `tabs` permission explained: what browser extensions can really see in your open tabs
The tabs permission lets Chrome extensions log every URL you visit in real time — no history permission needed. Here's what it does and how to audit yours.