The browser extension
Getting data in
Packing it, hosting it, and rolling it out.
The browser is where most people meet an AI tool, and it is the one surface a
collector cannot read. Somebody signed into ChatGPT with a personal Gmail
address leaves nothing on disk for a script to find. The extension does two
jobs on the pages of tools the registry knows about.
Account detection. It resolves the signed-in account, throws away the
local part of the address immediately, and reports the domain if it is not on
your corporate list. The domain, never the mailbox.
The paste guard. It intercepts paste and drop before the content reaches
the page, scans it on the machine for secret patterns and document
classification markings, and warns or blocks. What it reports is a list of
detector ids. The pasted text never leaves the machine - it is not sent to
the extension's own service worker, let alone to your receiver.
What the paste guard looks for
Secret formats: AWS keys, private keys, GitLab, GitHub, Anthropic, OpenAI,
Slack and Google tokens, Azure storage secrets, JWTs. Marketing platform
credentials: Stripe live keys, Mailchimp, HubSpot, SendGrid, Meta tokens.
Password assignments. Payment card numbers, Luhn validated. UK National
Insurance numbers. IBANs. Bulk email lists, meaning ten or more distinct
addresses in one paste. And document classification markings.
The markings are the interesting one if you hold ISO 27001 or 42001. The
labels come from managed configuration, so your own classification policy
becomes something enforced at the paste boundary rather than something
written down. A compound label such as "Client Confidential" matches whatever
the case; a bare CONFIDENTIAL matches only in capitals, so the disclaimer
footer on every email in your organisation stays quiet.
Some things are deliberately not detected, because the false-positive rate
would teach people to dismiss the overlay without reading it: UK sort codes,
which are indistinguishable from dd-mm-yy dates; dates of birth; passport and
driving licence numbers; a single email address.
In warn mode somebody can go ahead with a "Paste anyway" button, and that
override is itself reported. In block mode they cannot. The mode is managed
configuration, so moving a fleet from warn to block is a policy push rather
than a release.
Why it is not in a web store
You pack it and deploy it yourself, through enterprise browser policy. A
store listing would mean a public extension with your receiver's address in
it, and a review queue between you and a fix.
The cost of that is a one-time setup: pack, host, push policy. After that,
day-to-day changes - the paste guard's mode, your corporate domains, a new
enrollment token - are policy pushes, and a new release is pack, upload,
done.
Start in the portal
Administration > Extension setup walks the whole flow one page at a time.
It serves the extension's source with your receiver origin already in the
manifest, generates every policy file pre-configured, and probes your hosting
to tell you whether what you uploaded is actually there.
It generates the full policy matrix: the Chromium managed-storage plist for
macOS, the Windows deploy scripts for Chromium and Firefox, and the Firefox
install-and-configure plist for macOS - each with your receiver URL, a fresh
enrollment token, your corporate domains and the paste guard settings baked
in. What it cannot work out for itself it asks you for: the Chromium
extension id, which only exists once you have packed it, the Firefox gecko
id, and the URLs you are hosting on.
The rest of this page is the same ground in writing, for reading before you
start, or for a rollout the portal's pre-configured download does not suit.
The five steps
Point the source at your receiver. One line in the manifest; the
portal's download has it done already. Without it, the report is blocked
by CORS and you get an extension that detects everything and reports
nothing.Pack it. In Chrome,
chrome://extensions, Developer mode, Pack
extension, with the source directory and a blank private key on the first
pack. You get a.crxand a.pem.Host the packed file and its update manifest anywhere on HTTPS.
Push the policies through your MDM or GPO.
Verify on one machine before the fleet.
The signing key
The .pem from step 2 is the signing key. Put it in your password manager
and never commit it. Losing it changes the extension's id, and a changed
id means every browser in the fleet treats it as a different extension: a
full redeployment, not an update.
Pin the key into the manifest as well, so the id stays the same across
repacks and local loads:
Hosting
Put the versioned .crx and your updates.xml on public HTTPS. An S3 bucket
is fine. Grant public read with a wildcard resource on the bucket, not
per object - grant it per object and every release you upload afterwards
starts life private, which looks exactly like a browser that has stopped
updating. Check both URLs return 200 before you push any policy.
Firefox needs the same files in its own formats: a Mozilla-signed .xpi andfirefox-updates.json. The two browsers do not share an update manifest, so
a release that covers both means updating two files. Serve the .crx asapplication/x-chrome-extension and the .xpi as application/x-xpinstall.
Policy
On macOS each Chromium browser takes two plists, and it needs both. The
forcelist entry installs the extension; the ExtensionSettings entry withoverride_update_url is what keeps the browser polling your update manifest
afterwards. One without the other gives you an extension that installs once
and never updates, or one that is configured but not installed - either way,
an extension that reports nothing.
Because the extension reads no central configuration, changing the receiver
URL, the domains or the paste guard's mode means regenerating the policy
files and pushing them again.
Checking it works
On one machine, after the policy lands: open a tool the registry knows, check
the extension is present and enabled, and look for the device under Discovery
Tools. Then paste something harmless that matches a detector - a fake AWS
key is the usual choice - and confirm the overlay appears and the finding
arrives under Governance > Paste guard.
What happens when the receiver is unreachable
Protection carries on regardless. The guard warns and blocks locally whether
or not anything can be recorded.
Reporting is handled differently for the two kinds of finding, because they
are different kinds of fact. An account flag can be worked out again, so a
refused report is picked up by the next check a few minutes later. A
paste cannot - it happened once - so a refused paste finding goes into a
bounded queue on the machine, capped at 100 events and seven days, oldest
dropped first, and is retried on a timer, at browser startup and alongside
the daily heartbeat. The queue holds the same content-free fields that would
have been posted: tool, surface, source, severity, detector ids, and when it
happened. The pasted text is not in it, because the pasted text never got
that far.