cross-origin-storage

The Public Hash List (PHL): an availability-gating allowlist for Cross-Origin Storage

Status of this document. This design document, and the early implementation described below, currently live in the WICG/cross-origin-storage repository, alongside the Cross-Origin Storage explainer and spec this document serves as a companion artifact to. The Governance section below describes this proposal’s target end state — hosting under the WHATWG, with a dedicated, cross-vendor repository, editors, and a signing key of its own — which has not happened yet. Housing both the design document and its implementation in a single vendor’s spec repository is a pragmatic interim step, not the destination: nothing in the Governance section is settled, and a dedicated repository remains the goal for both.

Why “Public Hash List”? The name is a deliberate echo of the Public Suffix List (PSL). The PSL is a single, openly licensed, cross-vendor data file that every browser consults to make a privacy-sensitive boundary decision. The PHL is the analogous artifact for Cross-Origin Storage: a single, openly licensed, cross-vendor data file that every browser consults to decide which cached bytes are safe to admit exist. “Public Suffix List” → “Public Hash List” is intended to make the analogy, and the freely-reusable intent, obvious on first read.

Authors

Early implementation

An early implementation of the Public Hash List proposal is maintained at public-hash-list/implementation/ in this repository. Housing it here, alongside this design document (see “Status of this document” above), is a pragmatic interim step — the goal remains a dedicated, cross-vendor repository, not permanent co-location with the spec of a single implementer.

To keep the list evergreen, it automatically ingests “top” resources from ten sources (Google Hosted Libraries, Microsoft Ajax CDN, cdnjs, jsDelivr, npm popular packages, Chromium pervasive resources, the YouTube player, Google Maps JS API, Google Fonts, and the HTTP Archive) plus a hand-curated AI model-hub section drawn from the most-downloaded models on the Hugging Face Hub (currently capped at the top 10,000 by download count). Like the PSL, it also supports manual additions: contributors propose entries via pull request against a reviewed JSON schema (URL, hash, description, rationale, and submission date), evaluated against the same ubiquity bar the automated sources apply. The canonical Public Hash List flat file and its SHA-256 integrity file are published in the data/ directory (stored with Git LFS; media.githubusercontent.com, not raw.githubusercontent.com, serves the actual file content).

Objective

Define a vendor-neutral, openly licensed, continuously updated list of content hashes for resources so widely deployed that confirming their presence in a shared cache reveals nothing specific about a user, so that any user agent can unconditionally answer Cross-Origin Storage availability queries for those hashes, while every other resource stays gated by default.

Background

Motivation: from implementation-defined to interoperable

Some browsers already maintain their own implementation-defined lists of resources that receive special cache-sharing treatment. For example, Chromium ships an internal pervasive-resources list that exempts certain widely-used assets from its HTTP cache-partitioning policy. This creates a performance observation that is not intentionally exposed as a Web API: there is no mechanism for a resource to opt in, and there is no API for script to query which resources receive the special treatment. The list is internal to the browser, opaque to the Web, and differs across vendors.

COS changes this fundamentally. It makes the sharing relationship explicit: resources can be registered by hash, and requestFileHandle() provides a standard API for script to query the cache. The performance benefit of cross-origin cache sharing is therefore no longer a side-effect of an invisible, vendor-specific heuristic; it is a first-class, queryable capability. But this also means that the set of resources eligible for sharing becomes observable to the Web, and its composition directly determines whether the capability is interoperable. If each browser keeps its own private list, developers cannot rely on cross-origin cache hits being consistent across browsers, and the performance win is fragmented along vendor lines. The PHL is the mechanism that makes the allowlist cross-browser and openly auditable: a single, vendor-neutral data file that every conforming user agent consults, so the eligibility decision is the same everywhere.

COS and content-addressable sharing

