This document contains advice for people reviewing Vaultonomy for security reasons — to understand its behaviour and implications for security. It describes how to check that the releases published by Vaultonomy on Google Web Store and Firefox Add-ons are verifiably the result of building the source code in this repository, and have not been tampered with.
This is aimed at staff of extension hosting platforms and anyone with an interest in what they're installing.
Also see the Reviewing Vaultonomy Behaviour page, which covers how to review and verify the source code.
- Reviewing Vaultonomy Behaviour explains how to verify that the intended behaviour of Vaultonomy is acceptable.
- Reviewing Vaultonomy Releases (this document) explains how to verify that the installed software does in fact exhibit the intended behaviour established here — i.e. it's not been modified.
- Background
- Vaultonomy's release archives
- Verifying a signed
.crxor.xpiarchive against a release archive - Building from source
The general workflow to take an extension from developer to user is:
- Developer bundles the extension code and resources into a
.ziprelease archive - Developer submits the release archive to an extension Marketplace, like Chrome Web Store and Firefox Add-ons. The developer also submits source code and build instructions required to re-create the release archive.
- The Marketplace performs automated & manual checks on the release archive to detect problems.
- If the checks are passed, the Marketplace creates a digital signature of the
distribution archive's contents. They add metadata files (including the
signature) to the archive, and publish the result as a
.crx(Chrome).xpi(Firefox) file on their Marketplace for users to install. (Browsers only allow users to install extensions that have been signed by their Marketplace.)
Vaultonomy requires a build step to generate the .zip extension release
archives. The build has two separate modes for Chrome-based browsers and
Firefox, to account for differences between the browsers.
The release archives that Vaultonomy submits to Google Web Store and Firefox Add-ons are built in using GitHub Actions (build servers run by GitHub). We use GitHub's attestation feature to create verifiable proofs that Vaultonomy's release archives were built on a GitHub-operated Actions runner using the build instructions committed to the repo at the tag version.
The release archives are published for each release on the repository's Releases page.
The .crx or .xpi file you install from your browser's extension Marketplace
should contain the files from the release archive, except for extra metadata
added by the Marketplace. At a high level, the steps to verify this are:
-
Download the
.crx/.xpiarchive from your MarketplaceExpand details…
Download the Firefox
.xpifile from Firefox Add-ons by right-clicking & "Save Link As…" on the "Add to Firefox" button on Vaultonomy's Firefox Add-ons page.To download the Chrome
.crxfile, you need to use a 3rd party tool because Chrome Web Store does not show a download link on its website. There are several 3rd party websites and browser extensions that will allow you to download.crxfiles for an extension. Search the web for "download chrome extension crx" or similar. -
Download the release archive for the same version number from the Vaultonomy GitHub releases page
Expand details…
- Go to https://github.com/h4l/vaultonomy/releases
- Search for the version number matching the version you're verifying
- Download the release archive from the release page. The release archives
are named like:
vaultonomy_chrome_v0.0.1.zipvaultonomy_firefox_v0.0.1.zip
-
Verify GitHub's attestation that it built the release archive on its servers
Expand details…
Vaultonomy uses GitHub artefact attestations to allow end-users to verify that a
.ziprelease archive was built on GitHub's servers in a transparent way.- Install GitHub CLI: https://cli.github.com/
- Use the
gh attestation verifycommand to check the release archive you downloaded in step 2:
$ gh attestation verify vaultonomy_firefox_v0.0.1-citest.9.zip --repo h4l/vaultonomy Loaded digest sha256:1efb5d8e48f2df6e0270acd2a5377c0f31f5c8b16c7d836cc323ab990d5d7674 for file://vaultonomy_firefox_v0.0.1-citest.9.zip Loaded 1 attestation from GitHub API ✓ Verification succeeded! sha256:1efb5d8e48f2df6e0270acd2a5377c0f31f5c8b16c7d836cc323ab990d5d7674 was attested by: REPO PREDICATE_TYPE WORKFLOW h4l/vaultonomy https://slsa.dev/provenance/v1 .github/workflows/ci.yml@refs/tags/v0.0.1-citest.9
If you'd like more in-depth details of the build, add
--format jsonto the command. The output will contain details such as the exact git commit hash the build was made from, and a link to the GitHub Actions run logs.
-
Compare the files inside each archive to check they are identical
Expand details…
In a typical UNIX command-line environment, you can use
unzipanddifftools to compare the files:# extract the marketplace's archive into the marketplace-files sub-directory $ unzip -d marketplace-files vaultonomy.crx ... # extract the release (source) archive into the release-files sub-directory $ unzip -d release-files vaultonomy_chrome_vX.Y.Z.zip ... # Compare the files in each directory $ diff -r release-files marketplace-files ...
The output of
diffwill show any differences between the two directories. No output means no difference, so files that match will not be mentioned (use the-soption to list identical files).-
For Chrome
.crxfiles, you should expect the output to be as follows:$ diff --recursive release-files marketplace-files Only in marketplace-files: _metadata diff --color=auto --recursive release-files/manifest.json marketplace-files/manifest.json 1a2,3 > "update_url": "https://clients2.google.com/service/update2/crx", >
Chrome Web Store adds a
_metadatadirectory, and also modifiesmanifest.jsonto add an"update_url"property at the top. It makes no other changes. -
For Firefox
.xpifiles, you should expect the output to be as follows:$ diff --recursive release-files marketplace-files Only in marketplace-files: META-INF
Firefox Add-ons adds the META-INF directory, which contains several files. It makes no other changes.
If you're using Windows, there are graphical applications that can compare directories of files or zip archives to each other. For example, WinMerge. You may need to rename the
.crx/.xpifiles to use the.zipextension. -
Vaultonomy's release archives are built using docker. Building in a docker container makes it easy to reproduce the builds without needing to manually install and configure dependencies. However the core build step can run on your own computer if you prefer.
You'll need a recent version of the Docker command-line tool installed, with docker buildx.
If you have a source tarball/zip you need to build from, extract it. Otherwise clone Vaultonomy's git repository and check out the tag you wish to build.
From the root directory, run the following command (omit one of the package-
targets if you only need one platform):
$ docker buildx bake package-firefox package-chromeThe build outputs are:
$ tree dist/packages/
dist/packages/
├── chrome-production
│ └── vaultonomy_chrome-production.zip
└── firefox-production
└── vaultonomy_firefox-production.zipThese are the .zip release archives that get submitted to Marketplaces for
review.
Note: This uses the
docker-bake.hclfile, and builds thepackage-firefoxandpackage-chrometargets. You can run withbakewill do. TheDockerfilecontains the build instructions.
Note: The
.zipfilenames do not contain a version number in this example, because the build only gives numbers to builds that explicitly opt-in. You can set environment variables to get files with version numbers. This will not affect the files within the release archive — the version inmanifest.jsonis set from thepackage.jsonversion.
GITHUB_REF_TYPE=tagGITHUB_REF_NAME=vX.Y.Z
Note: The build takes steps to make it bit-for-bit reproducible, following advice from https://reproducible-builds.org. I've not yet conducted enough builds to be confident that it's consistency reproducible, but I've been able to reproduce CI builds locally bit-for-bit. The main source of potential differences is the version of the nodejs runtime used to perform the build, as it's currently using the latest 22.X.X version. However, run-time and build-time dependencies in package.json are pinned exactly.
To build locally, install nodejs (we use version 22 currently).
# Install npm dependencies
$ npm install
# To build for chrome:
$ npm run build
# To build for Firefox:
$ VAULTONOMY_BROWSER=firefox npm run buildThis will create files under dist/chrome/ or dist/firefox/ respectively. The
files are not bundled into a release .zip archive, but should be the same as
the release archive files.