Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
3583f5c
docs(specs): the token request reveals its headers, and the verifier …
xgreenx Sep 9, 2026
6f9c3a5
docs(specs): the token request's Content-Length, and the line endings…
xgreenx Sep 9, 2026
31680fa
docs(specs): the header set, not its order
xgreenx Sep 9, 2026
27aaf90
docs(specs): the identity requests carry their headers in any order too
xgreenx Sep 9, 2026
ba4b280
docs(specs): the token request is one revealed range, its fields are …
xgreenx Sep 9, 2026
d58930a
docs(specs): GitHub's identity request needs a user-agent
xgreenx Sep 10, 2026
3acbf4a
docs(specs): the identity request may carry headers nothing compares
xgreenx Sep 10, 2026
a76d547
docs(specs): the token request's head is held to a subset, not a set
xgreenx Sep 10, 2026
e74a9c7
docs(specs): one keyword per sentence in REQ-PLAT-56A
xgreenx Sep 10, 2026
070f0ea
docs(specs): say how the token head is normalized before comparison
xgreenx Sep 10, 2026
41cbe59
docs(specs): count every authorization header, and forbid on both req…
xgreenx Sep 10, 2026
59c66fe
docs(specs): the head boundary is one, and the length has one spelling
xgreenx Sep 10, 2026
d8a66b7
docs(specs): the reader removes JSON whitespace before it matches
xgreenx Sep 11, 2026
44e9574
Merge token framing specification prerequisite (#31)
Wondertan Sep 12, 2026
eeed0bc
docs(specs): reconcile browser validation ownership
Wondertan Sep 12, 2026
1c1a885
docs(specs): extract CCDP and ceremony service contracts
Wondertan Sep 12, 2026
0fd7f0a
docs(ccdp): separate denial from local cancellation
Wondertan Sep 13, 2026
01d5fb0
docs(ccdp): group event instrumentation fields
Wondertan Sep 13, 2026
d266091
docs(ccdp): clarify denial and failure message names
Wondertan Sep 13, 2026
596ceb3
docs(ccdp): allow notary inputs across platform profiles
Wondertan Sep 13, 2026
5b46008
docs(specs): reconcile CCDP with existing contracts
Wondertan Sep 13, 2026
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
415 changes: 415 additions & 0 deletions specs/ccdp-distribution.md

Large diffs are not rendered by default.

879 changes: 879 additions & 0 deletions specs/ccdp.md

Large diffs are not rendered by default.

108 changes: 88 additions & 20 deletions specs/ceremony-common.md
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,14 @@ identity-platform signing root, notary key, Platform Verifier, verifier governan
browser supply chain, or Consumer Chain invalidates the properties that depend
on it.

Browser result acceptance is not ledger verification. Prover performs canonical
parsing and local request/commitment consistency checks; Application validates
the delivered structure. Neither performs local notary-signature verification
or a separate Google nonce-versus-expected-digest comparison. Well-formed
mismatches or forgeries can survive those browser checks but still fail the
applicable downstream proof, digest-binding, trusted signing-key, or
notary-signature check before an authoritative effect.

- SP-BIND-01:
Evidence produced by a ceremony discharges only for the Authorized
Transaction Data committed in its Authorization Digest. Depends on
Expand All @@ -237,15 +245,18 @@ on it.
conformance tests (supporting, not proving) plus the collision resistance of
SHA-256 and keccak256.
- SP-CLIENT-01:
The Canonical Runtime rejects evidence issued to an OAuth client other than
the one fixed by its immutable ceremony profile. Depends on ASM-PROV-04,
The browser Prover rejects a parsed OAuth client identifier differing from
the one fixed by its immutable ceremony profile. This checks local consistency,
not the authenticity of an attestation's claimed identifier; ledger
verification authenticates that identifier independently. Depends on ASM-PROV-04,
ASM-PROV-05, ASM-PROV-07, ASM-NOTARY-01, ASM-PROOF-01, and ASM-BROWSER-01.
Evidence: checked invariant in the Canonical Runtime, plus conformance tests
(supporting).
- SP-DELIVERY-01:
An authorization response for one OAuth client reaches only an origin
registered to that client, so a site borrowing another deployment's client
cannot receive its evidence. Depends on ASM-PROV-01, ASM-BROWSER-01.
The Identity Platform delivers an OAuth client's initial authorization
response only to that client's registered redirect origin. Subsequent browser
release follows REQ-COMMON-30, so borrowing another deployment's client does
not authorize receipt of its response. Depends on ASM-PROV-01, ASM-BROWSER-01.
Evidence: external audit of the registered redirect URI list, plus
conformance tests (supporting).
- SP-EXCHANGE-01:
Expand Down Expand Up @@ -671,9 +682,11 @@ attestation to verify carries no value at all.
The Deployment MUST register with each Identity Platform only redirect URIs
whose origins it controls.
- REQ-COMMON-30 (upholds SP-DELIVERY-01):
The Canonical Runtime MUST forward an authorization response only over a live
browser channel authenticated to an exact origin in the deployment-configured
allowed application-origin set. The set MAY contain more than one origin.
The Canonical Runtime MUST release an authorization response beyond Callback
only after authenticating the exact Application origin against the deployment
allowlist. The Canonical Runtime MUST carry the response only to the configured
Prover, preserving that authenticated origin restriction as defined by CCDP
(REQ-CCDP-03, REQ-CCDP-04). The set MAY contain more than one origin.
- REQ-COMMON-31 (upholds SP-DELIVERY-01):
The Canonical Runtime MUST ignore a forwarding target supplied in the
redirect request.
Expand Down Expand Up @@ -942,16 +955,39 @@ and no `authorization` needle to count.
removing every space and horizontal tab. The
Platform Verifier MUST leave carriage-return and line-feed bytes in
place. The Platform Verifier MUST require exactly one occurrence of the normalized,
line-anchored credential header needle `\r\nauthorization:bearer` across
all revealed request bytes, counting the region before the committed
range and the region after it together. Necessity: HTTP field names and
the auth-scheme token are case-insensitive and the colon admits optional
whitespace, so a literal search over raw bytes is evadable; removing only
bytes absent from the needle can create a spurious match, an over-reject
which is safe, but can never hide a real one; and keeping CR and LF is
what makes the needle count header lines rather than any substring, so a
second genuine `authorization` header is rejected whatever the Identity
Platform would have done with it.
line-anchored credential header needle `\r\nauthorization:` across
all revealed request bytes, whatever auth scheme follows it, counting the
region before the committed range and the region after it together.
Necessity: HTTP field names are case-insensitive and the colon admits
optional whitespace, so a literal search over raw bytes is evadable;
removing only bytes absent from the needle can create a spurious match, an
over-reject which is safe, but can never hide a real one; keeping CR and LF
is what makes the needle count header lines rather than any substring; and
counting under any scheme is what rejects a second `authorization` header
whatever it carries. A count of `bearer` lines alone leaves a second header
under Basic or a platform's own token scheme uncounted, and the Identity
Platform answering for whichever credential it honoured, which is the
committed bearer or someone else's.
- REQ-COMMON-39A (upholds SP-EXCHANGE-01):
For that same identity-session request, the Platform Verifier MUST reject
revealed request bytes carrying a line feed not preceded by a carriage
return, a carriage return not followed by a line feed, or a line beginning
with a space or a horizontal tab. Necessity: the count of REQ-COMMON-39
reads header lines, and each of the three is a byte some parser reads as a
line boundary this one does not, so a second header could sit where the
count sees none.
- REQ-COMMON-39B (upholds SP-EXCHANGE-01):
For that same identity-session request, the Platform Verifier MUST reject a
revealed header line whose name, normalized as REQ-COMMON-39 normalizes
and with `_` read as `-`, is `cookie`, `content-encoding`,
`transfer-encoding`, `x-http-method-override`, `x-http-method` or
`x-method-override`. Necessity: each changes what the Identity Platform
does with the request in a way no revealed byte shows. `cookie` is the case
that matters: another credential a platform might honour over the
committed bearer, and that bearer is the one thing the cross-bind to the
token exchange fixes. The underscore folds because a CGI-style stack reads
`content_encoding` as `content-encoding`. `authorization` is not on this
list only because REQ-COMMON-39 already holds it to one line.
- REQ-COMMON-40 (upholds SP-EXCHANGE-01):
For that same identity-session request, the Platform Verifier MUST require
the raw transcript bytes immediately before the committed range to be
Expand Down Expand Up @@ -1037,6 +1073,26 @@ and no `authorization` needle to count.
more than one position. Necessity: an authenticated response value the
account holder influences, such as a display name, can embed a lookalike
field.
- REQ-COMMON-19F (upholds SP-BIND-01, SP-EXCHANGE-01):
The Platform Verifier reading a JSON field from revealed attestation bytes
MUST first remove every JSON whitespace byte (`0x20`, `0x09`, `0x0a`,
`0x0d`) that touches a structural byte (`:`, `,`, `{`, `}`, `[`, `]`) on
either side, and no other byte. The Platform Verifier MUST match the
field's delimiter, count its positions under REQ-COMMON-19A, read its
value, and judge its terminator over the bytes that removal leaves. The
Implementation MUST reveal a member as the transcript carries it, its JSON
whitespace inside the revealed range at its offsets. The Implementation
MUST NOT commit that whitespace with a bearer. Every compact delimiter this
specification spells, such as `"login":"` or `"access_token":"`, names the
member that removal leaves, not the bytes a platform must serve. The
Proving Circuit is outside this rule: REQ-COMMON-19 and REQ-COMMON-19D fix
what it asserts at the offset the prover supplies. Necessity: a platform
may pretty-print the response it serves for the media type a profile pins,
and GitHub does for `/user`. Removing whitespace only where it touches a
structural byte leaves every reader one exact template and makes a member
in any spelling the same member, so a second copy spelled with spaces is
still the duplicate REQ-COMMON-19A rejects, while `123 456` still does not
read as `123456`.
- REQ-COMMON-20 (upholds SP-EXCHANGE-01):
The Proving Circuit MUST constrain every variable value it opens or
extracts to the charset the profile states, including values that are never
Expand Down Expand Up @@ -1267,6 +1323,15 @@ the constructions that role implements.
format, or required security properties is invalid. A destination chain
cannot support it without selecting a compatible Notary Service. A profile
whose Attestation Count is zero remains valid without either.
- TEST-COMMON-10A (exercises REQ-COMMON-19F, REQ-COMMON-19A):
A revealed member spelled with each JSON whitespace byte, alone and as a
run, between its name and its colon, between its colon and its value, and
between its integer and its terminator, reads as the compact member, and
its bytes are revealed at their transcript offsets; a second copy of the
field spelled with whitespace is rejected as a duplicate; a byte JSON does
not call whitespace, such as `0x0b`, in any of those positions is rejected;
an integer with whitespace between its digits is rejected; and a member
whose whitespace an HTTP chunk boundary splits is not built as a layout.
- TEST-COMMON-11 (exercises REQ-COMMON-21, REQ-COMMON-21A, REQ-COMMON-21B, REQ-COMMON-21C):
The Platform Verifier rejects an authenticated foreign authority, method,
or path. The request constructor refuses a media type or `redirect_uri`
Expand All @@ -1285,7 +1350,9 @@ the constructions that role implements.
- TEST-COMMON-14 (exercises REQ-COMMON-30, REQ-COMMON-31):
Each of two configured application origins can complete its own authenticated
live channel; an unlisted origin is rejected, and a redirect request carrying
a forwarding target cannot change either result.
a forwarding target cannot change either result. Callback privately carries
the return only to the configured Prover; that Prover authenticates the same
Application origin before credential use.
- TEST-COMMON-15 (exercises REQ-COMMON-29):
Every redirect URI registered against each production client resolves to an
origin the deployment controls. Verification: audit of the platform client
Expand All @@ -1311,7 +1378,8 @@ the constructions that role implements.
moves no value; and a call whose native value differs from the quoted value
is rejected at every hop.
- TEST-COMMON-17 (exercises REQ-COMMON-33, REQ-COMMON-34B, REQ-COMMON-33A, REQ-COMMON-34, REQ-COMMON-34A, REQ-COMMON-34C, REQ-COMMON-34D, REQ-COMMON-34E):
An attestation carrying a foreign notary signature is rejected; a
At ledger verification, the trusted Notary Service rejects an attestation
carrying a foreign notary signature; a
verification whose fee was not delivered is rejected; the charged fee is
identical across differing attested content, authors, payers, and
submitters; the current fee is readable before the Submission is submitted; and a
Expand Down
29 changes: 25 additions & 4 deletions specs/libid.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,19 @@ specifications.
protocols cite it instead of restating opener, isolation, and continuity
mechanics.

## Browser ceremony and services

- [Ceremony Cross-Document Protocol](ccdp.md) defines its documents, routes,
private navigation inputs, messages, events, and phases over popup transport.
- [OAuth Bridge](oauth-bridge.md) defines public configuration, callback ingress,
and the confidential GitHub token-exchange HTTP contract.
- [CCDP Distribution](ccdp-distribution.md) defines static resource responses,
Callback configuration insertion, isolation policies, and compatible publication.

These chapters are normative browser/service boundaries. TypeScript APIs, build
tooling, UI projections, dependency pins, and qualification evidence belong to
the implementation documentation, not this specification.

## System model and specification ownership

libID turns an identity-platform authorization into a proof that a Consumer
Expand All @@ -43,7 +56,8 @@ User -> Identity Platform -> Canonical Runtime -> Proving Circuit -> Consumer

The Consumer never verifies evidence itself. It calls the Proof Verifier,
which selects the Platform Verifier registered for the named identity platform
and Platform Ceremony Version, which in turn obtains
and ledger-local Verifier Version. Several Verifier Versions may implement the
same Platform Ceremony Version. The selected Platform Verifier obtains
attestation authenticity from the Notary Service once for each attestation
that profile carries. Google carries none, so its path reaches no Notary
Service and pays no fee; X and GitHub carry two each. The result travels
Expand All @@ -52,8 +66,10 @@ Authorized Transaction Data, and client identifier, and the Consumer decides
what that transaction means. [Common §5.1](ceremony-common.md#51-verification-path)
owns this path.

The application operator controls its frontend, redirect deployment, OAuth
clients, and GitHub Token Service, but is not trusted to choose identity fields,
The Application, OAuth Bridge, and CCDP Distribution may have different operators.
They control their frontend, redirect deployment, OAuth registrations, token
service, and distributed browser code respectively. Those deployments are
trusted for the local browser ceremony, but not to choose authoritative identity fields,
change the proof-bound operation, or widen proof validity. The identity platform
controls the authenticated account response. The notary authenticates X/GitHub
transcripts and their creation times. Verifier governance selects accepted
Expand All @@ -64,6 +80,8 @@ authenticates the Transaction Author and supplies its Chain ID and Block Time.
|---|---|---|---|
| User | chooses an account and authorizes an operation | human intent | parsing or cryptographic verification |
| Application operator | configures clients and deployment assets; starts or withholds work | deployment availability and declared configuration | identity fields, proof target, or proof validity |
| OAuth Bridge operator | holds OAuth client registrations and any confidential secret; configures and serves Callback; exchanges GitHub codes | correct Callback configuration, credential handling, and availability | ledger identity, digest, notary-key, or validity decisions |
| CCDP Distribution publisher | supplies browser code, proving assets, and response policies to multiple Bridges | correct code and asset supply under ASM-CCDP-01 | authority to change ledger verification rules |
| Identity-platform operator | authenticates accounts and issues signed or TLS-authenticated responses | the `ASM-PROV-*` behavior the selected profile cites | the proof-bound transaction or Transaction Author |
| Notary operator | operates the X/GitHub attestation key and observes sessions | `ASM-NOTARY-01` | user intent or transaction authorization |
| Verifier governance administrator | activates verifier artifacts, trust roots, parameters, and the Supported Version Set | correct authority lifecycle | user consent |
Expand Down Expand Up @@ -91,7 +109,10 @@ root and verifier.
| Chain ID, Transaction Author, Block Time, and transaction-data encoding | consumer protocol Chain Profile |
| Platform endpoints, fields, trust roots, and proof projections | [Identity-platform ceremonies](platform-ceremonies.md) |
| Popup origin allowlists, message model, delivery, navigation, closure, and continuity guarantees | [Popup transport](popup-transport.md) |
| Redirect transport, interruption behavior, and UI control flow | browser architecture |
| Ceremony documents, routes, private fragments, messages, events, and phase transitions | [CCDP](ccdp.md) |
| Public ceremony configuration, callback ingress, GitHub token HTTP API | [OAuth Bridge](oauth-bridge.md) |
| Static response policies, aggregate Callback artifact, immutable asset publication | [CCDP Distribution](ccdp-distribution.md) |
| Package APIs, UI projections, build tooling, and qualification evidence | implementation documentation (non-normative) |
| Transaction dispatch and author authentication | Consumer protocol |
| Verification dispatch, replay recording, trust roots, and version governance | [Common ceremony rules](ceremony-common.md) |

Expand Down
Loading