Skip to main content

Overview

Microsoft Edge, Brave, Opera, Vivaldi, and Arc are all built on Chromium and all run Manifest V3 extensions. The browser extension ships one build, and that same build loads in each of them. There is no per-browser port and no second artifact. A browser being Chromium-based does not mean Beacon has tested it there. This page keeps the two claims apart: which browsers run in automated tests on every change, and which rely on the manual checklist below.

Support levels

The extension needs a browser built on Chromium 111 or newer, because its interceptor is declared as a main-world content script in the manifest.

Which browser an event came from

Every event the extension sends names the browser that produced it. On a managed fleet that matters: a paste into ChatGPT from the managed Edge profile and one from a personal Brave install are different investigations. The extension’s service worker reads the browser’s own UA Client Hints brand list (navigator.userAgentData.brands), falling back to the user-agent string, and sends OpenTelemetry semantic-convention attributes on every OTLP log: user_agent.name and user_agent.version are typed event fields. They are metadata rather than content, so they survive every retention mode, including metadata retention in the extension and Metadata-only managed forwarding, which drops raw. Threat rules can match on e.user_agent.name. To see the browser on recent events:
user_agent.name is what the browser claims to be. Some browsers do not name themselves: When a browser adds a brand Beacon does not know, that brand is reported as-is. When a browser gives neither brand hints nor a recognizable UA string, the attributes are omitted rather than guessed.

Install

Every Chromium browser uses the same archive, agent-beacon-browser-extension-<version>-chrome.zip, or a local dist/ build. The -chrome suffix names the Chromium extension family, not Google Chrome alone; the Firefox build ships separately as -firefox.xpi. See Use a release archive for download and verification. Load it unpacked from the browser’s extensions page, with developer mode turned on: Then choose Load unpacked and select the dist folder or the unzipped release folder, as described in Load it in Chrome. The extension is not published in any extension store yet. When it is, Brave, Vivaldi, and Arc install from the Chrome Web Store, Opera needs its own add-ons listing (or the user allows Chrome Web Store installs in Opera), and Edge needs its own Microsoft Edge Add-ons listing through Partner Center. No Edge Add-ons submission exists today.

Manual verification checklist

Use this for every browser the automated e2e does not cover, and record the result. Two passes: the replay e2e, which needs no login and no network, and a live check against the real sites.

1. Replay e2e against the browser binary

The Playwright harness accepts any Chromium-family binary through BROWSER_EXECUTABLE. It launches the browser with the built extension and replays recorded chat streams through it, which proves the extension loads, the interceptor fires, and delivery works in that browser.
Typical executable paths: On Windows, the path is the Target of the browser’s shortcut (right-click the shortcut, then Properties). BROWSER_CHANNEL selects a Playwright channel instead (chromium, the default, or msedge; pre-release variants such as msedge-beta also work). BROWSER_EXECUTABLE wins when both are set. A browser that ignores --load-extension, as branded Chrome does, fails every test at the first step, which is itself a useful result: skip to the live check.

2. Live check against the real sites

With the Beacon endpoint running:
  • Load the extension unpacked from the browser’s extensions page. It appears in the list, is enabled, and shows no errors.
  • The toolbar popup opens and shows capture on and a queue depth of 0.
  • Send one message on claude.ai. A claude_web event arrives in the runtime log.
  • Send one message on chatgpt.com. A chatgpt_web event arrives in the runtime log.
  • Both events carry user_agent.name. Note the value; see Which browser an event came from for what each browser should report.
  • No permission prompt about local network access appeared. The service worker console, from the extensions page, shows no delivery errors.
  • Quit and restart the browser. The extension is still enabled and the next message is still captured.
  • Browser-specific: in Brave, repeat one message with Shields up for the site; in Opera, confirm the extension is allowed on claude.ai and chatgpt.com; in Arc, check whether capture also works in a Space that uses a different profile, and record the answer.

3. Record the result

Add a row to the pull request or release notes that ran it:

Force-install through browser policy

For IT-managed fleets, Chromium browsers can install an extension without user action through the ExtensionInstallForcelist policy, or its successor ExtensionSettings with installation_mode: force_installed. Each browser reads that policy from its own location: Beacon has not verified an enterprise policy path for Opera, Vivaldi, or Arc. Check the vendor’s current enterprise documentation, and test on one machine, before relying on policy there. Each ExtensionInstallForcelist entry is <extension id>;<update URL>. Two things block force-install today:
  • There is no update URL to point at. The extension is not in the Chrome Web Store or Microsoft Edge Add-ons, and Beacon does not publish a signed .crx with an update manifest. Force-install needs one of those.
  • There is no stable extension ID. An unpacked extension’s ID is derived from the folder it was loaded from, because the manifest carries no key. A policy has nothing fixed to name until the extension is packaged with a key or listed in a store.
Until then, distribution is load-unpacked. Managed profiles can also block developer mode, which blocks Load unpacked. If your fleet does, allow developer mode for the profiles that should run the extension, or wait for a store listing.

Browser extension

Install, configuration, and troubleshooting.

Schema fields

Where user_agent sits in the event schema.