on
Deploying custom Chrome Extensions via Group Policy
Recently, reecetech (more accurately, a hackathon project gone wild) had a requirement to deploy an internally written Google Chrome Extension to our fleet of Windows clients. Unfortunately, the documentation for doing this is poor to say the least, and Google strongly discourage the publication of Chrome Extensions except via their store for security reasons. So, here goes – a guide to deploying an internal-only Chrome Extension to Windows Computers via Group Policy.
Prerequisites
- A Google Chrome extension you wish to publish internally
- An Active Directory domain, with all target computers joined to this domain
- A web server
Note: this was tested against Google Chrome 76 version. Your mileage may vary!
A little bit more about Chrome Extensions
Chrome Extensions are, at their core, a manifest.json
file that is packaged into a CRX file. When cryptographically signed and packaged into a CRX file, they generate a unique ‘Extension ID’ along the lines of ghbmnnjooekpmoecnnnilnnbdlolhkhi
.
By default, Chrome will only permit installation of extensions that have been cryptographically signed by Google, and the only way to get signed by Google is to submit to the Chrome Store. In earlier versions of Chrome, this was not required and one could install any CRX file by just dragging it into the browser, however this is not the case any more. Indeed, on macOS and non-Active Directory domain-joined Windows computers, it is not possible (as far as I am aware) to install a CRX file from anywhere except the Chrome Store.
Preparing your Extension for distribution
- Determine where your extension will be deployed from, and where the update manifest (an XML file that will be explained later) will be hosted. This must be a web server, preferably secured by TLS. In this example, the update manifest is at
https://corp.example.com/service/chrome_extension/update.xml
, and any updates will be served fromhttps://corp.example.com/service/chrome_extension/v0.0.1.crx
. - Update your extension’s
manifest.json
to include:
{
...
"update_url": "https://corp.example.com/service/chrome_extension/update.xml",
...
}
- In Chrome, pack your extension using ‘Developer mode’. If you have not already done this, a private signing key in
PEM
format will also be generated. You must save this key in a safe place as it will be required for any future updates to your extension. - Having packed your extension, drag and drop it into the same computer to determine your Extension ID. In this case, it will be
aaaaaaaaafgjeglblehebfpbcfeobpgk
- Grab your CRX and place it on your web server in the directory specified above. The naming convention is up to you. In this example, the extension is uploaded as
https://corp.example.com/service/chrome_extension/v0.0.1.crx
.
Creating your Update.xml file
This was a mild source of pain for me and took me longer than I’d like to admit to get working. Basically:
- Don’t do anything fancy with the XML. At all.
- Use single quotes
- Basically, do exactly as Google tells you
Using documentation from Google, I was able to figure out how to make it work. Mistakes (on my part) were made. Regardless, your Update.xml file instructs Chrome where to download updates to your extension from. Technically you could have several extensions pointing at the same update file, but for simplicity’s sake we’re going to use one file for one extension.
<?xml version='1.0' encoding='UTF-8'?>
<gupdate xmlns='https://www.google.com/update2/response' protocol='2.0'>
<app appid='aaaaaaaaafgjeglblehebfpbcfeobpgk'>
<updatecheck codebase='https://corp.example.com/service/chrome_extension/v0.0.1.crx' version='0.0.1' />
</app>
</gupdate>
For each future revision of your extension, simply replace the <updatecheck />
element with the latest version of your extension. I thought that Chrome might be able to magically figure out the latest version, but it can’t.
Configuring Group Policy
Note: if you are not an Active Directory Administrator then the following steps are irrelevant. You can’t do them. Instead, you will need to ask your administrators to do the below.
If you haven’t already, you will need to have imported the Google Chrome ADMX files into your directory. This is outside the scope of this article, however between this article from Google and this article from Microsoft you should be able to figure it out.
- Either from a computer with the Group Policy Management Tools installed (or, if you’re feeling lucky, a Domain Controller), open Group Policy Management and create a new Group Policy Object
- Either at a Computer or User level, navigate to Adminstrative Templates -> Google -> Google Chrome -> Extensions
- Define the ‘Configure the list of force-installed apps and extensions’ policy
- Set the policy to Enabled
- Click ‘Show’
- Add a new entry in the following format:
extensionid;https://updateurl
. For our example above, enter verbatimaaaaaaaaafgjeglblehebfpbcfeobpgk;https://corp.example.com/service/chrome_extension/update.xml
- OK out of the dialogue boxes
- Define the ‘Configure extension, app, and user script install source’ policy
- Set the policy to Enabled
- Click ‘Show’
- Add a new entry with the path to where your extensions will be downloaded from. In our example, this would be
https://corp.example.com/service/chrome_extension/*
, permitting any CRX files that start withhttps://corp.example.com/service/chrome_extension/
to be downloaded. Subdirectories are also included, so this can be as broad or narrow as you wish. - OK out of the dialogue boxes
At this point, you should be able to run gpupdate /force /boot
and see your extension be automatically deployed!