Skip to content
Open
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
48 changes: 28 additions & 20 deletions specs/ceremony-common.md
Original file line number Diff line number Diff line change
Expand Up @@ -192,17 +192,20 @@ Attestation Count: The number of entries in the closed attestation list a
each authoritative field appears exactly once at the JSON location fixed by
its Platform Profile.
- ASM-PROV-07:
For profiles relying on platform-side decoded-form uniqueness (X), at the
exact token endpoint and method fixed by that profile, the
Identity Platform accepts token redemption only under the profile's media
type and rejects a form body containing more than one decoded occurrence of
any profile-listed field. Necessity: launch circuits deliberately avoid
proving the complete form grammar; without this parser property a prover
could witness one `code` or `code_verifier` while the platform consumes
another. GitHub instead enforces the complete canonical request in its
Platform Verifier under REQ-PLAT-61 and does not depend on this assumption.
Evidence: recurring integration probes against each dependent profile's
production endpoint.
For a Platform Profile that reads a decoded form field from a token request
it does not hold whole, at the exact token endpoint and method fixed by that
profile, the Identity Platform accepts token redemption only under the
profile's media type and rejects a form body containing more than one
decoded occurrence of any profile-listed field. Necessity: a circuit that
extracts a field without proving the complete form grammar needs this
parser property; without it a prover could witness one `code` or
`code_verifier` while the platform consumes another. No launch profile
depends on this assumption: X and GitHub each hold the complete revealed
token body in the Platform Verifier under REQ-PLAT-63 and REQ-PLAT-61. A
future Platform Profile that reads a decoded form it does not hold whole
cites this assumption and joins the probes of REQ-COMMON-32. Evidence:
recurring integration probes against each citing profile's production
endpoint.
- ASM-NOTARY-01:
The configured notary key is unforgeable, signs only transcripts it
observed, and stamps their creation time from a clock within ordinary skew
Expand Down Expand Up @@ -233,13 +236,15 @@ on it.
Evidence produced by a ceremony discharges only for the Authorized
Transaction Data committed in its Authorization Digest. Depends on
ASM-PROV-02, ASM-PROV-05, ASM-PROV-06,
ASM-PROV-07, ASM-NOTARY-01, ASM-PROOF-01, ASM-CHAIN-01. Evidence:
ASM-PROV-07 for a profile that cites it, ASM-NOTARY-01, ASM-PROOF-01,
ASM-CHAIN-01. Evidence:
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-05,
ASM-PROV-07 where applicable, ASM-NOTARY-01, ASM-PROOF-01, and ASM-BROWSER-01.
ASM-PROV-07 for a profile that cites it, ASM-NOTARY-01, ASM-PROOF-01, and
ASM-BROWSER-01.
Evidence: checked invariant in the Canonical Runtime, plus conformance tests
(supporting).
- SP-DELIVERY-01:
Expand All @@ -250,8 +255,9 @@ on it.
conformance tests (supporting).
- SP-EXCHANGE-01:
An attested token exchange redeems the authorization code produced by this
ceremony and no other. Depends on ASM-PROV-02, ASM-PROV-03, ASM-PROV-07,
ASM-NOTARY-01, ASM-PROOF-01, ASM-BROWSER-01. Evidence: conformance tests
ceremony and no other. Depends on ASM-PROV-02, ASM-PROV-03, ASM-PROV-07
for a profile that cites it, ASM-NOTARY-01, ASM-PROOF-01, ASM-BROWSER-01.
Evidence: conformance tests
(supporting, not proving).
- SP-FRESH-01:
Evidence older than its authenticated ceiling is rejected. Depends on
Expand Down Expand Up @@ -832,7 +838,8 @@ the value, and its closing quote. JSON unsigned integers and booleans use the
typed local matches of REQ-COMMON-19D. A form-field check asserts a field
boundary, the exact ASCII name and `=`, the value, and the next `&` or body end.
Because authenticated response fields satisfy ASM-PROV-06, and form uniqueness
is either enforced by the Platform Verifier or assumed under ASM-PROV-07,
is enforced by the Platform Verifier over the revealed body under REQ-PLAT-61
and REQ-PLAT-63, or assumed under ASM-PROV-07 by a profile that cites it,
these local checks provide the required field meaning without the impractical
proving cost of a complete JSON or form parser. Hidden ranges stay behind the
pinned attestation format's range commitments; the circuit links transcripts
Expand Down Expand Up @@ -1043,7 +1050,8 @@ which the following identity-header rules could apply.
name, `=`, the charset-constrained value, and then `&` or the authenticated
body end. The circuit does not scan the rest of the body for duplicates;
a profile relying on the platform for that property cites ASM-PROV-07.
GitHub instead checks its fully revealed body under REQ-PLAT-61.
X and GitHub instead check their fully revealed bodies under REQ-PLAT-63
and REQ-PLAT-61.
- REQ-COMMON-19A (upholds SP-EXCHANGE-01):
The Platform Verifier extracting a field from revealed attestation bytes
MUST reject a transcript in which the field's full delimiter matches at
Expand Down Expand Up @@ -1128,9 +1136,9 @@ constant.
from one, as a public proof input.

