v147 · developer trial · workers · security
Document Policy in Dedicated Workers
Chrome 147 adds developer trial support for Document-Policy in dedicated workers. A network-loaded worker reads its policy from its own script response, not the creating page’s response; only local blob: and data: workers clone their creator’s policy.
chrome://flags/#enable-experimental-web-platform-features, or launch with --enable-blink-features=DocumentPolicyInDedicatedWorker (the runtime flag is DocumentPolicyInDedicatedWorker, status experimental in Chromium’s runtime_enabled_features.json5, checked 2026-10-04). The API surface may change before it ships. Do not use in production.
at a glance
| Status in Chrome 147 | Developer trial (behind a flag); dev-trial milestone 147 per the ChromeStatus API record (stage desktop_first: 147), announced in the DevTrial announcement document |
|---|---|
| Flag | enable-experimental-web-platform-features / --enable-blink-features=DocumentPolicyInDedicatedWorker |
| Spec | WICG Document Policy (Draft Community Group Report) + HTML Standard integration in whatwg/html PR #12026 |
| Explainer | Document Policy in Workers (MSEdgeExplainers) |
| Intent thread | blink-dev thread (the prototype-stage intent recorded on ChromeStatus) |
| Tracking bug | issues.chromium.org/issues/450845903 |
| ChromeStatus | 6242687411945472 — Document Policy in Dedicated Workers |
what is Document Policy?
Document Policy is an HTTP header (Document-Policy: directive=value) that allows servers to enforce or opt into behaviours for a document. Example directives include:
force-load-at-top— prevent JavaScript from scrolling the document to a mid-page position on loadlossless-images-max-bpp— enforce maximum bits-per-pixel for lossless imagesoversized-images— enforce a maximum image display/intrinsic size ratiojs-profiling— opt into the JS Self-Profiling API; the worker use case that motivated this feature (see WICG/js-self-profiling#33)
Previously, these policies were defined for documents and iframes, not workers. In this dedicated-worker proposal, a network worker uses the policy declared by its script response and ignores the creating page’s policy; a local blob: or data: worker instead clones its creator’s policy. That distinction matters when configuring a server: a page response header alone cannot opt a network worker into js-profiling.
syntax
This feature adds no new header and no new JavaScript API — it changes where the existing Document-Policy response header is read from (the worker script’s own HTTP response). The header keeps its syntax from the WICG Document Policy draft, §7.2.1, which defines it as a Structured Header whose value “must be a dictionary”:
# ABNF, quoted verbatim from WICG Document Policy §7.2.1
Document-Policy = sf-dictionary
Each dictionary member is a document policy directive: a directive name (an sf-token naming a configuration point, or *) with optional parameters — any directive may carry a report-to parameter, and integer/float/enum configuration points carry a required value parameter. The spec’s own directive examples (§7.1, verbatim):
boolean-feature
boolean-feature=?0
integer-feature=2
float-feature=-0.2
enum-feature=state
What Chrome 147’s developer trial changes is how a dedicated worker obtains its policy. Per the explainer (semantics for dedicated workers, quoted verbatim):
- “For network scripts: Parse
Document-Policyfrom the worker script’s HTTP response headers” - “If no
Document-Policyheader is present: Each feature uses its spec-defined default value (same as document contexts)” - “For local schemes (blob:, data:): Worker clones the creator’s Document Policy, since no HTTP response exists to consult (blob: URLs clone from the environment that created the blob, data: URLs clone from the document that created the worker)”
The worker’s effective policy is taken only from the script response for network workers — the explainer is explicit that “any creator policy is ignored (no merge/intersection)”. The spec change lands via the HTML Standard’s policy container: whatwg/html PR #12026 (“Add DP to policy-container” + “add fallback case” per the PR patch), aligning with initialize a worker’s policy container.
Source: WICG Document Policy §7.2.1; §7.1 Policies as Structured Headers; explainer; whatwg/html PR #12026 (all fetched 2026-10-04)error handling
The header has no exception surface in JavaScript — failures are absorbed by the parsing rules:
- Unknown or malformed directives are ignored. The WICG draft, §7.2.1 specifies that any dictionary member that does not name a supported configuration point (or the special value
*) is ignored by the processing steps; a directive whose value falls outside the configuration point’s range likewise fails structured-field parsing rather than throwing in script. - An absent header is not an error. Per the explainer (verbatim): “If the response lacks a
Document-Policyheader, the feature falls back to its spec-defined default (for js-profiling, typically off)” — the observable failure mode is the gated API being unavailable in the worker (e.g.Profileris not constructible), not an exception from the policy machinery itself. - Documented unknown — violation reporting in workers. Whether the
report-toparameter and theDocument-Policy-Report-Onlyheader operate in worker contexts is not specified by either the WICG draft (its reporting sections predate the worker extension) or the worker policy-container PR; both were checked on 2026-10-04. This page records that as unknown rather than inventing behaviour.
examples
Serve the worker script (not just the page) with a Document-Policy header — the explainer’s example (verbatim):
Document-Policy: js-profiling
The page can then create that dedicated worker; this client-side call is illustrative glue, not a verbatim snippet or a runtime test from the explainer. The header above belongs on the worker script response, regardless of whether the page response has its own policy:
const worker = new Worker("/worker.js");
“If Document-Policy is enabled in the worker, developers can use the Profiler” (explainer example, verbatim):
// Start a profiling session
const profiler = new Profiler({ sampleInterval: 10, maxBufferSize: 10_000 });
doWork();
const trace = await profiler.stop();
console.log(JSON.stringify(trace));
new Worker() call is gendn-derived to illustrate the network-worker response model (checked 2026-10-08). The explainer does not specify a page-response example.
browser compatibility
mdn/browser-compat-data has no entry for the Document-Policy header (checked BCD v8.1.4, published 2026-10-01, on 2026-10-04: its http/headers/ tree has no Document-Policy.json, and no key anywhere in the compiled data mentions it), so the table below is interim, built from the ChromeStatus API record rather than BCD per-version data:
| Browser | Document Policy in dedicated workers | Notes (interim, non-BCD) |
|---|---|---|
| Chrome | 147 — developer trial, behind a flag | ChromeStatus dev-trial stage desktop_first: 147; overall status “Proposed”; runtime flag DocumentPolicyInDedicatedWorker (experimental) |
| Edge | Not shipped | Proposal authored by Microsoft Edge (explainer owners); no shipped support recorded |
| Firefox | No signal | ChromeStatus Firefox view: “No signal”, no standards-position link filed |
| Safari | No signal | ChromeStatus Safari view: “No signal”, no standards-position link filed |
For the motivating gated API, BCD does have per-version data: BCD api/Profiler.json records Profiler (JS Self-Profiling) as Chrome/Edge 94, Firefox not shipped (bug 1867361), Safari not shipped — so even once workers honour Document-Policy: js-profiling, profiling remains Chromium-only.
specifications
| Specification | Status |
|---|---|
| Document Policy — §7.2.1 The Document-Policy HTTP header | Draft Community Group Report (WICG) |
| HTML Standard — whatwg/html PR #12026 “Add DP to policy-container” | Pull request (authored 2025-12-16 by the feature owner; merge state not re-verified from this environment, 2026-10-04 — ChromeStatus records maturity “Working draft”) |
security and privacy
From the explainer’s Privacy and Security Considerations (quoted verbatim): “Document Policy inheritance is limited to local URLs (blob:, data:), consistent with the HTML policy container model, this prevents cross-origin policy leakage”; “Inherited policies cannot expand privileges beyond what the creator or script origin allows”; “Worker script responses define the effective policy, ensuring each origin controls its own features”; and “The proposal adds no new fingerprinting or cross-origin exposure surfaces.” The response-driven model exists precisely so that a creating document’s policy cannot be imposed on a cross-origin worker script — each origin gates its own features through its own headers.
Source: Document Policy in Workers explainer — Privacy and Security Considerationssee also
- Chrome Platform Status — Document Policy in Dedicated Workers
- WICG Document Policy specification
- Explainer: Document Policy in Workers (MSEdgeExplainers)
- WICG/js-self-profiling#33 — “How does document policy work in workers?” (initial public proposal)
- Chromium tracking bug 450845903
- blink-dev intent thread
- chrome-platform-showcase: Document Policy in Dedicated Workers demos (five concepts, every route GET-verified 200, 2026-10-04)