Skip to content

feat(ceremony): implement browser identity ceremonies - #28

Open
Wondertan wants to merge 125 commits into
mainfrom
feat/ceremony-rebuild-plan
Open

Wondertan wants to merge 125 commits into
mainfrom
feat/ceremony-rebuild-plan

Conversation

@Wondertan

@Wondertan Wondertan commented Sep 7, 2026

Copy link
Copy Markdown
Member

Implements @libid/ceremony over a caller-supplied @libid/popup connection, with Google, X and GitHub v1 pipelines and a static CCDP distribution. Application owns popup lifetime and downstream submission. Prover keeps OAuth returns private, generates proofs and attestations, and returns a separate identity; Client structurally validates and assembles the result without browser cryptographic verification.

The shared Browser tests job runs the popup, ceremony and dev-app suites; this PR contains no duplicate CI job. Normative browser contracts remain in #13, on popup spec #22, with #31's framing rules and #35's browser GitHub profile. This PR owns implementation documentation and preserves all 158 test requirement IDs.

A single operation feed drives readiness, UI and measurements. Callback forwards popup's authenticated Application origin privately to Prover; Prover admits exactly that origin. Prefetch and execution share declared resources and emitted dependencies. Backend/input preparation, notarization and proof work overlap while final delivery waits for all required outputs. X and GitHub perform both token and identity exchanges through browser notary sessions. Bridge supplies the public GitHub clientCredential; Client derives fixed /auth/callback from its Bridge origin. The shared dev app runs the updated Bridge/notary/CCDP services, supports concurrent manual ceremonies, and displays collapsible operation measurements and distinct interruption outcomes.

Release qualification remains incomplete. Automated coverage includes real fixture proofs and matched-notary concurrency. Manual runs confirm live Google, X and GitHub ceremony completion on desktop and mobile, and real-verifier acceptance for all three platforms. Physical-device edge cases, complete resource accounting and the optional WebRTC implementation remain qualification gaps; see the qualification guide.

@SupremaLex

Copy link
Copy Markdown
Member

Ran this branch (0469056) end to end with a real GitHub OAuth app, a local
Notary and a local Bridge. Two problems in the browser package.

1. GitHub sends iss and the parser rejects the whole return

Created a fresh GitHub OAuth app for the test. The callback came back with an
iss parameter. The parser has no case for it, so auth failed straight away —
before any token exchange.

src/platforms/codeReturn.ts:20

if (key !== 'state' && key !== 'code' && key !== 'error') return null

What GitHub sent (keys only): code, iss, state

Any unknown key makes parseCodeOAuthReturn return null, and
platforms/github/1/prover.ts:37 then throws Invalid GitHub return. The
cancel path breaks the same way — error, iss, state is rejected too.

iss is the issuer identifier from RFC 9207. Rather than just adding it to the
allowlist, it may be worth checking its value against the expected issuer —
that is what it is for.

2. Errors are thrown away, so this was hard to find

fail takes no argument:

