feat(e2ee): pair a browser device with the native daemon through the worker barrier - #435
Conversation
…worker barrier The browser binding could register a device endpoint but could not take part in native pairing, and its witness barrier existed only in tests. A phone web client needs both, plus a build that trusts a real witness. Pairing (Rust, shared with the browser): - PairingClaimV1::create_at and Phone::join_published_welcome build for wasm32. The activation payload moves to pairing::pair_activation_payload so native and browser sign the same bytes. - BrowserEndpoint gains pairing_claim (a deterministic claim over the registered KeyPackage for a matching invitation, refused once a transaction is pending or the image has joined), join_published (kind 8 over the daemon's published Welcome with the daemon as inviter), and prepare_pair_activation (kind 9 over the native activation payload, so the daemon's accept_activation verifies it unchanged). - A browser test pairs with the native daemon lifecycle end to end: submit, confirm, Welcome, join, activation, messages both ways, and the identity, ordering, and replay refusals. Replica trust configuration: - ReplicaTrustSet::decode_config/encode_config define a canonical, bounded byte form (version, three replicas, one to four keys each). - The Node test artifact can build daemon and device endpoints from a configured trust, and a test shows receipts from unnamed replicas never complete an operation. Worker barrier and page surface: - worker/barrier.js runs fresh read, reconcile, mutate, continue against the fixed same-origin /v1/e2ee/witness path. The credential enters once through authorizeWitness() and never leaves the worker; the page sees only exact released results. - The loader exposes createDeviceEndpoint/openDeviceEndpoint handles with pairingClaim, joinPublished, preparePairActivation and the existing device mutations. Production creation still fails with rollback_anchor_unavailable because production names no trust. - A registration that fails certification releases the worker's endpoint so the page reopens it; the next call recovers the committed request. Deployment-test artifact: - `build.mjs deployment-test` is the production artifact with every module byte-identical except worker/trust.js, which loads trust/replica-trust.bin pinned by size and SHA-256 in integrity.json. Trust is never read from a link, query, or page input. check-abi verifies the byte identity, the export delta, and that production still names no trust. - `pnpm test:deployment` pairs a real browser with a native daemon through that artifact and the same-origin witness path, then exchanges messages both ways and reopens the endpoint. CI runs it for every browser in the matrix. Signed-off-by: Lokesh <lokeshselvam7025@gmail.com>
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Advanced Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.Scanned FilesNone |
Summary
This is the first step toward
/remotefrom a phone web browser. The browser binding could register a device endpoint, but it could not take part in native pairing, and its witness barrier existed only in tests. This PR closes both gaps and adds a build that trusts a real witness.Pairing (Rust, shared with the browser)
PairingClaimV1::create_atandPhone::join_published_welcomenow build for wasm32.pairing::pair_activation_payload, so native and browser sign identical bytes.BrowserEndpointgains three operations:pairing_claim: a deterministic claim over the registered KeyPackage for a matching invitation. It is refused once a transaction is pending or the image has joined.join_published: kind 8 over the daemon's published Welcome, with the daemon as the expected inviter.prepare_pair_activation: kind 9 over the native activation payload. The daemon'saccept_activationverifies it unchanged.Replica trust configuration
ReplicaTrustSet::decode_configandencode_configdefine a canonical, bounded byte form: version, three replicas, one to four keys each.Worker barrier and page surface
worker/barrier.jsruns fresh read, reconcile, mutate, continue against the fixed same-origin/v1/e2ee/witness.authorizeWitness()and never leaves the worker. The page receives only exact released results, never requests, certificates, or credentials.createDeviceEndpoint/openDeviceEndpointhandles for pairing and every supported device mutation.rollback_anchor_unavailable.worker/trust.jsnames no trust, and check-abi enforces that.Deployment-test artifact
build.mjs deployment-testproduces the production artifact with every module byte-identical exceptworker/trust.js. That module loadstrust/replica-trust.bin, pinned by size and SHA-256 inintegrity.json.deployment_test_replica_trust), and the absence of test identifiers.pnpm test:deploymentpairs a real browser with a real native daemon through that artifact and a same-origin witness. It then exchanges messages both ways and reopens the endpoint. CI runs it for each browser in the matrix.The AWS side of the witness is in #434.
Known risk (not fixed here)
KeyPackages carry
not_before= the device's clock. A daemon whose clock is behind the phone's by more than the pairing window rejects the claim asKeyPackage. The browser pairing test advances the daemon clock by 2 s to model a small skew. A real phone with a fast clock could hit this, so it needs a tolerance decision before phone testing.Test plan
cargo fmt --check; clippy-D warningsin all CI configurations, plus wasm32--features deployment-testcargo test -p axl-e2ee: 145 passed withbrowser-test-fixtures, 133 withnode-test-fixtures, includingbrowser_device_pairs_with_the_native_daemon_lifecycleand the trust-config round tripbuild/build:test/deployment-test,check:abi,check:typespnpm test:deployment: passed on Chromium and Firefox. WebKit could not launch locally because of missing host libraries, so CI covers it.