Blog

Self-hosting Chrome extensions in 2022 and beyond

Published Jun 21, 2022

When I made my first ex­ten­sion back in ye olden days - in the times of 30°C sum­mers and $1.5 Costco hot dog meals - Google al­lowed de­vel­op­ers to self-​host Chrome ex­ten­sions. This al­lowed users to in­stall ex­ten­sions di­rectly from their web­site, with­out hav­ing to go through the Chrome Web Store.

But as with all good things, a few bad ap­ples spoil it for the rest of us. By al­low­ing users to in­stall ex­ten­sions from any­where, Google didn’t have any con­trol over what ex­ten­sions were al­lowed. This made ex­ten­sions a prime tar­get for mal­ware and search hi­jack­ing, with no way to re­voke bad ex­ten­sions once they were out there. In its con­tin­u­ous quest to pro­tect users (… and maybe gain a bit of con­trol over their ecosys­tem. It is Google, after all), Google blocked in­stal­la­tion of ex­ten­sions from out­side the Web Store on all other plat­forms than Linux.

The block is pretty ex­ten­sive. If you try to in­stall an ex­ten­sion by sim­ply fol­low­ing a link, as you used to be able to, you’ll be met with a CRX_REQUIRED_PROOF_MISSING error with no way to by­pass it:

Screenshot of the CRX_REQUIRED_PROOF_MISSING error

If you man­u­ally down­load the .crx and drag it onto the chrome://extensions page you’ll get a bit fur­ther - you’ll even be able to in­stall it! Im­me­di­ately upon in­stalling it, how­ever, you’ll be met with an error and the ex­ten­sion will be hard-​disabled:

Screenshot of the hard-disabled extension

This is a bit prob­lem­atic for a small num­ber of use cases. I re­cently ran into a sit­u­a­tion where I wanted to in­stall an ex­ten­sion on com­put­ers in an or­ga­ni­za­tion, with­out ac­cess to the great big In­ter­net. With no way to reach the Chrome Web Store, down­load­ing the ex­ten­sion from there was a no-go.

Luck­ily Google has left one pos­si­bil­ity open. In ad­di­tion to load­ing the ex­ten­sion un­packed (which re­quires a lot of tech­ni­cal work from the user, and doesn’t sup­port auto-​updating) there is one more way to in­stall self-​hosted ex­ten­sions in Chrome that still works: en­ter­prise poli­cies.

For the pur­pose of self-​hosting ex­ten­sions, the fol­low­ing poli­cies are rel­e­vant:

Ex­ten­sion­In­stall­Sources

Lists the do­mains from which ex­ten­sion in­stal­la­tions are al­lowed. Note that both the host do­main (where the .crx is fetched from) and the re­fer­rer do­main (where the link to the .crx is clicked from) must be added.
The value is a list of strings, with each entry spec­i­fy­ing an al­lowed do­main using a match pat­tern

Ex­ten­sion­In­stal­lAl­lowlist

Lists the spe­cific ex­ten­sions that can be in­stalled. The value is a list of strings, with each entry being the ID of an al­lowed ex­ten­sion.

In order for an ex­ten­sion to be in­stal­lable, it must be per­mit­ted by both of those poli­cies. In ad­di­tion to this, the usual host­ing re­quire­ments must be met (namely serv­ing the .crx with Content-Type: application/x-chrome-extension).

This means that an ex­ten­sion hosted at https://jfagerberg.me/extension.crx, being linked to by https://example.com, with the ex­ten­sion ID aaaaaaaabbbbbbbbccccccccdddddddd, can be in­stalled by any user that has the fol­low­ing reg­istry file in­stalled, or has the cor­re­spond­ing group poli­cies:

[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome]
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome\ExtensionInstallSources]
"1"="https://example.com/*"
"2"="https://jfagerberg.me/*"
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome\ExtensionInstallAllowlist]
"1"="aaaaaaaabbbbbbbbccccccccdddddddd"

This is, as far as I am aware, the only way to self-​host ex­ten­sions in mod­ern Chrome.