const fail = () => {          // src/ccdp/documents/prover.ts:36

so .catch(fail) at line 116 gets the error and drops it. There are six empty
catch blocks in the two CCDP documents — prover.ts:42,72,96,133 and
prefetch.ts:25,29. Each ends in a fixed message:

Unable to complete proof. Return to your application.
Unable to prepare. Return to your application.

The user sees that, the browser console is empty, and no server logs anything,
because it fails before any request goes out. A broken OAuth parser and a broken
service worker look identical from outside.

Smallest fix: catch (e) and log it. Better: pass a reason into fail and put
it in the abort-ceremony message, which already has a reason field that is
always a constant today.

With iss accepted locally, the ceremony gets through consent, the callback,
the Bridge token exchange and a real MPC-TLS session with github.com. It then
fails in the Notary's attestation step — reported on libid-org/notary#6.

@Wondertan Wondertan changed the title feat(ceremony): rebuild browser package around supplied popup connections feat(ceremony): implement browser identity ceremonies Sep 12, 2026
@Wondertan
Wondertan force-pushed the feat/ceremony-rebuild-plan branch 2 times, most recently from 76c2e71 to facce8b Compare September 13, 2026 13:48
@Wondertan
Wondertan force-pushed the feat/ceremony-rebuild-plan branch from facce8b to d7871b4 Compare September 13, 2026 14:00
@Wondertan
Wondertan force-pushed the feat/ceremony-rebuild-plan branch 2 times, most recently from c3aec3a to 9f1cd69 Compare September 13, 2026 19:13
@Wondertan
Wondertan marked this pull request as ready for review September 13, 2026 20:01
@Wondertan
Wondertan changed the base branch from feat/popup-package to main September 13, 2026 20:03
@Wondertan
Wondertan requested a review from xgreenx September 13, 2026 20:47
@Wondertan
Wondertan force-pushed the feat/ceremony-rebuild-plan branch from 6e5fe4b to 5357174 Compare September 15, 2026 13:16
@Wondertan
Wondertan changed the base branch from main to feat/popup-closure September 15, 2026 13:17
Base automatically changed from feat/popup-closure to main September 15, 2026 13:25
@Wondertan
Wondertan force-pushed the feat/ceremony-rebuild-plan branch from 5357174 to 8433200 Compare September 15, 2026 13:28
…p connections

Implement the current CCDP actors, platform proof pipelines, byte-prefetch graph and static distribution. Add real browser proof and loader qualification, focused security regressions, and explicit remaining launch gates.

Assisted-by: GPT-6
Signed-off-by: Wondertan <hlibwondertan@gmail.com>
Move Callback, Prefetch and Prover entrypoints under ccdp/documents while keeping proving and cache implementations in their existing modules. Update build paths, exports and package maps, and remove the requested plan artifacts.

Assisted-by: GPT-6
Signed-off-by: Wondertan <hlibwondertan@gmail.com>
Return from the provider fixture only after the test observes it. Preserve the real keeper-expiry delay without racing two automatic navigations.

Assisted-by: GPT-6
Signed-off-by: Wondertan <hlibwondertan@gmail.com>
Keep the request fixture alive until the held circuit is released, including after assertion failures and test timeouts, so one migration test cannot stall later ceremonies.

Assisted-by: GPT-6
Signed-off-by: Wondertan <hlibwondertan@gmail.com>
Keep each fixture ceremony timeline and popup diagnostics separate. On failure, report the pending notary operation or each popup status without logging OAuth returns, transcripts, or proof data.

Assisted-by: GPT-6
Signed-off-by: Wondertan <hlibwondertan@gmail.com>
Use one request-owned fixture for held downloads and simulated HTTP failures. Restore the server state even when the timed-out test body cannot finish its finally block, preventing later tests from receiving stale 503 responses.

Assisted-by: GPT-6
Signed-off-by: Wondertan <hlibwondertan@gmail.com>
Activate both root and nested keepers before opening isolation fixtures. This keeps cold worker startup out of the bounded automatic handoff while preserving the nested-registration and single-delivery assertions.

Assisted-by: GPT-6
Signed-off-by: Wondertan <hlibwondertan@gmail.com>
Print HTTP and TLS prover milestones when real concurrency qualification fails, and retain the matched notary service output. Keep the existing deadlines and assertions.

Assisted-by: GPT-6
Signed-off-by: Wondertan <hlibwondertan@gmail.com>
The pinned WASM adapter catches exceptions but discards write promises. Preserve synchronous WebSocket errors so failed writes cannot appear successful to TLSNotary.

Assisted-by: GPT-6
Signed-off-by: Wondertan <hlibwondertan@gmail.com>
Build the pinned keeper and notary 0.2.0 pair with the upstream fix for clean driver completion during final verification. Preserve their dependency lockfiles and legacy wire format while the matching released images are unavailable.

Assisted-by: GPT-6
Signed-off-by: Wondertan <hlibwondertan@gmail.com>
Use the browser's document event instead of a timeOrigin comparison: WebKit can vary the reported clock within the same document, allowing assertions to observe the departing page.

Assisted-by: GPT-6
Signed-off-by: Wondertan <hlibwondertan@gmail.com>
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Sep 15, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
❌ Deployment failed
View logs
libid 08c3f3d Sep 23 2026, 01:56 PM

Remove the Rust backport and local image builds so the ceremony PR leaves the legacy claim harness unchanged.

Assisted-by: GPT-6
Signed-off-by: Wondertan <hlibwondertan@gmail.com>
Use native base64 primitives while preserving canonical validation. Remove unused declarations, unreachable handling and redundant build state.

Assisted-by: GPT-6
Signed-off-by: Wondertan <hlibwondertan@gmail.com>
Remove the unused Vitest configuration and outdated setup text. Ignore Playwright output consistently across workspace packages.

Assisted-by: GPT-6
Signed-off-by: Wondertan <hlibwondertan@gmail.com>
Record the passing hosted checks, retain outstanding qualification gates and update local notary examples. Remove the obsolete contract-update link.

Assisted-by: GPT-6
Signed-off-by: Wondertan <hlibwondertan@gmail.com>
@Wondertan

Copy link
Copy Markdown
Member Author

@xgreenx, claim pkg is unrelated to this PR and thus the new commit on this branch... Force push it away

@Wondertan
Wondertan force-pushed the feat/ceremony-rebuild-plan branch from f99aa38 to e633486 Compare September 21, 2026 09:50
Use the selected worker once active and rely on the existing dispatch
acknowledgement, since WebKit can retain activating state in another document.
Keep waiting for newer installing workers and cover both cases with regressions.

Record the remaining upstream pre-handshake EOF qualification gap.

Assisted-by: GPT-6
Signed-off-by: Wondertan <hlibwondertan@gmail.com>
Capture available popup state without waiting for a body element, and retain the original assertion when either document is unavailable. Print complete run diagnostics for CI failures.

Assisted-by: GPT-6
Signed-off-by: Wondertan <hlibwondertan@gmail.com>
Match the notary 0.3.1 server and browser WASM, and consume circuits 0.4.0
with the existing matched Noir/bb toolchain. Keep the newer Bridge pin.

Provide the notary's required forwarded client IP through a standard local
proxy and use native amd64/arm64 images. Open session sockets after shared
WASM startup so the new first-data deadline cannot expire during loading;
per-session TLS setup remains concurrent.

Record real browser proof/notary and loader qualification. Adoption of the
unreleased provider-connection fixes remains a separate release bump.

Assisted-by: GPT-6
Signed-off-by: Wondertan <hlibwondertan@gmail.com>
Update the matched browser WASM and notary server release. Use peer mode directly in local development and browser qualification, remove Caddy, and record the concurrent proof and delayed-send checks.

Assisted-by: GPT-6
Signed-off-by: Wondertan <hlibwondertan@gmail.com>
Remove release narratives, obsolete failure notes and migration history. Keep current integration pins, verified coverage and remaining qualification requirements, preserving all stable test IDs and documenting the closed lifecycle accurately.

Assisted-by: GPT-6
Signed-off-by: Wondertan <hlibwondertan@gmail.com>
Apply one ten-second budget from send through final attestation. Expiry rejects pending and sibling work through the existing worker cleanup path. Cover real socket and worker shutdown in all three browser engines, plus failure delivery while ZK work remains pending.

Assisted-by: GPT-6
Signed-off-by: Wondertan <hlibwondertan@gmail.com>
Record successful live Google, X and GitHub ceremonies on desktop and mobile, and real verifier acceptance for all three platforms. Keep unqualified failure and device cases explicit and clarify the shared bearer circuit limit.

Assisted-by: GPT-6
Signed-off-by: Wondertan <hlibwondertan@gmail.com>
Assisted-by: GPT-6
Signed-off-by: Wondertan <hlibwondertan@gmail.com>
Assisted-by: GPT-6
Signed-off-by: Wondertan <hlibwondertan@gmail.com>
Assisted-by: GPT-6
Signed-off-by: Wondertan <hlibwondertan@gmail.com>
@Wondertan
Wondertan changed the base branch from main to feat/popup-origin-wildcards September 23, 2026 13:56
Base automatically changed from feat/popup-origin-wildcards to main September 23, 2026 14:49

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants