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

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

  1. 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 from https://corp.example.com/service/chrome_extension/v0.0.1.crx.
  2. Update your extension’s manifest.json to include:

    {
    	...
    	"update_url": "https://corp.example.com/service/chrome_extension/update.xml",
    	...
    }
    
  3. 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.

  4. Having packed your extension, drag and drop it into the same computer to determine your Extension ID. In this case, it will be aaaaaaaaafgjeglblehebfpbcfeobpgk

  5. 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:

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.

  1. 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
  2. Either at a Computer or User level, navigate to Adminstrative Templates -> Google -> Google Chrome -> Extensions
  3. Define the ‘Configure the list of force-installed apps and extensions’ policy
    1. Set the policy to Enabled
    2. Click ‘Show’
    3. Add a new entry in the following format: extensionid;https://updateurl. For our example above, enter verbatim aaaaaaaaafgjeglblehebfpbcfeobpgk;https://corp.example.com/service/chrome_extension/update.xml
    4. OK out of the dialogue boxes
  4. Define the ‘Configure extension, app, and user script install source’ policy
    1. Set the policy to Enabled
    2. Click ‘Show’
    3. 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 with https://corp.example.com/service/chrome_extension/ to be downloaded. Subdirectories are also included, so this can be as broad or narrow as you wish.
    4. 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!