Cross-Origin Storage (COS) lets a user agent share a single cached copy of a large, content-addressed file across unrelated origins. A file is keyed by its hash, so a 50 MB Wasm resource fetched once on site-a.example can be reused by site-b.example with no second download. The current hash algorithm is SHA-256 (matching the Web Crypto API’s implementers’ recommendations and COS’s requirement that hash.value be a 64-character lowercase hex string), but COS carries the algorithm explicitly as a HashAlgorithmIdentifier precisely so it can migrate later; the list described here is designed to migrate with it (see Data format). The cross-origin win is real: jquery-3.7.1.min.js is served bit-for-bit identically from ajax.googleapis.com, cdnjs.cloudflare.com, code.jquery.com, and ajax.aspnetcdn.com, which is exactly the duplication COS removes. At the scale the early implementation now operates — hundreds of thousands of hashes once the k-anonymity-gated long tail described in Scaling parameters is included — this kind of exact duplication is common enough to be worth removing structurally, not just for a handful of hand-picked libraries.

The privacy hazard is equally real, and is the subject of the explainer’s Availability gating and Cross-site probing sections. Because any origin can call requestFileHandle(hash) and learn whether that hash is cached, cache presence becomes an oracle. If a hash is rare, that is, is used by only a handful of sites, a positive answer tells a probing attacker which of those sites the user has visited. This is the same class of attack the PSL was created to mitigate for cookies (so-called “supercookies”); COS needs its own structural mitigation. The explainer’s answer is an allowlist of resources that are unconditionally eligible for cross-origin availability disclosure. Such resources are (i) either so widely deployed that disclosing their cache presence is uninformative about any individual or (ii) are part of an agreed-on set of well-known resources, like AI model weights. This document designs that allowlist.

The governance and distribution precedent is the Public Suffix List: a community-maintained data file pulled from a single canonical URL, split into structured sections, carrying VERSION/COMMIT headers, updated continuously, used cross-vendor by browsers, CAs, and CDNs, and explicitly outside any single vendor’s control. The PHL adopts that model wholesale.

Glossary

Requirements

Any successful solution must:

Proposal

We propose the Public Hash List (PHL): a single, openly licensed, cross-vendor data file listing the content hashes of ubiquitous and well-known Web resources. A hash present in the PHL is unconditionally eligible for COS availability disclosure; every other hash stays gated by default. The PHL’s sole job is to enumerate exactly those resources whose ubiquity makes disclosing their cache presence safe.

Data format

The user agent needs exactly one thing at runtime: given a hash, is it on the list? That is a set-membership test, and the only data it requires is the algorithm and the digest. Everything else, like which CDN vouched for the file, how many mirrors it has, or when it first appeared, is curation and audit metadata for maintainers and reviewers, not lookup payload. The PSL solved precisely this split: its machine-readable payload is bare suffix lines, and all provenance (“confirmed by…”, source URLs, dates) lives in // comments that parsers skip. The PHL should do the same: a flat text list with structured comments.

Concretely:

// Public Hash List (PHL)
// VERSION: 2026-06-19T18:30:00Z
// COMMIT: 9f3c…
// License: MPL-2.0  https://mozilla.org/MPL/2.0/
//
// ===BEGIN SHA-256===
// Ubiquitous, corroborated resources. User agents MUST treat these as eligible.
// jQuery 3.7.1 — corroborated by Google Hosted Libraries, cdnjs, Microsoft Ajax, code.jquery.com
// e.g. https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js
fc9a93dd241f6b04...
// D3 7.9.0 — Google Hosted Libraries, cdnjs
// e.g. https://ajax.googleapis.com/ajax/libs/d3js/7.9.0/d3.min.js
f2094bbf6141b359...
// ===END SHA-256===
//
// ===BEGIN SHA-256 HUGGING-FACE===
// Hand-curated AI resources from a recognized model hub (see Sources).
// User agents SHOULD include this section; a user agent MAY omit it.
// gemma-2-2b-it (int4 .task) — e.g. https://huggingface.co/.../g-2b-it-gpu-int4.bin
1a2b3c4d5e6f7a8b...
// ===END SHA-256 HUGGING-FACE===

Each significant line is a bare lowercase hex digest, trivially parsed (^[0-9a-f]{64}$), trivially grepped, and diff-friendly so additions and removals are reviewable line-by-line.

The published artifact is therefore just: a header, section delimiters, and bare digests, with human-readable provenance in comments. A user agent can additionally compile it into a compact probabilistic membership filter (cuckoo or bloom) for the hot path; the text file remains the canonical, auditable source.

