Deploying the CrowdStrike AIDR Browser Extension via Falcon for IT

Using Falcon for IT to deploy the CrowdStrike AIDR browser collector across Edge, Chrome, and Firefox Developer Edition — writing browser policies directly on endpoints via the Falcon sensor without standing up a parallel MDM deployment.


Background

CrowdStrike AIDR (AI-powered Detection and Response) includes a browser collector extension that provides visibility into browser-based activity. Unlike the DLP and IDP extensions, which can be deployed directly via a Falcon sensor policy, the AIDR extension currently has no native sensor policy deployment option. With broader rollout on the roadmap, we needed a way to test the extension across our environment before that capability becomes available.

Rather than standing up a parallel MDM deployment just for this, we leveraged Falcon for IT — using its PowerShell and Zsh script execution capabilities to write the necessary browser policies directly on endpoints where the Falcon sensor was already running.


The Approach

Each browser has its own policy mechanism for force-installing and pre-configuring extensions. The goal for each was the same: silently install the AIDR extension and pre-populate its managed storage with the configuration values it needs to register with the AIDR service — without any user interaction.

The four values written to each browser’s managed storage are:

Key Value
registrationIdentity Encrypted token used to register the browser with AIDR
urlTemplate AIDR service endpoint
userId The logged-in username
userFullName COMPUTERNAME\username

Microsoft Edge

Edge was the most straightforward of the three. It uses Chromium’s ExtensionSettings registry key under HKLM:\SOFTWARE\Policies\Microsoft\Edge\ to both force-install extensions and configure their managed storage.

A single PowerShell script handles both steps:

  1. Write the installation_mode: force_installed and update_url values under the ExtensionSettings key for the extension ID
  2. Write the four managed storage values under the 3rdparty\extensions\<ID>\policy registry path

The script runs as SYSTEM in a 64-bit PowerShell host via Falcon for IT, and the extension appears in Edge as a managed extension after the browser restarts.

 1# Edge AIDR Extension - Full Deployment Script
 2# Run as: SYSTEM, 64-bit PowerShell
 3$ErrorActionPreference = "Stop"
 4
 5try {
 6    # ─────────────────────────────────────────────
 7    # PART 1: Force-install the extension via policy
 8    # ─────────────────────────────────────────────
 9    $extensionID = "folndgmoekgkipoolphnkclopeopkecc"
10    $policyPath = "HKLM:\SOFTWARE\Policies\Microsoft\Edge\ExtensionSettings\$extensionID"
11
12    if (-not (Test-Path $policyPath)) {
13        New-Item -Path $policyPath -Force | Out-Null
14    }
15
16    New-ItemProperty -Path $policyPath -Name "installation_mode" -Value "force_installed" -PropertyType String -Force | Out-Null
17    New-ItemProperty -Path $policyPath -Name "update_url" -Value "https://edge.microsoft.com/extensionwebstorebase/v1/crx" -PropertyType String -Force | Out-Null
18
19    Write-Output "Part 1 complete: Extension policy set"
20
21    # ─────────────────────────────────────────────
22    # PART 2: Configure managed storage
23    # ─────────────────────────────────────────────
24    $storagePath = "HKLM:\Software\Policies\Microsoft\Edge\3rdparty\extensions\$extensionID\policy"
25
26    if (-not (Test-Path $storagePath)) {
27        New-Item -Path $storagePath -Force | Out-Null
28    }
29
30    Set-ItemProperty -Path $storagePath -Name "registrationIdentity" `
31        -Value "<Your registrationIdentity here>" `
32        -Type String -Force
33
34    Set-ItemProperty -Path $storagePath -Name "urlTemplate" `
35        -Value "https://api.crowdstrike.com/aidr/aiguard" `
36        -Type String -Force
37
38    New-ItemProperty -Path $storagePath -Name "userId" `
39        -Value "%USERNAME%" -PropertyType ExpandString -Force | Out-Null
40
41    New-ItemProperty -Path $storagePath -Name "userFullName" `
42        -Value "%COMPUTERNAME%\%USERNAME%" -PropertyType ExpandString -Force | Out-Null
43
44    # ─────────────────────────────────────────────
45    # PART 3: Verify
46    # ─────────────────────────────────────────────
47    $policy = Get-ItemProperty -Path $policyPath
48    $storage = Get-ItemProperty -Path $storagePath
49
50    Write-Output "Part 2 complete: Managed storage configured"
51    Write-Output ""
52    Write-Output "=== Verification ==="
53    Write-Output "Extension ID:          $extensionID"
54    Write-Output "Installation mode:     $($policy.installation_mode)"
55    Write-Output "Update URL:            $($policy.update_url)"
56    Write-Output "urlTemplate:           $($storage.urlTemplate)"
57    Write-Output "userId:                $($storage.userId)"
58    Write-Output "userFullName:          $($storage.userFullName)"
59    Write-Output "registrationIdentity:  Set"
60    Write-Output ""
61    Write-Output "Deployment complete. Restart Edge for changes to take effect."
62
63    Exit 0
64
65} catch {
66    Write-Error "Deployment failed: $($_.Exception.Message)"
67    Exit 1
68}