Disclosure alone does not enforce decoded form semantics. GitHub pairs full
request disclosure with REQ-PLAT-61's canonical, complete five-field check;
a hidden suffix or a second form field is rejected by its Platform Verifier.
X retains ASM-PROV-07 as its decoded-form soundness dependency.
request disclosure with REQ-PLAT-61's canonical, complete five-field check,
and X with REQ-PLAT-63's; a hidden suffix or a second form field is rejected
by the Platform Verifier. Neither depends on ASM-PROV-07.

REQ-COMMON-22A prevents adding request credentials to the circuit's public
inputs. It does not forbid revealing an intentionally public application
Expand Down
103 changes: 75 additions & 28 deletions specs/platform-ceremonies.md
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,10 @@ sessions.
| 4 | `redirect_uri` | immutable redirect URI |
| 5 | `code_verifier` | PKCE verifier per common §7 |

The whole request is revealed. The table fixes field order for canonical
serialization under common §6, not to protect a hidden suffix; REQ-PLAT-63
holds the complete body to that serialization.

- REQ-PLAT-29 (upholds SP-EXCHANGE-01):
The Implementation MUST reveal the token request's `code` range. The
Canonical Runtime MUST require that revealed serialized value to equal the
Expand All @@ -445,6 +449,35 @@ sessions.
identity session sends it inside a header. Necessity: the range is opened
to link two attestations, so it needs a bound and a charset; the circuit
verifies no other property of the token response.
- REQ-PLAT-63 (upholds SP-EXCHANGE-01, SP-BIND-01, SP-CLIENT-01):
The Prover and Platform Verifier MUST require the complete request body to
be the common §6 canonical form serialization of exactly the five fields in
the table, in that order, each occurring once with a nonempty value.
The Prover and Platform Verifier MUST reject malformed encoding, noncanonical
spelling, an extra or duplicate field, or bytes outside that complete body.
The Prover and Platform Verifier MUST enforce common REQ-COMMON-16B's
charset for `client_id` and common §7's canonical unpadded base64url
encoding of exactly 32 bytes for `code_verifier`. `code` and
`redirect_uri` are nonempty values with no further constraint: the Platform
Verifier reads neither, and the Canonical Runtime compares them under
REQ-PLAT-29 and REQ-PLAT-29C. The `grant_type` value is the exact ASCII
bytes `authorization_code`, which REQ-PLAT-56 compares.
Verification: walk the body once, requiring each literal field name from
the table in order, `=`, a nonempty value in the common serializer's output
alphabet, `&` between pairs and nothing after the last pair. Field names
are the exact literal names in the table. Encoded value bytes are never
reparsed as
another form. A value containing a form delimiter is safe only as the
serializer's encoded value, not as another field. No `refresh_token`,
device-flow field, or other grant field is admitted; the pinned endpoint
receives only this authorization-code request. Acceptance does not depend
on X rejecting malformed or duplicate forms. The Canonical Runtime's
comparisons of `code`, `grant_type` and `redirect_uri` under REQ-PLAT-29
and REQ-PLAT-29C are separate local checks; the Platform Verifier's
digest-to-verifier comparison remains common REQ-COMMON-15A. Necessity:
revealing a range does not reject a form delimiter inside it, and the
circuit does not scan for duplicates under common REQ-COMMON-19C; holding
the whole body removes the platform's parser from the soundness argument.