Sources and why they were chosen

Popularity-based sources

The candidate hashes are produced by a build pipeline that scrapes several popularity-based catalogs, downloads each listed .js/.css/.wasm/ asset, hashes it, dedupes exact (hash, URL) pairs, and merges mirrors of the same file. The specific sources were chosen to triangulate ubiquity from independent angles, because no single signal is trustworthy on its own:

Collectively, these span curated catalogs, real request volume, developer adoption, browser-vendor vetting, embedded-widget reach, and web fonts. A resource that clears several of these independent measures is ubiquitous in a way that makes its cache presence uninformative about any individual, which is exactly the privacy property the allowlist needs.

This source set is explicitly not set in stone. It reflects today’s and the existing long-tail Web; the durable part of the design is the methodology, not the particular catalogs. Sources will be added or retired as the ecosystem shifts: obvious near-term candidates include other general CDNs (unpkg) and other Web-font providers. Adding a source is a governance action, not a format change.

Critically, the list of intake vendors is not predetermined or controlled by any single party. The initial set above is a draft, subject to neutral editorial review by the WHATWG-hosted group that governs the PHL. Any proposed addition or retirement must clear the thirty-day public comment period and unanimous editor approval described in Change process below. Objective criteria drive source selection: independence from existing sources, a verifiable and reproducible methodology for determining which assets to include, and an empirical ubiquity signal (e.g., request volume, download count, or cross-CDN corroboration). Sources that duplicate an existing signal without adding independent evidence are unlikely to be approved. This process ensures that the intake vendor set reflects the breadth of the Web rather than the preferences of any particular browser vendor or CDN operator.

A hand-curated source: a recognized AI model hub

The sources above all rest on an objective signal of ubiquity: request volume, download counts, cross-CDN identity. AI model weights, which are one of COS’s core use cases (the explainer opens with multi-gigabyte Gemma and Llama models), do not fit that mold. A specific model build may be enormously valuable to deduplicate yet appear on only a handful of sites, so it would never qualify under those objective signals, and most of them do not catalog models at all. To unlock the AI use case we therefore add a hand-curated source: the public catalog of a recognized model hub (e.g., the Hugging Face Hub). Inclusion here is justified not by a measured ubiquity signal but by membership in a recognized, openly browsable hub where the weights are publicly published and content-addressed; the disclosure such an entry permits is coarse interest inference (“this user runs in-browser AI models”) rather than identification of a specific site, because the artifacts are public hub downloads, not site-unique secrets. The only remaining issue is how to handle rather unique, custom models posted to public hubs. We can control this risk by focusing our efforts solely on models that reach a given download threshold, which hubs like Hugging Face track independently.

Because this source departs from the objective bar, it is optional but strongly encouraged, in normative terms:

User agents SHOULD include the hand-curated model-hub section of the PHL. The AI model use case delivers its benefit only when adoption is uniform: a user agent that includes the section lets large model weights be shared cross-origin and downloaded once, while omission forces those same multi-gigabyte downloads to repeat per origin. Uneven adoption confers a material performance advantage directly contrary to the PHL’s purpose as a neutral, cross-vendor resource. Because at least one major user agent is already expected to ship this section, this risk is concrete, and deviation from this recommendation should only be decided under exceptional circumstances.

The Hugging Face Hub is named here because it is, at present, the de facto central hub for openly published AI models, which makes it the natural seed for this source today. The design is not bound to it, though: the inclusion basis is “a recognized public model hub,” not Hugging Face specifically. Should the center of gravity shift to a different hub, or should the ecosystem fragment across several, additional hubs can be added (or the seed retired) by the same governance process that adds any other source. The model-hub section is the durable construct, the particular hub behind it is not.

Manual additions

Anyone can manually submit a PR for inclusion if they can demonstrate the ubiquity required. Submissions will be reviewed by a process similar to that of the PSL but adjusted to the specific needs of the PHL.

Scaling parameters

