MonkeyLoader All articles
Infrastructure

A Script Shelf, Not a Script Free-for-All: Managed Helpers for UK Support Desks

MonkeyLoader
A Script Shelf, Not a Script Free-for-All: Managed Helpers for UK Support Desks

Photo: Diliff, CC BY-SA 3.0, via Wikimedia Commons

Support desks live in the gaps between systems. One tab has the case record; another has the order; a third has the parcel tracker that was last redesigned in 2019. The repetitive work is real: copy a reference, normalise a postcode, add a tag, paste a template. A userscript can save minutes per case. A free-for-all of userscripts can also become a support incident with a pulse.

MonkeyLoader's take: do not ban helpers, and do not let everyone install whatever they find. Build a small internal shelf. One managed browser extension, one signed manifest, a short allowlist, and a rollback button. No full app release for every tiny tweak.

Start with the allowlist, not the code

Before you write a helper, write down the domains where helpers are allowed to run. Keep it boring and exact: admin.example.co.uk, cases.example.co.uk, partner.example.co.uk. Not *.example.co.uk, and definitely not <all_urls>. The extension hardcodes this list. The signed manifest can only narrow it, never widen it. If someone adds a new admin portal, that is a code review and a new extension build, not a JSON edit at 4:55pm on a Friday.

On Windows estates, force-install the extension through Chrome Enterprise or Edge policies. Name it something obvious in the toolbar, like Helper Shelf. Support agents should know what it is, how to reload it, and who owns it. A mystery extension is how trust dies.

A manifest you can sign and pin

The extension fetches two files from an internal HTTPS bucket: manifest.json and manifest.sig. The manifest lists helper IDs, exact versions, packaged file names, match patterns and run timing. The signature is Ed25519. The public key lives in the extension; the private key stays in your admin console or, better, an HSM. If the signature does not verify, the extension ignores the manifest and falls back to the last good copy in chrome.storage.local.

Pin versions by file name. No latest.js, no CDN redirects, no 'fetch the newest thing from the wiki'. If a helper is at 1.3.0, the manifest says helpers/copy-case-ref-1.3.0.js. Keep the previous couple of versions inside the extension package so rollback is a manifest change, not a rebuild.

version: 7
issued: 2026-11-09T09:00:00Z
helpers:
  - id: copy-case-ref
    version: 1.3.0
    file: helpers/copy-case-ref-1.3.0.js
    matches: [https://admin.example.co.uk/*]

Each helper gets a one-line owner and an expiry date in the review record. If nobody owns it, it does not go on the shelf. That sounds bureaucratic; it is cheaper than discovering a helper in six months that quietly posts case notes to a dead Slack webhook.

Injecting without picking a fight with CSP

Most support helpers only need the DOM: find a button, add a badge, prefill a field, copy text to the clipboard. Run those in the extension's isolated world with chrome.scripting.registerContentScripts. The page keeps its CSP. You are not asking the dashboard to trust a new script origin, and you are not stuffing eval into a page that has spent years locking itself down.

Register only what the signed manifest allows and only on origins that passed the hardcoded allowlist. Unregister the old set before registering the new one. If a helper genuinely needs page globals, treat it as a separate review. It may need world: 'MAIN', a chat with the dashboard owner, and a test against the CSP. Most helpers should never get that far.

const allowed = new Set(['admin.example.co.uk', 'cases.example.co.uk']);
const scripts = manifest.helpers
  .filter(h => h.matches.every(isAllowed))
  .map(h => ({
    id: h.id,
    js: [h.file],
    matches: h.matches,
    runAt: h.runAt || 'document_idle',
    world: 'ISOLATED'
  }));
await chrome.scripting.unregisterContentScripts();
await chrome.scripting.registerContentScripts(scripts);

Rollback is a button, not a postmortem

Keep every signed manifest under an immutable key, for example manifests/2026-11-09T09-00Z.json. The current pointer is just another object. The admin console gets one button: 'Roll back to previous manifest'. It copies the previous signed manifest to current, and the extension picks it up on its next poll or when an agent clicks 'Reload helpers' in the popup. No extension rebuild, no waiting for a release train.

Version pinning makes this safe. If the previous manifest points at bulk-tag-0.9.2.js and that file is still in the package, rollback is instant. Test the rollback path before you need it. A rollback button that has never been pressed is just a rumour.

The bit that keeps it sane

Log every manifest fetch, verification failure and helper registration. Keep the logs short and searchable. When an agent says 'the copy button has gone weird', you want to know which helper version is live, not scroll through a year of browser console noise.

Finally, say no to a few requests. The shelf is for small, reversible support chores. If a helper starts needing secrets, personal data exports or a network call to a service nobody owns, it has outgrown the shelf. Put it in the app. That is not a failure of the loader; it is the loader doing its job.

All Articles

Related Articles

When the Registry Blinks: A Fallback Loader for UK Builds

When the Registry Blinks: A Fallback Loader for UK Builds

Edge Cases: Serving IE Mode a Legacy Bundle Without Punishing Everyone Else

Edge Cases: Serving IE Mode a Legacy Bundle Without Punishing Everyone Else

The Wrapper, the Pin and the Kill Switch: Extending Vendor Loaders You Cannot Fork

The Wrapper, the Pin and the Kill Switch: Extending Vendor Loaders You Cannot Fork