The request is one revealed range: the request line, every header and the
body. The rows below name what the Platform Verifier reads out of it, not
Expand Down Expand Up @@ -483,8 +516,8 @@ range indistinguishable from a `refresh_token` value.

Those reveals and the in-circuit `code_verifier` opening of REQ-COMMON-15
reduce the hidden request surface, but revealing a range does not reject a form
delimiter inside it. The X profile therefore retains ASM-PROV-07 as a soundness
dependency.
delimiter inside it. REQ-PLAT-63 therefore holds the complete body to the exact
five-field form; X, like GitHub, does not depend on ASM-PROV-07.

- REQ-PLAT-29A (upholds SP-CLIENT-01):
The Implementation MUST reveal the `client_id` range of the token request in
Expand All @@ -506,7 +539,8 @@ dependency.
reads; the Platform Verifier compares the revealed `grant_type` itself
under REQ-PLAT-56. Revealing them narrows the body a prover can compose
without being observed; it does
not by itself exclude a duplicate field, which remains ASM-PROV-07. The
not by itself exclude a duplicate field, which REQ-PLAT-63 rejects over the
complete body. The
Platform Verifier enforces the disclosure: an attestation hiding either
range does not match the profile layout of common REQ-COMMON-17A and
REQ-COMMON-18A and fails verification.
Expand Down Expand Up @@ -761,15 +795,17 @@ forbidden by REQ-PLAT-56A.
The Prover and Platform Verifier MUST reject malformed encoding, noncanonical
spelling, an extra or duplicate field, or bytes outside that complete body.
The Prover and Platform Verifier MUST enforce common REQ-COMMON-16B's
charset for `client_id`, common §7's canonical unpadded base64url encoding
of exactly 32 bytes for `code_verifier`, and printable ASCII without
whitespace for `client_secret`. The decoded `code` and `redirect_uri` are
nonempty UTF-8 strings with no additional charset restriction.
Verification: decode each value once, apply its field constraints, serialize
the ordered tuple with the common serializer, and compare the complete body
byte for byte. Field names are the exact literal names in the table. Encoded
value bytes are never reparsed as another form. A credential containing a form
delimiter is safe only as the serializer's encoded value, not as another field.
charset for `client_id` and common §7's canonical unpadded base64url
encoding of exactly 32 bytes for `code_verifier`. `code`, `redirect_uri`
and `client_secret` are nonempty values with no further constraint: the
Platform Verifier reads none of them, and the Prover compares `code` and
`redirect_uri` under REQ-PLAT-46 and REQ-PLAT-48A.
Verification: walk the body once, requiring each literal field name from
the table in order, `=`, a nonempty value in the common serializer's output
alphabet, `&` between pairs and nothing after the last pair. Field names
are the exact literal names in the table. Encoded value bytes are never
reparsed as another form. A credential containing a form delimiter is safe
only as the serializer's encoded value, not as another field.
No `grant_type`, `refresh_token`, device-flow field, or other extension is
admitted; the pinned endpoint receives only this authorization-code request.
Acceptance does not depend on GitHub rejecting malformed or duplicate forms.
Expand Down Expand Up @@ -1139,7 +1175,7 @@ Platform Verifier, Notary Service, Consumer.
- TEST-PLAT-09B (exercises REQ-PLAT-30A, REQ-PLAT-32A):
An X transcript that reveals plaintext `access_token` bytes in either
session, or omits the bearer hash commitment, is rejected.
- TEST-PLAT-09C (exercises REQ-PLAT-29C, REQ-PLAT-56, REQ-PLAT-56A, REQ-PLAT-56B, REQ-PLAT-56C):
- TEST-PLAT-09C (exercises REQ-PLAT-29C, REQ-PLAT-56, REQ-PLAT-56A, REQ-PLAT-56B, REQ-PLAT-56C, REQ-PLAT-63):
The Platform Verifier rejects an X attestation that hides the `grant_type`
or `redirect_uri` range, and the Canonical Runtime rejects a revealed value
differing from the canonical form serialization of its deployment profile.
Expand All @@ -1158,7 +1194,16 @@ Platform Verifier, Notary Service, Consumer.
count that is not the body's length, is not decimal digits, or carries a
leading zero, and accepts the count wherever it sits in the head; and it
rejects a head carrying a bare line feed, a bare carriage return, an
obsolete line fold, or a line with no colon.
obsolete line fold, or a line with no colon. The canonical five-field body
passes; missing, empty, additional, duplicate, reordered, malformed, or
noncanonical fields fail even if X were to accept them. Encoded duplicate
names cannot evade the exact name/serialization check. A value with encoded
delimiters remains one value and passes; raw delimiters creating more
fields fail. Refresh or device-grant fields fail. Invalid
client-identifier bytes and a noncanonical or wrong-length PKCE verifier
fail. Canonical form escaping in `code` and `redirect_uri` passes the form
check; a mismatch with the consumed code or the deployment profile's
redirect still fails under REQ-PLAT-29 and REQ-PLAT-29C.
- TEST-PLAT-10 (exercises REQ-PLAT-30, REQ-PLAT-31, REQ-PLAT-32, REQ-PLAT-36, REQ-PLAT-51, REQ-PLAT-52):
An opened bearer range that is empty, over 4096 bytes, or outside printable
ASCII fails to prove; a revealed identity response missing `id` or the
Expand All @@ -1180,10 +1225,10 @@ Platform Verifier, Notary Service, Consumer.
exact name/serialization check. A credential with encoded delimiters remains
one value and passes; raw delimiters creating more fields fail. Refresh or
device-grant fields fail. All accepted lengths cover the complete body.
Invalid client-identifier bytes, a noncanonical or wrong-length PKCE verifier,
and invalid UTF-8 in `code` or `redirect_uri` fail. Canonical form escaping in
those two strings passes the form check; a mismatch with the captured code
or frozen redirect still fails the Prover's local comparisons.
Invalid client-identifier bytes and a noncanonical or wrong-length PKCE
verifier fail. Canonical form escaping in `code` and `redirect_uri` passes
the form check; a mismatch with the captured code or frozen redirect still
fails the Prover's local comparisons.
- TEST-PLAT-13 (exercises REQ-PLAT-37, REQ-PLAT-38, REQ-PLAT-62):
Prover sends the frozen client/credential/redirect and ceremony code/verifier
through its token Proxy session, using the same selected notary as identity.
Expand Down Expand Up @@ -1249,11 +1294,13 @@ Platform Verifier, Notary Service, Consumer.
before any token request starts, as is a redirect whose `state` matches no
live local ceremony or a ceremony already consumed.
- TEST-PLAT-19 (exercises REQ-COMMON-32; supports ASM-PROV-07):
Recurring integration probes send each profile-listed X token
request field twice, in both orders and using both literal and percent-encoded
equivalent field names, and send the otherwise valid request under alternate
media types. The production endpoint rejects every probe and issues no
bearer.
For each production Platform Profile that cites ASM-PROV-07, recurring
integration probes send each profile-listed token request field twice, in
both orders and using both literal and percent-encoded equivalent field
names, and send the otherwise valid request under alternate media types.
The production endpoint rejects every probe and issues no bearer. No launch
profile cites ASM-PROV-07: X and GitHub hold the complete token body under
REQ-PLAT-63 and REQ-PLAT-61, so the launch probe set is empty.
- TEST-PLAT-21 (exercises REQ-PLAT-38, REQ-PLAT-49, REQ-PLAT-55):
A same-session bearer opening opens the token attestation commitment; a
missing, mismatched, or other-session opening fails. The opening remains
Expand Down Expand Up @@ -1301,11 +1348,11 @@ platform behavior rather than a proven property. The Implementation claiming
conformance MUST run a recurring check that each platform still rejects a
mismatched `code_verifier`.

X still relies on ASM-PROV-07 for decoded-form uniqueness and uses
TEST-PLAT-19's recurring probes. GitHub instead rejects noncanonical or extra
fields over its fully revealed request under REQ-PLAT-61; it no longer relies
on GitHub rejecting duplicate fields. Both still assume the platform honors
the canonical request, PKCE, and one-use authorization-code semantics.
X and GitHub each reject noncanonical, extra or duplicate fields over the
fully revealed token request, under REQ-PLAT-63 and REQ-PLAT-61; neither
depends on ASM-PROV-07, and TEST-PLAT-19 has no launch profile to probe for
it. Both still assume the platform honors the canonical request, PKCE, and
one-use authorization-code semantics.

The Prover can withhold work or supply malformed evidence. Local request and
commitment checks detect structural substitution, not a well-formed forged
Expand Down
Loading