The corpus has two tiers with different growth dynamics. The curated-catalog sources (Google Hosted Libraries, Microsoft Ajax CDN, cdnjs, jsDelivr, npm popularity, Chromium pervasive resources, YouTube Player, Google Maps JS API, Google Fonts) draw from a small, stable set of roughly 16 known CDN hostnames and grow slowly: the dominant driver there is new versions of already-listed resources (dozens of historical jQuery builds, hundreds of versioned YouTube player_ias files), so that tier grows roughly with release cadence, not with the size of the Web.

The HTTP Archive source is structurally different: rather than trusting a curated host list, it admits a hash once it is independently observed on ≥100 distinct origins in monthly crawl data — a k-anonymity gate on origin diversity rather than a host allowlist. That tier now accounts for the majority of entries. Combined, the early implementation’s current candidate set is 301,618 distinct hashes. Storage remains manageable at this scale: a SHA-256 digest is 32 bytes, so the full list is under 10 MB of raw digests, and a probabilistic membership filter shrinks the hot-path structure to a few megabytes at a tunable false-positive rate — still comfortably within browser memory. Lookups remain local set-membership tests with no network dependency; query volume is bounded by requestFileHandle() calls. Should the k-anonymity-gated tier continue to dominate growth, the governance process (see Change process) is the mechanism for revisiting parameters such as the origin threshold or response-type filter that bound its size.

Rollout: continuous, like the PSL

There is no phased launch. The PHL follows the PSL’s rolling-release model end to end:

  1. The build re-scrapes the curated catalogs on a schedule, re-hashes new and changed files, and proposes additions/removals.
  2. Human-submitted and automated changes to the catalogs land via pull request against the canonical repository, subject to the governance and exclusion rules below.
  3. The canonical signed file at a single stable URL always reflects the latest state, with VERSION/COMMIT headers so consumers can detect changes.
  4. User agents pull and cache the file on their own cadence (with a small embedded fallback for offline first-run) and recompile their membership filter, exactly how mature PSL consumers refresh.

A safety property holds throughout: because every entry is a public, demonstrably ubiquitous resource, the worst a bad entry can do is over-disclose a file that was already safe to disclose, never a private one.

The PHL contains only hashes and public provenance, never user data, so the list itself leaks nothing. The core section’s safety rests on its inclusion bar: a file is listed only after clearing multiple independent signals of ubiquity, which is precisely the property that makes its cache presence uninformative about an individual. The hand-curated model-hub section relaxes that bar deliberately for the AI use case, and accepts a different, bounded guarantee: coarse interest inference from public hub artifacts. This is why it is a separate, optional section rather than mixed into the core list. In both cases, presence on the PHL authorizes availability disclosure for that hash and nothing else: user agents remain free, and expected, to apply probe-rate limiting, on-device fingerprinting detection, and size-proportionate GREASE’ing per the explainer. The file is signed so consumers can verify integrity and provenance before trusting it, and the reproducible build lets any party independently re-derive and challenge any entry.

License. To match the PSL and keep cross-vendor adoption frictionless, the PHL is published under the Mozilla Public License 2.0 (MPL-2.0), the same license the PSL itself uses. MPL-2.0 is OSI- and FSF-approved, weak (file-based) copyleft, and explicitly permits embedding MPL-licensed components into proprietary codebases (such as a closed-source browser binary) provided the MPL components remain available under the MPL. Using the same license as the precedent the PHL is modeled on minimizes legal review for any vendor that has already cleared the PSL.

A note on what is being licensed: the individual entries are facts (a file has a given hash), and facts attract no copyright in the US; a curated compilation can nonetheless attract a thin compilation copyright and, in the EU, a separate sui generis database right. Publishing the whole list under MPL-2.0 places both beyond doubt for downstream users. Crucially, the PHL distributes hashes and (in comments) example URLs only, never the resource bytes, so it never redistributes jQuery, a font, or a model, and therefore inherits none of those resources’ own licenses. It is a list about files, not a copy of them.

Governance

The PHL is governed by the WHATWG.

Why the WHATWG

The WHATWG is the natural home for the PHL for the same reasons it hosts the Living Standards that define the APIs the PHL serves: it operates by consensus among major browser vendors, its process is openly documented, and its output carries the cross-vendor legitimacy that a privacy-boundary artifact requires. The PSL predates modern standards governance and is informally maintained by the Mozilla community; the PHL, coming later, can do better. Hosting under the WHATWG means:

