Important
Most of the documentation in the repository, including the dissertation, references a previous architecture, which is currently being reworked. Most information about web applications and manifests remains unchanged, while major parts of the infrastructure are deprecated. Target alpha release: December 2025.
Note
To read the motivation for this project and the problem it solves, please read our introductory blog post on WEBCAT.
The purpose of this project is to showcase an architectural framework that provides blocking code signing, as well as integrity and transparency checks for browser-based applications. In doing so, it primarily leverages existing technologies and community infrastructure, including Sigsum, and CometBFT. The browser extension has no external runtime dependencies, and all cryptographic operations are performed using only the Web Crypto API. Runtime policy enforcement in the enrolled domains is handled by the browser's Content Security Policy (CSP).
The project has been originally written as a master's thesis for the Master Computer Security at the Vrije Universiteit Amsterdam and the University of Amsterdam, sponsored by the Freedom of the Press Foundation. The full dissertation is available on ePrint. It has since evolved to address censorships risks, centralization, and single points of failure concerns.
WEBCAT is:
- An enrollment consensus system
- A set of specifications
- A Firefox (v2) extension (out of date)
- A CLI for developers and hosters
- Some dependencies, such as sigsum-ts and cometbft-ts. Though they are no longer in use in WEBCAT, we also worked on tuf-browser and sigstore-browser.
This is currently experimental software and should not be used in production.
See The long and winding road to safe browser-based cryptography and Introducing WEBCAT for additional context.
See apps for a list of supported and in-progress apps.
See threat model for preliminary threat model considerations.
If you are a developer and want to design or port your application, look at the developer reference and also at the issues mentioning the porting of existing apps (such as: #28, #26, #25).
| Feature | Supported? | CSP Directive / Value | Notes |
|---|---|---|---|
| WebAssembly | Yes | script-src 'wasm-unsafe-eval' | |
| Web Workers | Yes | worker-src 'self' | |
| Shared Workers | Yes | worker-src 'self' | |
| Service Workers | Yes | worker-src 'self' | |
| Iframes | Yes | frame-src/child-src 'self' blob: data: <enrolled_origin> | External origins needs to be enrolled. |
| Nested Iframes | Yes | frame-src/child-src 'self' blob: data: <enrolled_origin> | All external origins needs to be enrolled. |
| Inline Script | No | ||
| Script Hash | No | ||
| Script Unsafe Eval | No |
It is implemented and theoretically possible to include scripts from remote origins that are also enrolled (and similarly workers or styles), still providing a transparency chain of all hosts and allowing loads from CDNs. This is because origin validation is recursive, and enrollment is checked when the manifest is parsed and validated.
The unsigned extension, to use exclusively for testing, development, and debugging, is built via GitHub Actions at every commit. Download the artifact from the latest run. Once unzipped, it can be installed temporarily in Firefox via about:debugging#/runtime/this-firefox and then choosing "Load Temporary Add-on..." and selecting the extracted manifest.json.
The following test domains are provided solely for demonstration and showcasing purposes. As such, they are not secure, not well-maintained, and do not guarantee any form of data retention. A test enrollment server and list distributor—provided without any guarantees—are available at https://transparency.cat/api/ and https://transparency.cat/update/.
| Domain | App | Description |
|---|---|---|
| testapp.nym.re | Testapp | Showcases WASM, Webworkers, Workers, and Sharedworkers support. |
| element.nym.re | Element | The Matrix client. |
| globaleaks.nym.re | Globaleaks | Whistleblowing platform. |
| jitsi.nym.re | Jitsi Meet | Video conferencing software. |
| standardnotes.nym.re | Standard Notes | A secure and private notes app. |
| bitwarden.nym.re | Bitwarden | Cloud password manager. |
| cryptpad.nym.re | CryptPad | End-to-end encrypted collaboration suite. |
The enrollment system has three roles:
- Log all enrollment transactions
- Process enrollment transactions
- Build daily enrollment lists
This is a permissioned chain run by a limited set of trusted organizations. External parties can audit the chain but do not participate in consensus. The chain governs enrollment, modification, and de-enrollment. Nodes (and validators) independently fetch the target host, observe the proposed change, and agree on both the observed state and the operation's validity (e.g., you cannot de-enroll a domain that isn’t currently enrolled).
Once per day, the chain initiates a list-building transaction that deterministically applies the full history to produce the current enrollment list. That list is distributed to users' browsers at startup and at predefined intervals.
Developers are responsible for signing, logging, and distributing their artifacts, and for publishing a policy. A policy is the trust material required to validate developer artifacts. It consists of:
- One or more Ed25519 signing keys
- A signature threshold (≤ number of keys)
- A Sigsum policy (one or more Sigsum logs and their keys, plus a witness policy)
Developers may also publish a reference hostname that is enrolled with the same policy. Artifacts are signed using any threshold of the policy’s keys, and each signature carries a Sigsum proof satisfying the Sigsum policy.
Website administrators enroll using a developer-provided policy (optionally referencing the developer’s reference hostname) and deploy the developer’s artifacts.
Users download the most recent enrollment list from a CDN and verify its freshness and consensus using the embedded trusted-organization keys in the browser component. When visiting a site, the browser checks the local enrollment list. If the site is enrolled, it fetches the site’s enrollment policy from the site itself and verifies it against the policy hash embedded in the local list. If a reference hostname is provided, the browser also verifies that the current site’s policy hash matches the reference’s (e.g., submissions.webcat.example matches securedrop.org). The verified enrollment policy is then used to validate developer artifacts.
Thanks to smaury of Shielder and to antisnatchor of Persistent Security for their security-related insights. Thanks to Giorgio Maone of the Tor Project for the development-related support. We are also working with, and taking inspiration from, the WAICT working group.
