Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 12 additions & 8 deletions security/browser-headers/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,16 @@ The candidate is disabled and both approval flags remain false.
## Reviewed input and source prerequisite

`rust-policy.json` binds the accepted Rust 4.12.0 public crate and the
[protected documentation run](https://github.com/durable-workflow/sdk-rust/actions/runs/41954374074),
artifact 13382143373. Its ZIP SHA-256 is recorded with its tooling revision.
[protected documentation run](https://github.com/durable-workflow/sdk-rust/actions/runs/41959739724),
artifact 13384761426. Its ZIP SHA-256 is recorded with its tooling revision.
The full input contains 484 regular files and 372 HTML pages.

The earlier artifact's `help.html` and `settings.html` contained executable
links and inline history-back handlers. The generator refuses them. The merged
[SDK source correction](https://github.com/durable-workflow/sdk-rust/pull/207)
provides a safe crate-index fallback and an external history listener. The sole
automatic protected build and deployment for the current proposal are successful
at tooling revision `2b45fd7b12a6e9460666045a3c7f644860caea3b`. Public package/source
at tooling revision `46cf36514f7a39e819213771abf9efc82321c062`. Public package/source
identities remain unchanged. Eight live identity, navigation, help/settings and
API files matched this artifact on November 5, 2026. The
[current staging proposal](rust-stage-proposal.md) records their hashes and the
Expand All @@ -27,11 +27,13 @@ separate acceptance that remains pending.
The current inventory describes that accepted published artifact.
`source_preparation` is null. `history/` retains the earlier local derivative and
the accepted SDK #207 artifact's browser result as historical evidence only.
The derivative was not a public artifact. SDK #212 retains every page and asset
byte from the prior SDK #209 artifact.
Only the build identity changes. The executable script hashes and generated
rule are unchanged. That static comparison does not carry forward the earlier
browser pass. Current compatibility is unrun and the rule remains disabled.
The derivative was not a public artifact. Compared with accepted SDK #212,
SDK #211 changes exactly `__build.json`, `help.html` and `settings.html`. The two
utility pages only replace `workflow_testing` with `worker_latency` in generated
`data-current-crate` metadata. All 372 page-resource records, executable script
hashes and the parsed rule are unchanged. That static comparison does not carry
forward the earlier browser pass. Current compatibility is unrun and the rule
remains disabled.

## Policy and inventory

Expand Down Expand Up @@ -115,6 +117,8 @@ exact input bindings, ownership, proposed checks and rollback decision.
separately reviewable, unrun local browser/telemetry packet. Normal CI exercises
only its inert source controls. The optional browser entrypoint requires its
own exact run admission; it makes no provider or production request.
`rust-preparation-proposal.md` supplies the next separately reviewed acquisition
and immutable-image custody design. No acquisition, seal or prepared image exists.

## Rust-only staged acceptance and rollback

Expand Down
14 changes: 7 additions & 7 deletions security/browser-headers/rust-browser-validation.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@
"scope": "Current artifact source proposal only; browser, telemetry, TLS/HSTS and provider acceptance pending",
"input_artifact": {
"repository": "durable-workflow/sdk-rust",
"run_id": 41954374074,
"artifact_id": 13382143373,
"tooling_revision": "2b45fd7b12a6e9460666045a3c7f644860caea3b",
"zip_bytes": 4071521,
"zip_sha256": "15f1e2745a0b268e1093820b3486c4910e8d1bf7b63062e562200586d3beef95"
"run_id": 41959739724,
"artifact_id": 13384761426,
"tooling_revision": "46cf36514f7a39e819213771abf9efc82321c062",
"zip_bytes": 4067287,
"zip_sha256": "ea80b0d3191da525152b8f02ff2e3253a29ed93a723dfeae4c344eefb392cada"
},
"source_preparation": null,
"compatibility_accepted": false,
"historical_result": "history/rust-sdk207-browser-validation.json",
"next_action": "Security reviews the exact current-artifact proposal; General separately admits bounded compatibility and any later provider stage.",
"inventory_sha256": "01e0872a2d03726d52092362f7654285a81635f92f2f5bd30ecace505d14c71d",
"next_action": "Security reviews the exact current-artifact and preparation/custody proposal; General separately decides controller implementation, preparation and any later browser/provider stage.",
"inventory_sha256": "ad4b2134cf4bdb42b7dfabd58ba145567c8b4facd9d9652f9af5c61604beb60a",
"csp_sha256": "b002ffc9f95abc8145319d8a045aef9f0184d323d81ff9aec5a9de54d2f2d710"
}
22 changes: 11 additions & 11 deletions security/browser-headers/rust-inventory.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
"origin": "https://rust.durable-workflow.com",
"input_artifact": {
"repository": "durable-workflow/sdk-rust",
"run_id": 41954374074,
"artifact_id": 13382143373,
"tooling_revision": "2b45fd7b12a6e9460666045a3c7f644860caea3b",
"zip_bytes": 4071521,
"zip_sha256": "15f1e2745a0b268e1093820b3486c4910e8d1bf7b63062e562200586d3beef95"
"run_id": 41959739724,
"artifact_id": 13384761426,
"tooling_revision": "46cf36514f7a39e819213771abf9efc82321c062",
"zip_bytes": 4067287,
"zip_sha256": "ea80b0d3191da525152b8f02ff2e3253a29ed93a723dfeae4c344eefb392cada"
},
"source_preparation": null,
"build_identity": {
Expand All @@ -16,7 +16,7 @@
"version": "4.12.0",
"crate_sha256": "620a8287af73c363dac61f0a91f20971a39f3b8cdc9513fbea85cdbd95a74ba4",
"source_revision": "4b2440a5618ccc1c98960ea2e1e62127042c3590",
"tooling_revision": "2b45fd7b12a6e9460666045a3c7f644860caea3b"
"tooling_revision": "46cf36514f7a39e819213771abf9efc82321c062"
},
"files": [
{
Expand All @@ -27,7 +27,7 @@
{
"path": "__build.json",
"bytes": 332,
"sha256": "6338f8427799ac2cf9b0c2a1c08fcf1889b8887761f42c2d748dc0e0cfad8a8a"
"sha256": "3e8d1827d1df8bf3c47ee8f0efcbd2f3692cb1bd8741f40c1271ef5c74f4a183"
},
{
"path": "activity_options/all.html",
Expand Down Expand Up @@ -1601,8 +1601,8 @@
},
{
"path": "help.html",
"bytes": 3059,
"sha256": "a42b770a5c7d5743fb8c3d58cab134336aa9f81bffbc4b442f4ae259b2a678ae"
"bytes": 3057,
"sha256": "6169059db0e7b8c17267d47d59780af8ba387556a49ddc19d4841a0b296177de"
},
{
"path": "index.html",
Expand Down Expand Up @@ -1791,8 +1791,8 @@
},
{
"path": "settings.html",
"bytes": 3007,
"sha256": "3fc76ea7eba9ad08821dca786bf35a746a12c619af2020f1a45f452f1dee6a91"
"bytes": 3005,
"sha256": "977ba0a22dbb3352c07d82c18569203bd5b4636c2f2aa20fc55d5e7bc302cfb0"
},
{
"path": "src/activity_options/activity_options.rs.html",
Expand Down
16 changes: 8 additions & 8 deletions security/browser-headers/rust-local-browser-packet.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
"run_status": "not-run",
"input_artifact": {
"repository": "durable-workflow/sdk-rust",
"run_id": 41954374074,
"artifact_id": 13382143373,
"tooling_revision": "2b45fd7b12a6e9460666045a3c7f644860caea3b",
"zip_bytes": 4071521,
"zip_sha256": "15f1e2745a0b268e1093820b3486c4910e8d1bf7b63062e562200586d3beef95"
"run_id": 41959739724,
"artifact_id": 13384761426,
"tooling_revision": "46cf36514f7a39e819213771abf9efc82321c062",
"zip_bytes": 4067287,
"zip_sha256": "ea80b0d3191da525152b8f02ff2e3253a29ed93a723dfeae4c344eefb392cada"
},
"playwright_version": "1.64.0",
"expected_chromium_version": "156.0.8078.4",
Expand All @@ -27,9 +27,9 @@
"rust-browser.test.cjs": "0b2f731db13e4f095230673bfda3d97a36f71c5ef62b8f3702a7978740d17d61",
"rust-browser-inputs.cjs": "43bb050185f05187e7d94a40d73b4fae965276696fe7356e6609b319c6b120ee",
"rust-browser-source.test.cjs": "deafc5ce08806c148b189a48f11012cc0c03600122dd8fe34eb01e223f381952",
"rust-policy.json": "c2441f7b0bf7aebc0c4ee491cda0470170231bc8baf14b4c2163552b8d2fd79c",
"rust-inventory.json": "01e0872a2d03726d52092362f7654285a81635f92f2f5bd30ecace505d14c71d",
"rust-rule.candidate.json": "90b37562aabf6ed8619fbb488ad764137731bec976d8e2ff5e7bfa382fba5634",
"rust-policy.json": "49eeb47bcb9e437f9830a2f93c89ced80cb2dfe84306ebfcc122fdf3975d0231",
"rust-inventory.json": "ad4b2134cf4bdb42b7dfabd58ba145567c8b4facd9d9652f9af5c61604beb60a",
"rust-rule.candidate.json": "a20518e8341d94445cad433acb99e7e6e9ca42c837092248b83e10cf07540e08",
"runtime/package.json": "a2cd697a8ed17ab196e4eac1bcb15ceec6da243a600a8f2584c8aabdadfc3c9d",
"runtime/package-lock.json": "959580e91aae43c61d0bbfcf11c21eb52ecafcfadb088f166b322fd3988a47ae"
}
Expand Down
75 changes: 40 additions & 35 deletions security/browser-headers/rust-local-browser-plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,36 +11,38 @@ production operation is proposed here.
## Inputs and provenance

`rust-local-browser-packet.json` binds the executable/data closure and exact
runtime. Its artifact tuple is the accepted SDK #212 input already recorded in
`rust-policy.json`: artifact 13382143373, ZIP SHA-256
`15f1e2745a0b268e1093820b3486c4910e8d1bf7b63062e562200586d3beef95`,
runtime. Its artifact tuple is the accepted SDK #211 input already recorded in
`rust-policy.json`: artifact 13384761426, ZIP SHA-256
`ea80b0d3191da525152b8f02ff2e3253a29ed93a723dfeae4c344eefb392cada`,
484 files / 372 HTML pages / 49 inline-script hashes. Public Rust 4.12.0 crate
and source identities are preserved; tooling matches the accepted SDK #212
build. The parsed rule, policy sources, approval flags and unrun status remain
unchanged. Input provenance fields now bind this artifact.
and source identities are preserved; tooling matches the accepted SDK #211
build. Only build identity and two utility-page metadata attributes change from
#212; all 372 page records and executable hashes stay equal. The parsed rule,
policy sources, approval flags and unrun status remain unchanged. Input
provenance fields now bind this artifact.

The proposed runtime is the existing Playwright 1.64.0 generation, pinned to the
official **linux/amd64** platform manifest in the packet. Registry metadata was
read without pulling or running that browser image. `runtime/package-lock.json`
records the two exact npm archives and integrity values. Only package-lock resolution, advisory metadata and inert source checks were
performed during this preparation. No
Playwright package, browser image or browser was executed for the source packet.

After separate admission, prepare a dedicated public dependency directory with
`runtime/package.json` and its lock. Use `npm ci --ignore-scripts --no-audit
--no-fund` with `PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1`. Do not run lifecycle hooks,
`playwright install`, `npx` downloads or an image build. Verify the approved image
manifest/config, library version and lock integrity. Mount only its prepared
`node_modules` directory into the browser cell. No home directory, credentials,
Docker socket or unrelated repository is an input. An unavailable dependency,
different platform or runtime mismatch stops the attempt for review.
records the two exact npm archives and integrity values. Earlier source review
resolved the lock, read advisory/registry metadata and ran inert source checks.
This retarget performed only data/source and raw HTTPS checks. No Playwright
package, browser image or browser was executed for this source packet.

The next preparation decision requires separate review of
[`rust-preparation-proposal.md`](rust-preparation-proposal.md): fixed public
archive acquisition, no npm or package execution, and verified data-only
construction of an image containing all three public input trees. It replaces
the earlier suggested npm-ci path. No image or dependency has been acquired,
prepared or sealed. A separately reviewed controller and cleanup implementation
is required before any acquisition/preparation admission.

Before execution, independently verify the ZIP digest and safe regular-file
membership, recheck the accepted protected-run/deployment identity and compare
live `__build.json` with the exact artifact. Those are finite read-only checks.
Stop if the live input has changed, the artifact has expired, or a required input
is unavailable. Do not dispatch a replacement build or silently retarget the
packet. The input API expires this ZIP on November 6, 2026 at 02:19:51 UTC.
packet. The input API expires this ZIP on November 6, 2026 at 03:10:05 UTC.

## What the proposed check exercises

Expand Down Expand Up @@ -79,7 +81,7 @@ Playwright, launches a browser or runs the optional browser entrypoint.
requires verification outside Node before any packet code is loaded. The
in-process check cannot authenticate code that is already executing. The exact
current packet SHA-256 is
`2060309bf48d3e179abf55c0f2e1ffbc4908fcd7227b0cc4eb11089afde71f2a`.
`c6c735624906c4680d162ba989ebd55f00a8124e6d8ca72f781f8fee646ae281`.

Before any separate preparation/run admission, General and Security must bind
an approved write-preventing mechanism and exclusive owner for all three public
Expand Down Expand Up @@ -111,7 +113,7 @@ assert not root.is_relative_to(Path.home())
manifest_path = root / 'rust-local-browser-packet.json'
assert stat.S_ISREG(manifest_path.lstat().st_mode)
manifest_bytes = manifest_path.read_bytes()
expected = '2060309bf48d3e179abf55c0f2e1ffbc4908fcd7227b0cc4eb11089afde71f2a'
expected = 'c6c735624906c4680d162ba989ebd55f00a8124e6d8ca72f781f8fee646ae281'
assert hashlib.sha256(manifest_bytes).hexdigest() == expected
manifest = json.loads(manifest_bytes)
assert manifest['run_status'] == 'not-run' and len(manifest['files']) == 8
Expand Down Expand Up @@ -143,17 +145,13 @@ This check is an integrity prerequisite. It does not create a seal or approve an
attempt. Record the separate write-prevention/custody proof and recheck the
mounts and cached image immediately before creating the admitted cell.

Dependency preparation is separately held. Its future admitted environment
must have a container-only empty home, distinct empty user/global npm config
files, a task-private cache, a public registry and an explicit environment
allowlist. No host home/profile, `.npmrc`, token, credential directory or secret
proxy setting may be inherited. Set `PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1` and
`--ignore-scripts`; use the exact lock and verify both archive integrity values
and library version. Do not import Playwright during preparation. Enumerate and
hash the resulting dependency tree, reject external links, then establish its
approved immutable/exclusive custody before any browser code resolves it.
No such environment, dependency tree or seal has been created by this source
retarget. Missing preparation/image/custody proof leaves execution held.
Dependency/image acquisition and custody are separately held. The new preparation
proposal specifies explicit credential-free transport, exact archive integrity,
safe dependency closure, a sealed memory descriptor for transfer, never-started
assembler/readback containers and a content-addressed derived image. Those
mechanisms do not exist yet and require review/admission. Preparation alone
would load no Node/Playwright code. The external hash check above remains a
prerequisite and does not itself create immutable custody.

## Proposed execution and cleanup

Expand All @@ -166,9 +164,16 @@ There is no automatic retry, host IPC, privileged mode, extra capability or
published port. The writable tmpfs and private shared memory count within the
container's memory cap. This is a proposed budget, not a reservation.

The following is the exact proposed launch shape after admission, the external
pre-load hash check and accepted custody proof above. Assign the
three absolute input paths from the reviewed public-input preparation; reject
The following retains the earlier mount-based launch shape as historical design
only. It is **not eligible for a next browser attempt**: the new preparation
proposal replaces all three host input mounts with a verified immutable image.
After separately accepted preparation, a source successor must bind the actual
derived image ID and zero-input-mount launch shape before browser admission.
No derived image ID exists, so this document cannot authorize that launch.

The earlier shape required the external pre-load hash check and accepted custody
proof above. It assigned three absolute input paths from reviewed public-input
preparation and rejected
commas/newlines in those paths. `packet_directory` contains only this public
packet. `runtime_modules` is the prepared public dependency tree. Do not point
either at a home or credential directory. The pinned image must already exist;
Expand Down
12 changes: 6 additions & 6 deletions security/browser-headers/rust-policy.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@
"version": "4.12.0",
"source_revision": "4b2440a5618ccc1c98960ea2e1e62127042c3590",
"crate_sha256": "620a8287af73c363dac61f0a91f20971a39f3b8cdc9513fbea85cdbd95a74ba4",
"tooling_revision": "2b45fd7b12a6e9460666045a3c7f644860caea3b"
"tooling_revision": "46cf36514f7a39e819213771abf9efc82321c062"
},
"input_artifact": {
"repository": "durable-workflow/sdk-rust",
"run_id": 41954374074,
"artifact_id": 13382143373,
"tooling_revision": "2b45fd7b12a6e9460666045a3c7f644860caea3b",
"zip_bytes": 4071521,
"zip_sha256": "15f1e2745a0b268e1093820b3486c4910e8d1bf7b63062e562200586d3beef95"
"run_id": 41959739724,
"artifact_id": 13384761426,
"tooling_revision": "46cf36514f7a39e819213771abf9efc82321c062",
"zip_bytes": 4067287,
"zip_sha256": "ea80b0d3191da525152b8f02ff2e3253a29ed93a723dfeae4c344eefb392cada"
},
"sources": {
"script": [
Expand Down
Loading
Loading