google-chrome-extensionchrome-extension-manifest-v3chrome-extension-manifest-v2

Auto update Chrome extension during development with CI/CD and update.xml


I have a Chrome Extension in development, locally which is a React application.

I have set up a CI/CD pipeline so that the React app is built with yarn build to produce the dist directory containing the app files and the manifest.json. The pipeline then uses this npm package to create the .crx file and upload it to a public storage location along with the update.xml file which has been updated with a new version number and URL to the new .crx file.

I created a private key (key.pem) locally and stored in a key vault so that the "packing" job in CI pipeline uses the same private key each time. The public key has been added to the manifest.json so that the app ID stays the same each time.

Update2.xml

<?xml version='1.0' encoding='UTF-8'?>
<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>
  <app appid='blahblahooaejaldnohkhmaedknkfogn'>
    <updatecheck codebase='https://mypubliccrxstorage.blob.core.windows.net/crx/myapp-1.0.20210702.22.crx' version='1.0.20210702.22' />
  </app>
</gupdate>

manifest.json

{
...
    "manifest_version": 2,
    "version": "1.0.20210702.22",
    "key": "<my-public-key",
...
    "update_url": "https://mypubliccrxstorage.blob.core.windows.net/crx/update2.xml"
}

Steps to install and update:

  1. Go to chrome://extensions/ > developer mode > load unpacked > select local dist directory.
  2. The unpacked extension appears in the list of extensions with app id: blahblahooaejaldnohkhmaedknkfogn
  3. Select the extension and click "Update"

Expected result:

Chrome queries the remote update.xml file, sees a version later than the initially installed version, downloads and installs the new crx file from the specified location.

Actual result:

The extension is not updated.

Note: I downloaded the crt generated by the CI/CD from the storage location and uploaded it here. The public key shown by that online tool matches the value of key in the manifest.json and the calculated app id matches the one in update.xml.

To dig a little deeper I opened Fiddler4 and sniffed the calls made by Chrome. Although I don't understand everything, part of one of the responses was:

<?xml version="1.0" encoding="UTF-8"?><gupdate xmlns="http://www.google.com/update2/response" protocol="2.0" server="prod"><daystart elapsed_days="5296" elapsed_seconds="28389"/><app appid="mgndgikekgjfcpckkfioiadnlibdjbkf" status="error-unknownApplication"/><app appid="apbllhlpimnkljppmmdbiipfbjjimjgj" cohort="1::" cohortname="" status="ok"><updatecheck _esbAllowlist="false" status="noupdate"/></app></gupdate>

That "app id" is not mine (or is that the Chrome app id?), but the status of "error-unknownApplication" perhaps gives some hint as to what is going on.


Solution

  • No protection setting in Chrome allows an extension to update. This setting also allows to drag and drop .crx into chromium extensions.

    Chrome settings