Repository and canonical artifact

The PHL lives in a public repository under the WHATWG GitHub organization. The repository contains:

Roles

Editors hold merge rights and are responsible for the correctness of the list and the integrity of the build pipeline. They are appointed by the WHATWG Steering Group and must represent at least two distinct browser-vendor affiliations at all times, so that no single vendor can merge changes unilaterally. The minimum viable editorial group is therefore two editors from two different vendors; in practice, broader representation across the major shipping browsers is expected and encouraged.

Contributors are any individuals or organizations that open Pull Requests. Contribution is open to everyone; no affiliation is required. A contributor who proposes a new source, a manual addition, or a policy change must provide evidence sufficient for the inclusion criteria to be evaluated by someone who has never seen the proposal before. Editors are not expected to take claims on trust.

Consumers — browser vendors and other user agents — are not required yet highly encouraged to adopt the PHL, but the cross-vendor privacy guarantee only holds when adoption is uniform. The WHATWG process provides the venue for consumer vendors to raise compatibility or security concerns about a proposed change before it lands rather than after, which is preferable for all parties.

Inclusion criteria and exclusion filters

General eligibility criteria

All resources must meet the following eligibility criteria:

  1. Content stability. The URL (or URL pattern) that delivers this hash is versioned or otherwise content-stable. A resource served from a URL like latest.min.js that silently changes bytes over time is ineligible, because today’s hash maps to a specific byte sequence and a future byte sequence at the same URL would be a distinct, un-listed hash.
  2. Public availability. The resource is freely fetchable without authentication, region restriction, or paywalling. A hash that a reviewer cannot independently re-derive from public sources cannot be audited and therefore cannot be listed.
  3. No tracking or fingerprinting purpose. Any resource whose primary design purpose is to identify individual users, track behavior, or serve as a fingerprinting vector is excluded, regardless of how widely deployed it is. Detection is necessarily judgement-based; the editors are the arbiters, with appeal to the WHATWG Steering Group.
  4. No compression, encoding, or transport-layer variation. The hash is computed over the canonical, identity-encoded response body. A resource that is byte-for-byte different depending on whether the server applies Brotli compression does not have a single canonical hash and cannot be listed. Pipeline documentation must specify the exact fetch and decoding steps used.

Entries that fail any criterion must be removed, regardless of how long they have been on the list. The automated pipeline enforces criteria 1–3 and 5 mechanically; criterion 4 may require human review.

Eligibility for the ===BEGIN SHA-256=== section

A hash is eligible for the core ===BEGIN SHA-256=== section (or any of the future hash algorithm sections) if and only if it clears all of the following:

Eligibility for the ===BEGIN SHA-256 HUGGING-FACE=== section

A hash is eligible for the ===BEGIN SHA-256 HUGGING-FACE=== (or equivalent model-hub) section if and only if it clears all of the following criteria:

Eligibility for the ===BEGIN SHA-256 MANUAL=== section

A hash is eligible for the ===BEGIN SHA-256 MANUAL=== section if and only if it meets all of the following:

Manual entries do not inherit the automated pipeline’s continuous update cycle. The submitter is responsible for filing a follow-up PR when a new version of the resource is released and for requesting removal when a version falls out of widespread use. Editors may remove a stale manual entry at their discretion if it no longer plausibly meets the ubiquity requirement.

Change process

Automated additions. The build pipeline runs on a scheduled cadence (currently weekly) against all active sources. New hashes that pass all automated criteria are batched into a pull request. The PR includes a machine-generated diff summary showing how many hashes are added or removed, which sources corroborate each addition, and a reproducibility manifest (a record of the exact fetch timestamps, response headers, and computed digests used to produce the diff). An automated addition PR requires approval from at least one editor before merging.

Automated removals. A hash is removed automatically when it no longer appears in any active source, subject to a grace period of two consecutive pipeline runs to absorb transient scraping failures. Removals are less sensitive than additions (removing a hash can only make COS more conservative, never less), so an automated removal PR may be merged by a single editor without a waiting period.