Verification: edge://extensions and edge://policy


Google Chrome

Chrome’s deployment is nearly identical to Edge, with two differences:

  • Registry paths use Google\Chrome instead of Microsoft\Edge
  • The force-install mechanism uses Chrome’s numbered ExtensionInstallForcelist format (integer-indexed values: 1, 2, 3…) rather than the ExtensionSettings key

The script detects the next available index in the forcelist automatically, so it won’t overwrite any existing force-installed extensions.

One issue we hit early on was curly/typographic quote characters (" ") in the PowerShell Write-Output lines causing a script parsing exception in Falcon for IT. PowerShell only recognizes straight ASCII quotes (") as string delimiters — something to watch for when copying scripts from a browser or document editor.

 1# Chrome AIDR Extension - Full Deployment Script
 2# Run as: SYSTEM, 64-bit PowerShell
 3$ErrorActionPreference = "Stop"
 4
 5try {
 6    # ─────────────────────────────────────────────
 7    # PART 1: Force-install the extension via policy
 8    # ─────────────────────────────────────────────
 9    $extensionID = "folndgmoekgkipoolphnkclopeopkecc"
10    $policyPath = "HKLM:\SOFTWARE\Policies\Google\Chrome\ExtensionInstallForcelist"
11
12    if (-not (Test-Path $policyPath)) {
13        New-Item -Path $policyPath -Force | Out-Null
14    }
15
16    # Find the next available numbered value
17    $existing = Get-ItemProperty -Path $policyPath -ErrorAction SilentlyContinue
18    $nextIndex = 1
19    while ($existing.PSObject.Properties.Name -contains "$nextIndex") {
20        $nextIndex++
21    }
22
23    New-ItemProperty -Path $policyPath -Name "$nextIndex" `
24        -Value "$extensionID;https://clients2.google.com/service/update2/crx" `
25        -PropertyType String -Force | Out-Null
26
27    Write-Output "Part 1 complete: Extension force-install policy set (index $nextIndex)"
28
29    # ─────────────────────────────────────────────
30    # PART 2: Configure managed storage
31    # ─────────────────────────────────────────────
32    $storagePath = "HKLM:\Software\Policies\Google\Chrome\3rdparty\extensions\$extensionID\policy"
33
34    if (-not (Test-Path $storagePath)) {
35        New-Item -Path $storagePath -Force | Out-Null
36    }
37
38    Set-ItemProperty -Path $storagePath -Name "registrationIdentity" `
39        -Value "<Your registrationIdentity here>" `
40        -Type String -Force
41
42    Set-ItemProperty -Path $storagePath -Name "urlTemplate" `
43        -Value "https://api.crowdstrike.com/aidr/aiguard" `
44        -Type String -Force
45
46    New-ItemProperty -Path $storagePath -Name "userId" `
47        -Value "%USERNAME%" -PropertyType ExpandString -Force | Out-Null
48
49    New-ItemProperty -Path $storagePath -Name "userFullName" `
50        -Value "%COMPUTERNAME%\%USERNAME%" -PropertyType ExpandString -Force | Out-Null
51
52    # ─────────────────────────────────────────────
53    # PART 3: Verify
54    # ─────────────────────────────────────────────
55    $storage = Get-ItemProperty -Path $storagePath
56
57    Write-Output "Part 2 complete: Managed storage configured"
58    Write-Output ""
59    Write-Output "=== Verification ==="
60    Write-Output "Extension ID:         $extensionID"
61    Write-Output "Force-install index:  $nextIndex"
62    Write-Output "urlTemplate:          $($storage.urlTemplate)"
63    Write-Output "userId:               $($storage.userId)"
64    Write-Output "userFullName:         $($storage.userFullName)"
65    Write-Output "registrationIdentity: Set"
66    Write-Output ""
67    Write-Output "Deployment complete. Restart Chrome for changes to take effect."
68
69    Exit 0
70
71} catch {
72    Write-Error "Deployment failed: $($_.Exception.Message)"
73    Exit 1
74}

Verification: chrome://extensions and chrome://policy


Firefox Developer Edition

Firefox was the most involved of the three, for a few reasons.

Policy Delivery

Firefox doesn’t use the Windows registry for extension force-installation in the same way Chrome and Edge do. Instead, it reads from a policies.json file placed in a distribution folder inside the Firefox install directory. For Developer Edition specifically, we write this file to:

C:\Program Files\Firefox Developer Edition\distribution\policies.json

The ExtensionSettings JSON inside that file tells Firefox to force-install the extension from a remote XPI URL.

Managed storage is still handled via the registry at HKLM:\Software\Policies\Mozilla\Firefox\3rdparty\Extensions\<ID>\, which works the same as standard Firefox.

The XPI Download Problem

After getting the policies in place, the extension still wasn’t installing. Checking about:policies confirmed the policy was being read correctly, which pointed to the download itself failing. Testing the XPI URL directly in Firefox produced a connection failure — but the same URL worked fine in Edge on the same machine.

The root cause: our proxy was performing SSL inspection, and Firefox — unlike Edge — does not automatically trust the Windows certificate store, so it was aborting the TLS connection when it saw the proxy’s inspection certificate instead of the expected certificate from pangea.cloud.

The fix was adding ImportEnterpriseRoots: true to the policies.json, which instructs Firefox to trust the Windows certificate store (and by extension, the proxy’s inspection certificate):

 1{
 2  "policies": {
 3    "ImportEnterpriseRoots": true,
 4    "ExtensionSettings": {
 5      "[email protected]": {
 6        "installation_mode": "force_installed",
 7        "install_url": "https://pangea.cloud/firefox-aidr-extension/aidr-extension-latest.xpi"
 8      }
 9    }
10  }
11}

The BOM Problem

The next issue was a JSON parse error in Firefox: SyntaxError: JSON.parse: unexpected character at line 1 column 1. This was caused by PowerShell’s Set-Content -Encoding UTF8 writing a UTF-8 BOM (byte order mark) at the start of the file — a character Firefox’s JSON parser doesn’t tolerate.

The fix was switching to .NET’s UTF8Encoding class with the BOM explicitly disabled:

1[System.IO.File]::WriteAllText(
2    "$distributionDir\policies.json",
3    $policiesJson,
4    [System.Text.UTF8Encoding]::new($false)
5)

After both fixes, the extension installed successfully on restart. Here is the final working script:

  1# Firefox Developer Edition AIDR Extension - Full Deployment Script
  2# Run as: SYSTEM, 64-bit PowerShell
  3$ErrorActionPreference = "Stop"
  4
  5try {
  6    $extensionID = "[email protected]"
  7    $installURL = "https://pangea.cloud/firefox-aidr-extension/aidr-extension-latest.xpi"
  8
  9    # ─────────────────────────────────────────────
 10    # PART 1: Force-install via policies.json
 11    # ─────────────────────────────────────────────
 12    Write-Output "Part 1: Writing policies.json..."
 13
 14    $devEditionPaths = @(
 15        "$env:ProgramFiles\Firefox Developer Edition",
 16        "${env:ProgramFiles(x86)}\Firefox Developer Edition"
 17    )
 18
 19    $installDir = $null
 20    foreach ($path in $devEditionPaths) {
 21        if (Test-Path $path) {
 22            $installDir = $path
 23            break
 24        }
 25    }
 26
 27    if (-not $installDir) {
 28        throw "Firefox Developer Edition install directory not found. Is it installed?"
 29    }
 30
 31    Write-Output "  Found Dev Edition at: $installDir"
 32
 33    $distributionDir = Join-Path $installDir "distribution"
 34    if (-not (Test-Path $distributionDir)) {
 35        New-Item -Path $distributionDir -ItemType Directory -Force | Out-Null
 36    }
 37
 38    $policiesJson = @"
 39{
 40  "policies": {
 41    "ImportEnterpriseRoots": true,
 42    "ExtensionSettings": {
 43      "$extensionID": {
 44        "installation_mode": "force_installed",
 45        "install_url": "$installURL"
 46      }
 47    }
 48  }
 49}
 50"@
 51
 52    # Write BOM-free UTF-8 — Firefox JSON parser rejects files with a BOM
 53    [System.IO.File]::WriteAllText("$distributionDir\policies.json", $policiesJson, [System.Text.UTF8Encoding]::new($false))
 54    Write-Output "  Written: $distributionDir\policies.json"
 55    Write-Output "Part 1 complete."
 56
 57    # ─────────────────────────────────────────────
 58    # PART 2: Configure managed storage via registry
 59    # ─────────────────────────────────────────────
 60    Write-Output ""
 61    Write-Output "Part 2: Configuring managed storage..."
 62
 63    $storagePath = "HKLM:\Software\Policies\Mozilla\Firefox\3rdparty\Extensions\$extensionID"
 64
 65    if (-not (Test-Path $storagePath)) {
 66        New-Item -Path $storagePath -Force | Out-Null
 67    }
 68
 69    Set-ItemProperty -Path $storagePath -Name "registrationIdentity" `
 70        -Value "<Your registrationIdentity here>" `
 71        -Type String -Force
 72
 73    Set-ItemProperty -Path $storagePath -Name "urlTemplate" `
 74        -Value "https://api.crowdstrike.com/aidr/aiguard" `
 75        -Type String -Force
 76
 77    New-ItemProperty -Path $storagePath -Name "userId" `
 78        -Value "%USERNAME%" -PropertyType ExpandString -Force | Out-Null
 79
 80    New-ItemProperty -Path $storagePath -Name "userFullName" `
 81        -Value "%COMPUTERNAME%\%USERNAME%" -PropertyType ExpandString -Force | Out-Null
 82
 83    Write-Output "Part 2 complete."
 84
 85    # ─────────────────────────────────────────────
 86    # PART 3: Verify
 87    # ─────────────────────────────────────────────
 88    $storage = Get-ItemProperty -Path $storagePath
 89    $policiesContent = Get-Content "$distributionDir\policies.json" -Raw
 90
 91    Write-Output ""
 92    Write-Output "=== Verification ==="
 93    Write-Output "Install directory:    $installDir"
 94    Write-Output "policies.json:        $distributionDir\policies.json"
 95    Write-Output "urlTemplate:          $($storage.urlTemplate)"
 96    Write-Output "userId:               $($storage.userId)"
 97    Write-Output "userFullName:         $($storage.userFullName)"
 98    Write-Output "registrationIdentity: Set"
 99    Write-Output ""
100    Write-Output "policies.json contents:"
101    Write-Output $policiesContent
102    Write-Output ""
103    Write-Output "Deployment complete. Restart Firefox Developer Edition for changes to take effect."
104
105    Exit 0
106
107} catch {
108    Write-Error "Deployment failed: $($_.Exception.Message)"
109    Exit 1
110}

Verification: about:addons and about:policies


macOS — What We Tried

We also attempted to deploy the Chrome extension on managed Macs using Falcon for IT’s Zsh script execution. On macOS, Chrome policy is delivered via plist files written to /Library/Managed Preferences/ — one for the force-install list (com.google.Chrome.plist) and one for the extension’s managed storage (com.google.Chrome.extensions.<ID>.plist).

The scripts ran successfully as root and the plist files were written correctly to disk, but chrome://policy remained empty. The reason: the Mac endpoints are MDM-enrolled, and Chrome on MDM-enrolled Macs only trusts policies delivered through the MDM profile channel. Flat plist files written directly to disk — regardless of ownership or permissions — are ignored.

For macOS, the correct deployment path is through the MDM (in our case, Jamf), which delivers signed configuration profiles that Chrome trusts. Falcon for IT is well suited for the Windows side of this deployment; Jamf handles Mac.


Summary

Browser Platform Method Notes
Microsoft Edge Windows Registry (ExtensionSettings) Straightforward, single script
Google Chrome Windows Registry (ExtensionInstallForcelist) Watch for quote encoding issues
Firefox Dev Edition Windows policies.json + Registry Needed ImportEnterpriseRoots and BOM-free UTF-8
Google Chrome macOS Attempted via plist MDM-enrolled Macs require Jamf profile delivery

This approach gave us a working AIDR browser extension deployment across our Windows fleet using infrastructure we already had, without waiting for native sensor policy support to arrive. When that capability does land in Falcon, migrating will be straightforward — the configuration values are already known and tested.