From d438d08f5f105b15b2d853d7a0673c87571090f0 Mon Sep 17 00:00:00 2001 From: Green Baneling Date: Wed, 30 Sep 2026 14:52:17 +0100 Subject: [PATCH] docs(specs): make the profile version fix the protocol parameters The Canonical Runtime derives a proof's expiry from the profile it ran, so a lifetime governance can change lets that expiry disagree with a Consumer Chain, or shift under a verifier upgrade. Each Platform Profile now fixes proofLifetime and maxFutureAttestationSkew per (platform, version); a new value takes a new Platform Ceremony Version. Governance keeps the Supported Version Set and the trust roots. Spec side of https://github.com/libid-org/libID-contracts/issues/65. Assisted-by: Claude Opus 5.5 Signed-off-by: Green Baneling --- specs/ceremony-common.md | 48 +++++++++++----------- specs/libid.md | 80 ++++++++++++++++++++++-------------- specs/platform-ceremonies.md | 24 ++++++----- 3 files changed, 87 insertions(+), 65 deletions(-) diff --git a/specs/ceremony-common.md b/specs/ceremony-common.md index 6561dea5..87bac959 100644 --- a/specs/ceremony-common.md +++ b/specs/ceremony-common.md @@ -49,9 +49,10 @@ Platform Verifier: The component on the Consumer Chain registered under one Platform Ceremony Version: The unsigned 16-bit `platformCeremonyVersion` selecting one identity platform's immutable Authorization Digest - construction, OAuth construction, and platform-specific proof statement. - The digest binds it, so it is the same number on every Consumer Chain. It - identifies no Platform Verifier implementation and is not a routing key. + construction, OAuth construction, platform-specific proof statement, and + protocol parameter values. The digest binds it, so it is the same number on + every Consumer Chain. It identifies no Platform Verifier implementation and + is not a routing key. Verifier Version: The unsigned 16-bit key under which a Consumer Chain's Verifier Governance Process registers one Platform Verifier for one @@ -114,13 +115,13 @@ Ceremony: The complete off-chain process that authenticates a user's selected Platform Profile: The immutable, independently versioned definition of one identity platform's ceremony: its endpoints, ordered request fields, - revealed ranges, authenticated response locations, proof-validity inputs, - parameter keys and rules, and, where its Attestation Count is nonzero, its - attestation protocol and format. A profile whose Attestation Count is zero - defines neither of those two. Every Platform Verifier registered for that - platform and version MUST enforce the same profile, but its implementation - and deployment are ledger-specific. The Consumer holds none of the profile - constants. + revealed ranges, authenticated response locations, proof-validity inputs + and rules, the value of each protocol parameter it names, and, where its + Attestation Count is nonzero, its attestation protocol and format. A + profile whose Attestation Count is zero defines neither of those two. Every + Platform Verifier registered for that platform and version MUST enforce the + same profile, but its implementation and deployment are ledger-specific. + The Consumer holds none of the profile constants. Proving Circuit: The zero-knowledge circuit whose proof a Platform Verifier checks. It proves only what cannot be read from authenticated evidence. @@ -131,8 +132,8 @@ Redirect Runtime: The immutable browser component served at a registered Verifier Governance Process: The authority over the verification path: the Proof Verifier's Supported Version Set and the Verifier Version each entry - is registered under, each Platform Verifier's pinned constants and trust - roots, and the protocol parameters. It is not the Consumer's governance. + is registered under, and each Platform Verifier's verifier artifact, Notary + Service, and trust roots. It is not the Consumer's governance. Identity Platform: Google, X, GitHub, or a future source of authenticated identity evidence. "Provider" is reserved for the formal OIDC term and for @@ -216,7 +217,7 @@ Attestation Count: The number of entries in the closed attestation list a The configured notary key is unforgeable, signs only transcripts it observed, and stamps their creation time from a clock within ordinary skew of real time. The enforced numeric bound on future skew is REQ-PLAT-09's - comparison against the current `maxFutureAttestationSkew` parameter, not + comparison against the Platform Profile's `maxFutureAttestationSkew`, not part of this assumption. - ASM-PROOF-01: A proof accepted under the verifier artifact selected for its platform and @@ -319,8 +320,9 @@ bytes plus the Authorized Transaction Data. field. `platformCeremonyVersion` identifies the complete platform ceremony boundary: -this Authorization Digest layout, the platform's OAuth construction, and its -platform-specific proof statement. It is the only version the digest binds. +this Authorization Digest layout, the platform's OAuth construction, its +platform-specific proof statement, and its protocol parameter values. It is +the only version the digest binds. The Verifier Version a Consumer Chain routes on is not in the digest, so a proof made for one ceremony version is acceptable at every Platform Verifier implementing it. @@ -498,12 +500,12 @@ Verifier knows what the payload is; only the Notary Service knows whether the notary signed. Everything between them is dispatch. The Supported Version Set lives in the Proof Verifier and is keyed by Verifier Version. The Platform Profile defines every immutable platform constant — endpoints, revealed -ranges, attestation format, validity rules, and parameter keys — and each -Consumer Chain's Platform Verifier enforces that profile and fixes the -encoding of its own Submission Payload. Verifier governance owns the mutable -verifier artifact, Notary Service, trust roots, fees, parameter values, and -the Verifier Version each verifier is registered under. The Consumer holds -none of those constants. +ranges, attestation format, validity rules, and protocol parameter values — +and each Consumer Chain's Platform Verifier enforces that profile and fixes +the encoding of its own Submission Payload. Verifier governance owns the +mutable verifier artifact, Notary Service, trust roots, fees, and the +Verifier Version each verifier is registered under. The Consumer holds none +of those constants. Two versions travel this path, deliberately unrelated. The Platform Ceremony Version is inside the payload and the digest, fixed by the Canonical Runtime @@ -1264,8 +1266,8 @@ Service. the Authorization Digest for no effect. - REQ-COMMON-26 (upholds SP-FRESH-01): The Platform Verifier MUST derive `proofValidUntil` from the platform profile's - authenticated validity input and any current protocol parameter that profile - names. The Platform Verifier MUST reject a Submission where + authenticated validity input and any protocol parameter value that profile + fixes. The Platform Verifier MUST reject a Submission where `Block Time >= proofValidUntil`. - REQ-COMMON-27 (upholds SP-FRESH-01): The Platform Verifier MUST NOT accept a caller-supplied validity bound. diff --git a/specs/libid.md b/specs/libid.md index 8d2c3d44..a7fa9a6c 100644 --- a/specs/libid.md +++ b/specs/libid.md @@ -68,8 +68,9 @@ identity fields, change the proof-bound operation, or widen proof validity. GitHub token exchange and identity notarization run in the browser; there is no confidential exchange service. The identity platform controls the authenticated account response. The notary authenticates X/GitHub -transcripts and their creation times. Verifier governance selects accepted -verifier artifacts, trust roots, and protocol parameters. The Consumer Chain +transcripts and their creation times. Verifier governance selects the +Supported Version Set, accepted verifier artifacts, and trust roots. Each +Platform Profile fixes its protocol parameters. The Consumer Chain authenticates the Transaction Author and supplies its Chain ID and Block Time. | Principal | Knows and can | Trusted for | Not trusted for | @@ -78,7 +79,7 @@ authenticates the Transaction Author and supplies its Chain ID and Block Time. | Application operator | configures clients and deployment assets; starts or withholds work | deployment availability and declared configuration | identity fields, proof target, or proof validity | | 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 | +| Verifier governance administrator | activates verifier artifacts, trust roots, and the Supported Version Set | correct authority lifecycle | user consent | The principal trust roots are Google's active signing moduli, the active X/GitHub notary keys, the selected proof-verifier artifacts, the Proof Verifier @@ -152,43 +153,60 @@ as shown here. ## Protocol parameters -Protocol parameters are governance-owned unsigned 64-bit values expressed in -seconds, read where they are enforced. -The Verifier Governance Process may update a supported parameter and emits its -key, previous value, and new value. The Platform Verifier reads the current -value when it verifies a proof; browser reads are advisory only. Lowering a -parameter may reject an outstanding proof, while raising one may extend an -outstanding X/GitHub proof. Current trust-root membership remains required. - -| Parameter | Launch value | Use | -|---|---:|---| -| `proofLifetime[x]` | 3600 | maximum age of the X token attestation | -| `proofLifetime[github]` | 3600 | maximum age of the GitHub token-exchange attestation | -| `maxFutureAttestationSkew` | 300 | maximum X/GitHub attestation lead over Block Time | +Protocol parameters are unsigned 64-bit values expressed in seconds. The +Platform Profile fixes the value of every parameter it names, as it fixes its +request lines, so one `(identityPlatform, platformCeremonyVersion)` pair +selects one value on every Consumer Chain and at every Verifier Version +implementing that profile. + +| Platform Profile | `proofLifetime` | `maxFutureAttestationSkew` | +|---|---:|---:| +| `("google", 1)` | not named | not named | +| `("x", 1)` | 3600 | 300 | +| `("github", 1)` | 3600 | 300 | + +`proofLifetime` is the maximum age of the attestation that supplies evidence +time: the X token attestation and the GitHub token-exchange attestation. +`maxFutureAttestationSkew` is the maximum lead of an X/GitHub attestation +timestamp over Block Time. Google's signed `exp` bounds its validity, so +`("google", 1)` names neither. Verifier governance controls the Supported +Version Set and the trust roots, so a proof is accepted only while a Verifier +Version implementing its profile is supported and the trust roots it relies +on are active. - REQ-PARAM-01: - The Verifier Governance Process MUST reject an unknown parameter key and a - parameter value which is not a canonical unsigned 64-bit integer. The - Verifier Governance Process MUST emit the parameter key, previous value, and - new value after a successful update. Necessity: independent implementations - must read and observe one closed parameter set. + The Platform Profile MUST fix each protocol parameter it names as one + unsigned 64-bit number of seconds. The Platform Verifier MUST NOT expose an + operation that changes a value its profile fixes. The Verifier Governance + Process MUST NOT change that value, including by upgrading a Platform + Verifier registered for the profile. A different value changes the ceremony + boundary of REQ-COMMON-01B, so it takes a new Platform Ceremony Version, + verified by a new Platform Verifier registered under its own Verifier + Version. Necessity: the Canonical Runtime derives a proof's expiry from the + profile it ran, so one Platform Ceremony Version must mean one value on + every Consumer Chain and through every verifier upgrade. - REQ-PARAM-02: - The Platform Verifier MUST use the current governance value and checked - arithmetic whenever a ceremony rule names one of these parameters. The + The Platform Verifier MUST use the value its profile fixes, with checked + arithmetic, whenever a ceremony rule names one of these parameters. The Platform Verifier MUST NOT accept a caller-supplied substitute. Necessity: callers must not widen proof freshness. - TEST-PARAM-01 (exercises REQ-PARAM-01, REQ-PARAM-02): - The launch values reproduce the platform validity vectors; an unknown key, - caller override, and overflowing calculation fail, while a governance update - emits the previous and new values and affects subsequent verification. + The values above reproduce the platform validity vectors; a caller override + and an overflowing calculation fail; a Platform Verifier exposes no + operation that changes a value its profile fixes; and two Platform + Verifiers implementing one profile, on different Consumer Chains, under + different Verifier Versions, or before and after an upgrade, apply the same + values to the same evidence time. ## Security Considerations -Verifier governance can shorten or widen the X/GitHub acceptance window. Every -proof still requires a currently active trust root, and Google remains bounded -by its signed expiry. The linked chapters define the remaining assumptions, -security properties, requirements, and platform-specific security -considerations. +Each X and GitHub Platform Profile fixes its acceptance window, which is +therefore the same on every Consumer Chain and at every Verifier Version +implementing that profile. Verifier governance can end a proof's acceptance +before the window closes by retiring a trust root it relies on or every +Verifier Version implementing its profile. Google remains bounded by its +signed expiry. The linked chapters define the remaining assumptions, security +properties, requirements, and platform-specific security considerations. ## References diff --git a/specs/platform-ceremonies.md b/specs/platform-ceremonies.md index 0f67e02b..0ae349d1 100644 --- a/specs/platform-ceremonies.md +++ b/specs/platform-ceremonies.md @@ -31,9 +31,10 @@ Terms are imported from Each platform ceremony has an independently versioned immutable profile. Its Platform Ceremony Version is carried in its Authorization Digest and in the Submission Payload. Each platform section defines its own launch version. A -version covers the digest, OAuth construction, and platform-specific proof -statement, not any Consumer Chain's verifier implementation. A Consumer Chain -routes on its own Verifier Version (common §5.1). +version covers the digest, OAuth construction, platform-specific proof +statement, and protocol parameter values, not any Consumer Chain's verifier +implementation. A Consumer Chain routes on its own Verifier Version (common +§5.1). A profile is selected by the pair `(identityPlatform, platformCeremonyVersion)`. Each platform section defines its exact canonical @@ -180,8 +181,8 @@ Proof validity and mutable-metadata ordering use the authenticated times below. | Identity platform | `metadataObservedAt` | `proofValidUntil` | |---|---|---| | Google | signed ID-Token `exp` | signed ID-Token `exp` | -| X | the token attestation's signed creation time | `metadataObservedAt + proofLifetime[x]` | -| GitHub | the token-exchange attestation's signed creation time | `metadataObservedAt + proofLifetime[github]` | +| X | the token attestation's signed creation time | `metadataObservedAt + proofLifetime` | +| GitHub | the token-exchange attestation's signed creation time | `metadataObservedAt + proofLifetime` | For X and GitHub, "timestamp" is the signed TLSNotary attestation creation time. The token attestation is the one-time PKCE and Authorization Digest @@ -189,8 +190,8 @@ binding, so it alone supplies evidence time: one signed timestamp anchors both m ordering and proof validity, exactly as Google's single signed `exp` does. The identity attestation opens the same bearer and carries the identity fields; its own creation time is not an evidence-time input and does not -refresh the authorization. The named lifetimes are current -[protocol parameters](libid.md#protocol-parameters). +refresh the authorization. `proofLifetime` and `maxFutureAttestationSkew` are +the [protocol parameters](libid.md#protocol-parameters) each profile fixes. Google's signed `exp` already supplies the accepted one-hour ordering and validity value. A Google proof also requires its signing modulus to remain in @@ -201,7 +202,7 @@ block an otherwise valid authority operation. - REQ-PLAT-09 (upholds SP-FRESH-01): The Platform Verifier MUST reject an X or GitHub attestation timestamp more than - `maxFutureAttestationSkew` ahead of Block Time. + its profile's `maxFutureAttestationSkew` ahead of Block Time. - REQ-PLAT-09A (upholds SP-FRESH-01): The Platform Verifier MUST derive `metadataObservedAt` and `proofValidUntil` from the exact sources in the table above and from @@ -1125,7 +1126,8 @@ observation ordering; client portability or a bounded client family; exact authorization and redirect transport; every authenticated request and response field with its provenance; how the Authorization Digest is carried through that platform's authorization; its authenticated client-binding source; an -authenticated proof-validity rule and parameter keys; its trust-root lifecycle; +authenticated proof-validity rule and the value of each protocol parameter it +names; its trust-root lifecycle; browser and deployment data exposure, retry, interruption, and withholding behavior; and conformance vectors. @@ -1169,8 +1171,8 @@ Platform Verifier, Notary Service, Consumer. `sub`. - TEST-PLAT-07 (exercises REQ-PLAT-22, REQ-PLAT-09, REQ-PLAT-09A): A proof at or after `proofValidUntil`, and a token-attestation creation time - more than `maxFutureAttestationSkew` ahead of Block Time, are rejected. An - X or GitHub identity-attestation timestamp changes neither + more than its profile's `maxFutureAttestationSkew` ahead of Block Time, are + rejected. An X or GitHub identity-attestation timestamp changes neither `metadataObservedAt` nor `proofValidUntil`; Google uses its signed `exp` for both values. - TEST-PLAT-08 (exercises REQ-PLAT-24):