Browser extensionFirefox

Firefox

Deploy the AgentKeeper Firefox extension through Firefox enterprise policy. On Windows and Linux, a policies.json file on disk is enough. On macOS, use an MDM configuration profile because modern...

config profile (macOS) · policies.json (Windows · Linux)

Deploy the AgentKeeper Firefox extension through Firefox enterprise policy. On Windows and Linux, a policies.json file on disk is enough. On macOS, use an MDM configuration profile because modern macOS blocks writing the policy into the Firefox app bundle. See the macOS section below.

Prerequisites

  • Firefox deployed to managed machines
  • An org API key from Settings → Access → API keys (starts with ak_live_)

Firefox's extension ID is help@rad.security. The add-on is unlisted on AMO (not publicly listed), so the signed .xpi is self-hosted at https://www.agentkeeper.dev/downloads/firefox/ and referenced by the install_url below. Firefox auto-updates from updates.json in that directory, so you don't edit the policy on every release.

policies.json format

Drop a policies.json file in the Firefox distribution directory. Firefox reads it on startup and applies the policy to all profiles.

{
  "policies": {
    "ExtensionSettings": {
      "help@rad.security": {
        "installation_mode": "force_installed",
        "install_url": "https://www.agentkeeper.dev/downloads/firefox/agentkeeper-0.1.7.xpi"
      }
    },
    "3rdparty": {
      "Extensions": {
        "help@rad.security": {
          "orgApiKey": "ak_live_xxxxxxxx",
          "backendUrl": "https://www.agentkeeper.dev/api"
        }
      }
    }
  }
}

Replace ak_live_xxxxxxxx with your org API key (from Settings → Access → API keys).

Auto-update: The install_url is the self-hosted signed XPI for the current version, but the extension manifest carries an update_url pointing to https://www.agentkeeper.dev/downloads/firefox/updates.json. Firefox polls it and updates automatically. You do not need to push a new install_url to the fleet for every release.

Note on userEmail: A flat policies.json cannot substitute per-user variables, so leave userEmail blank there. User binding happens only at enrollment time. Browser installs are keyed by an internal ID that MDM sync never matches, so an unbound install is not fixed up later. To attribute a user, either rely on Chrome-style capture, where the extension reads the signed-in corporate email automatically, or use an MDM configuration profile for Firefox and set userEmail to $EMAIL (Apple MDM) or {{mail}} (Intune). The MDM substitutes this value per user before delivery. If all devices belong to one user, a static email also works.

policies.json file location (Windows / Linux)

OSPath
WindowsC:\Program Files\Mozilla Firefox\distribution\policies.json
Linux/usr/lib/firefox/distribution/policies.json or /etc/firefox/policies/policies.json

The distribution/ directory may not exist; create it if needed.

macOS: configuration profile (not policies.json)

On macOS, do not drop policies.json into Firefox.app/Contents/Resources/distribution/. Modern macOS blocks writes to the signed app bundle (Operation not permitted, even with sudo), and a Firefox update would remove the file. Deliver an MDM configuration profile for the org.mozilla.firefox preference domain instead.

The profile carries the same ExtensionSettings and 3rdparty keys shown above, plus one macOS-specific requirement:

EnterprisePoliciesEnabled must be true. Unlike policies.json, where presence alone activates policies, a macOS configuration profile leaves about:policies inactive without this key. The policy is read but never applied, and nothing installs.

A ready-to-edit template (with the $EMAIL per-user pattern and all the macOS gotchas documented inline) ships in the repo at extension/docs/firefox-enterprise.mobileconfig. Push it as a device-scoped profile via Jamf, Iru/Kandji, or Intune.

Deploying via MDM

macOS (Jamf / Iru/Kandji / Intune): Push the configuration profile (extension/docs/firefox-enterprise.mobileconfig) as a device-scoped profile, not a script that writes policies.json. The script fails on the protected app bundle.

Intune (Windows): Use a PowerShell script policy or package the policies.json as a Win32 app.

Linux (Jamf / Iru/Kandji / Intune / config management): Write policies.json to /etc/firefox/policies/policies.json via a script. Check for an existing file first to avoid overwriting other policies.

Example shell script (Linux only):

#!/bin/bash
DIST_DIR="/etc/firefox/policies"
mkdir -p "$DIST_DIR"

cat > "$DIST_DIR/policies.json" << 'EOF'
{
  "policies": {
    "ExtensionSettings": {
      "help@rad.security": {
        "installation_mode": "force_installed",
        "install_url": "https://www.agentkeeper.dev/downloads/firefox/agentkeeper-0.1.7.xpi"
      }
    },
    "3rdparty": {
      "Extensions": {
        "help@rad.security": {
          "orgApiKey": "ak_live_xxxxxxxx",
          "backendUrl": "https://www.agentkeeper.dev/api"
        }
      }
    }
  }
}
EOF

Verifying the rollout

On a managed machine after Firefox restarts:

  1. Open about:policies. Confirm ExtensionSettings shows the AgentKeeper entry.
  2. Open about:addons. AgentKeeper shows "Installed by your organization" and cannot be removed.
  3. Extension popup reads "Paired".

See Verifying deployment for the full checklist.