Manual addition proposals. A human contributor who believes a resource meets the inclusion criteria opens a pull request following the manual additions template. The PR must include:

Manual addition PRs require approval from at least two editors from at least two distinct organizations before merging, to prevent any single vendor or CDN operator from self-advantaging. The review window is fourteen calendar days from the date of the last substantive change to the PR; editors may close a PR for inactivity after ninety days without response from the submitter.

Source additions and retirements. Adding a new source to the pipeline (e.g., a new CDN or a second model hub) or retiring an existing one is a larger governance action. It requires a written proposal in the repository’s issue tracker explaining the source’s independence from existing sources, the methodology for determining which assets to include, and the anticipated effect on list size and composition. Source proposals require approval from all editors and a thirty-day public comment period. This higher bar reflects the fact that source changes affect the entire list composition, not a single entry.

Policy changes. Changes to the exclusion criteria, the download threshold, or other governance parameters follow the same process as source additions.

Handling disputes

If a contributor or consumer disputes an inclusion or exclusion decision made by the editors, they may escalate to the WHATWG Steering Group following the standard WHATWG escalation path. The Steering Group’s decision is final. Editors are expected to document the reasoning behind non-obvious decisions in the governance log so that disputes can be evaluated against a clear record rather than reconstructed from memory.

Signing and integrity

The canonical data file is signed using an infrastructure key held by the WHATWG, separate from any individual editor’s credentials. The signing key’s public half is published in the repository and in the WHATWG’s key registry. User agents that verify the signature before trusting the file are protected against: a compromised CDN edge that serves a modified file, a DNS hijack redirecting the canonical URL, and a compromised editor account that pushes an unsigned build. Signing does not, by itself, protect against a compromise of the WHATWG’s signing infrastructure; the reproducible build and the public audit log are the backstop for that scenario.

Relationship to the COS specification

The PHL is a normatively referenced companion artifact, not a normative part of the COS specification itself. The COS spec defines the interface contract (“user agents MUST treat hashes on the PHL as unconditionally eligible”), and the PHL is the live data artifact that satisfies that contract. This mirrors the relationship between the HTML spec and the MIME type registry, or between the Fetch spec and the WHATWG URL parser: the spec defines the semantics, the companion artifact is the authoritative instance. Concretely, the COS spec will point to the canonical PHL URL and specify the retrieval and verification protocol; the PHL governance document (this document) specifies what goes into the file and why.

Alternatives considered

Per-vendor proprietary allowlists. Each browser could curate its own list, maximizing control and shipping cadence. But it fragments the privacy guarantee (a resource shareable in one browser, gated in another), duplicates an expensive curation effort, is unauditable by outsiders, and carries obvious anti-competitive optics if a dominant vendor’s list favors its own CDNs. The PSL is the existence proof that a single cross-vendor list is both feasible and preferable for exactly this kind of privacy-boundary decision.

Hardcode the list into each browser binary. Simpler than an update channel, but it ties freshness to the release cadence, and the PSL ecosystem has repeatedly shown that stale embedded copies are a leading source of bugs and privacy regressions. A continuously updated, signed file (with a small hardcoded fallback for offline first-run) avoids this while keeping a safe default; and is the reason the rollout above is rolling rather than phased.

Key the registry by URL (SRI/import-map style) instead of by content hash. Familiar from Subresource Integrity and import maps, but it breaks the moment the same bytes appear at a different URL, forcing one logical resource into many entries and undercounting its true ubiquity. COS is content-addressed by design; the list must be too. (URLs still appear as provenance in comments, just not as the key.)

Reuse a single existing list, e.g. Chromium’s pervasive-resources list alone. It already exists and is already consulted by a shipping browser. The PHL instead aggregates it as one corroborating source among several, runs it through published exclusion filters, and cross-checks it against independent signals of ubiquity, using the prior art without inheriting its single-vendor scope.

Possible future directions

Further sources. As noted under Sources, unpkg and other Web-font providers are the obvious next additions, each gated by the same corroboration-and-exclusion methodology.

Acknowledgements

Many thanks to the following people, in alphabetical order, whose feedback and ideas have helped shape this proposal: