1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
// Generated by scripts/regen-ceremony-profiles.py. Do not edit.
// The source of truth is solidity/contracts/ceremony/profiles.json.
//! The single source of truth for the ceremony profiles. Solidity, Rust and
//! TypeScript constants are generated from this file by
//! scripts/regen-ceremony-profiles.py. The Platform Verifiers are hand
//! written and READ these constants; only the values live here.
//!
//! THESE STRINGS ARE OURS, NOT THE SPECIFICATION'S. ceremony-common fixes no
//! literal of its own: platform-ceremonies REQ-PLAT-01 fixes the profile
//! NAMES, and every byte below is the profile author's choice. So this is a
//! cross-implementation agreement, and it is agreed here rather than three
//! times over.
//!
//! Three components must produce the same bytes: this repository's verifiers,
//! the browser that notarizes all four sessions, and the notary that signs
//! what it observed. A disagreement is silent -- a Consumer dispatching on one
//! string and a verifier registered under another simply never meet, and a
//! request line a prover composes one byte differently is an attestation
//! rejected with no error that says why.
//!
//! Changing a value here changes what a deployed verifier accepts. That is a
//! new ceremonyVersion, not an edit.
/// Which shape a platform's immutable identifier takes in its response.
///
/// The bare-integer form takes its structural terminator with it, which is
/// what proves the revealed digits are the whole number rather than a prefix
/// of a longer one (REQ-PLAT-51).
/// One notarized session: which server, and which request.
/// The token session: the OAuth exchange.
/// The identity session: the authenticated read that names the account.
/// One platform's ceremony profile at one Platform Ceremony Version.
/// Google's evidence is a signed token checked against Google's published
/// keys, so the profile notarizes nothing: no session, no attestation,
/// and no Notary Fee.
pub const GOOGLE: Profile = Profile ;
/// A public client with S256 PKCE and two browser-owned sessions, both
/// served by the same host.
pub const X: Profile = Profile ;
/// The credential GitHub calls `client_secret` is sent and revealed, so
/// an attestation publishes it and nothing here is confidential. The two
/// sessions are served by DIFFERENT hosts -- which is why one pinned
/// authority per profile would be wrong.
pub const GITHUB: Profile = Profile ;
/// The closed launch list. A platform outside it has no profile, and
/// `CeremonyProfile.attestationCount` reverts on one.
pub const LAUNCH: & = &;
/// The launch profile for a platform name, or nothing.
///
/// Nothing, rather than a default: a caller that cannot name the platform has
/// nothing to notarize, and guessing produces evidence no verifier accepts.
/// Header names no notarized request may carry, compared by every
/// Platform Verifier with the name lowercased, its whitespace removed and
/// `_` read as `-`. Each changes what the platform does with the request
/// in a way no revealed byte shows: `authorization` which client it
/// authenticates, `content-encoding` and `transfer-encoding` which bytes
/// it parses, `cookie` which session it answers for, the three override
/// names which method it runs. The identity request is excepted from
/// `authorization` alone: its one such header, under any scheme, is what
/// REQ-COMMON-39 counts. On the token request the verifier further
/// requires each session's requiredHeaders, `host` and `content-type`,
/// reads `content-length`, and ignores every other header: one outside
/// both lists changes only what the platform answers, and a wrong answer
/// is a response the verifier cannot read.
pub const FORBIDDEN_REQUEST_HEADERS: & = &;
// The seconds each profile fixes. A Platform Verifier reads them as
// constants: they belong to the profile like its request lines, an upgrade
// of the verifier keeps them, and a different value is a new
// ceremonyVersion (REQ-PARAM-01). A browser that knows the version it ran
// therefore knows the validity every chain enforces. `IdentityRegistry`
// supersedes a binding only on a strictly newer `observedAt`, so an
// allowance too generous lets a proof dated ahead hold a name until the
// clock catches up.
// The signed `exp` bounds validity, so the profile fixes no lifetime
// and no attestation skew. The OIDC circuit exposes no `iat`, so the
// observation is the token's `exp`: Google issues about an hour of
// life, and the claim reads roughly an hour ahead of the moment it
// describes.
/// `google/v1`: how far ahead of Block Time the evidence time may run.
/// The verifier subtracts it, so every version of a platform reports
/// time on one scale.
pub const FUTURE_OBSERVATION_ALLOWANCE_SECONDS_GOOGLE: u64 = 7200;
// The token attestation's creation time is the evidence time. A
// notary states wall-clock time as it observes it, so the observation
// is never ahead: five minutes covers clock skew between the notary
// and the chain.
/// `x/v1`: maximum age of the token attestation.
pub const PROOF_LIFETIME_SECONDS_X: u64 = 3600;
/// `x/v1`: how far ahead of Block Time the token attestation may be
/// dated.
pub const MAX_FUTURE_ATTESTATION_SKEW_SECONDS_X: u64 = 300;
/// `x/v1`: how far ahead of Block Time the evidence time may run. The
/// verifier subtracts it, so every version of a platform reports time
/// on one scale.
pub const FUTURE_OBSERVATION_ALLOWANCE_SECONDS_X: u64 = 300;
// Same as X: notary wall-clock, five minutes for skew.
/// `github/v1`: maximum age of the token attestation.
pub const PROOF_LIFETIME_SECONDS_GITHUB: u64 = 3600;
/// `github/v1`: how far ahead of Block Time the token attestation may
/// be dated.
pub const MAX_FUTURE_ATTESTATION_SKEW_SECONDS_GITHUB: u64 = 300;
/// `github/v1`: how far ahead of Block Time the evidence time may run.
/// The verifier subtracts it, so every version of a platform reports
/// time on one scale.
pub const FUTURE_OBSERVATION_ALLOWANCE_SECONDS_GITHUB: u64 = 300;