Skip to main content

Configuring policies.json for Enterprise Firefox Deployments

 Securing web browsers across thousands of corporate endpoints is a critical mandate for modern IT infrastructure. Left unmanaged, browsers become a primary vector for data exfiltration, shadow IT via rogue extensions, and unauthorized telemetry collection. System administrators require a deterministic, programmable method to enforce security baselines.

For cross-platform Endpoint management, Mozilla provides a native policy engine driven by a single configuration file: policies.json. This approach replaces legacy, brittle JavaScript-based AutoConfig setups (mozilla.cfg), offering a standardized, OS-agnostic method to lock down preferences, deploy internal extensions, and strictly disable telemetry Firefox instances might otherwise broadcast.

The Architecture of Firefox Policy Evaluation

Understanding how Firefox evaluates configurations is essential for predictable Firefox Enterprise deployment. When the Firefox executable initializes, it constructs its preference tree from multiple sources in a strict hierarchical order.

Historically, administrators relied on modifying about:config parameters via autoconfig.js. This method required manual JavaScript parsing at runtime, which was prone to silent failures during browser updates. Furthermore, while Mobile Device Management (MDM) tools and Windows Group Policy Objects (GPO) are effective, they are inherently tied to specific operating systems.

The introduction of the Mozilla Policy Engine standardizes this by reading a structured JSON file at boot. Before the browser interface renders or the user profile loads, the engine scans the installation directory for policies.json. If valid, these policies are injected directly into the default preference tree. Because this evaluation happens at the application level, a single policies.json payload can be distributed via Chef, Ansible, Jamf, or SCCM across Windows, Linux, and macOS environments with identical results.

Implementing the policies.json Configuration

To enforce a baseline configuration, administrators must create a policies.json file and distribute it to the correct distribution directory on the target machines.

1. Identify the Target Directory

The file must be placed in a specific path relative to the Firefox binary. Create the distribution folder if it does not already exist.

  • Windows: C:\Program Files\Mozilla Firefox\distribution\policies.json
  • macOS: /Applications/Firefox.app/Contents/Resources/distribution/policies.json
  • Linux: /etc/firefox/policies/policies.json (or /usr/lib/firefox/distribution/policies.json)

2. The Configuration Payload

Below is a production-ready policies.json configuration designed for stringent endpoint security. This payload enforces an extension allowlist, disables data collection, prevents users from saving passwords locally, and disables DNS-over-HTTPS (DoH) to ensure internal DNS resolution functions correctly.

{
  "policies": {
    "DisableAppUpdate": true,
    "DisableTelemetry": true,
    "DisableFirefoxStudies": true,
    "DisablePocket": true,
    "DontCheckDefaultBrowser": true,
    "OfferToSaveLogins": false,
    "PasswordManagerEnabled": false,
    "ExtensionSettings": {
      "*": {
        "installation_mode": "blocked",
        "blocked_install_message": "Unauthorized extensions are blocked by IT Security."
      },
      "uBlock0@raymondhill.net": {
        "installation_mode": "force_installed",
        "install_url": "https://addons.mozilla.org/firefox/downloads/latest/ublock-origin/latest.xpi"
      },
      "internal-auth-tool@corp.local": {
        "installation_mode": "force_installed",
        "install_url": "https://intranet.corp.local/deploy/extensions/internal-auth-tool.xpi"
      }
    },
    "Preferences": {
      "network.trr.mode": {
        "Value": 5,
        "Status": "locked"
      },
      "browser.newtabpage.activity-stream.feeds.telemetry": {
        "Value": false,
        "Status": "locked"
      }
    }
  }
}

Deep Dive: How the Configuration Works

The configuration file is divided into high-level policy definitions and granular preference locks.

Telemetry and Data Collection

The directive "DisableTelemetry": true is the explicit toggle to disable telemetry Firefox generates. However, a comprehensive security posture requires disabling related subsystems. "DisableFirefoxStudies": true prevents Mozilla from silently installing A/B testing components (Shield Studies) on corporate machines. The additional preference lock on browser.newtabpage.activity-stream.feeds.telemetry ensures that even new tab interactions are stripped of tracking code.

ExtensionSettings and The Allowlist Pattern

The ExtensionSettings block utilizes a zero-trust model for browser add-ons.

  1. The "*" key acts as a wildcard, targeting all extensions. Setting its installation_mode to blocked immediately restricts users from installing unapproved tools from the Mozilla Add-ons store.
  2. Specific extension IDs (e.g., uBlock0@raymondhill.net) override the wildcard. Setting their mode to force_installed alongside an install_url instructs Firefox to download and install the .xpi file silently at startup without user interaction.
  3. Self-hosted extensions (like internal-auth-tool@corp.local) can be sideloaded directly from internal web servers, bypassing the public extension store entirely.

Granular Preference Locking

The Preferences block allows administrators to map underlying about:config flags that do not have top-level policy equivalents. By setting "network.trr.mode" to 5 and declaring its status as "locked", the configuration explicitly disables Trusted Recursive Resolver (DNS-over-HTTPS). This is a critical step in corporate environments where DoH can bypass internal DNS sinkholes, split-horizon DNS, or network-level content filtering.

Common Pitfalls and Edge Cases

Silent Failures Due to JSON Syntax

The Mozilla Policy Engine utilizes a strict JSON parser. Unlike JavaScript, JSON does not tolerate trailing commas, unquoted keys, or single quotes. If a single syntax error exists within policies.json, Firefox will completely ignore the file and load with default settings, presenting a significant security risk.

The Fix: Administrators should validate the JSON payload as part of their CI/CD pipeline before deploying it via Endpoint management software. Additionally, IT support can type about:policies#errors into the Firefox URL bar on a client machine to view exact parsing errors and line numbers.

OS Policy Precedence

When utilizing a hybrid management strategy, administrators must understand precedence. If a Windows Group Policy (GPO) or macOS Configuration Profile (via MDM) conflicts with policies.json, the OS-level policy will always take priority. policies.json is evaluated last. It is highly recommended to choose a single source of truth—either pure OS-level management or exclusively policies.json—to prevent configuration drift.

Sideloading Extension Signatures

When utilizing force_installed for internal extensions, the .xpi file must still be cryptographically signed by Mozilla. Unsigned extensions will fail to install silently, even if explicitly defined in policies.json, unless the organization is utilizing the unbranded Firefox Extended Support Release (ESR) build and sets xpinstall.signatures.required to false.

Streamlining Enterprise Deployment

Leveraging policies.json configuration abstracts the complexity of browser lockdown into a highly readable, version-controllable format. By enforcing strict JSON configurations, DevOps and IT teams guarantee that every Firefox instance initializes in a secure, telemetry-free state, complete with the specific tooling required for internal corporate workflows.