rodauth-ciba 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +34 -0
  3. data/LICENSE +21 -0
  4. data/README.md +106 -0
  5. data/docs/adr/0003-follow-rodauth-hook-conventions.md +9 -0
  6. data/docs/adr/0004-retain-atomic-issuance-and-stage-alignment.md +16 -0
  7. data/docs/alignment-closeout.md +136 -0
  8. data/docs/alignment-roadmap.md +160 -0
  9. data/docs/api.md +337 -0
  10. data/docs/authentication-claims.md +80 -0
  11. data/docs/authorization-details.md +50 -0
  12. data/docs/claims.md +46 -0
  13. data/docs/failure-contract.md +34 -0
  14. data/docs/id-token-encryption.md +288 -0
  15. data/docs/id-token-hint.md +174 -0
  16. data/docs/login-hint-token.md +35 -0
  17. data/docs/max-age.md +65 -0
  18. data/docs/node-alignment.md +336 -0
  19. data/docs/operations.md +130 -0
  20. data/docs/outbound-http.md +52 -0
  21. data/docs/pairwise.md +76 -0
  22. data/docs/ping.md +118 -0
  23. data/docs/protocol-coverage.md +114 -0
  24. data/docs/refresh-tokens.md +151 -0
  25. data/docs/release-readiness.md +75 -0
  26. data/docs/release-validation.md +498 -0
  27. data/docs/request-context.md +51 -0
  28. data/docs/requirements-audit-current.json +3221 -0
  29. data/docs/requirements-audit-current.md +424 -0
  30. data/docs/requirements-audit.json +3190 -0
  31. data/docs/requirements-audit.md +175 -0
  32. data/docs/research/access-token-revocation-reference.md +81 -0
  33. data/docs/research/alignment-partial-triage.md +50 -0
  34. data/docs/research/claims-reference-contract.md +33 -0
  35. data/docs/research/client-assertion-algorithm-contract.md +177 -0
  36. data/docs/research/completion-error-boundaries.md +56 -0
  37. data/docs/research/consent-api-evolution.md +59 -0
  38. data/docs/research/dpop-reference-contract.md +423 -0
  39. data/docs/research/id-token-hint-reference-contract.md +254 -0
  40. data/docs/research/mtls-reference-contract.md +449 -0
  41. data/docs/research/node-ciba-lifecycle.md +30 -0
  42. data/docs/research/node-oidc-provider-comparison.md +45 -0
  43. data/docs/research/pairwise-reference-contract.md +264 -0
  44. data/docs/research/ping-reference-contract.md +165 -0
  45. data/docs/research/rar-reference-contract.md +55 -0
  46. data/docs/research/refresh-reference-contract.md +85 -0
  47. data/docs/research/registration-reference-contract.md +567 -0
  48. data/docs/research/request-parameter-inventory.md +42 -0
  49. data/docs/research/required-parameter-inventory.md +39 -0
  50. data/docs/research/resource-reference-contract.md +40 -0
  51. data/docs/research/signed-request-reference-contract.md +113 -0
  52. data/docs/resources.md +55 -0
  53. data/docs/security-review.md +294 -0
  54. data/docs/signed-requests.md +162 -0
  55. data/docs/user-code.md +73 -0
  56. data/docs/validation/node-alignment-tests.txt +10 -0
  57. data/examples/client.rb +39 -0
  58. data/examples/demo_app.rb +121 -0
  59. data/examples/dpop_smoke.rb +169 -0
  60. data/examples/ecdh_id_token_smoke.rb +84 -0
  61. data/examples/edwards_id_token_smoke.rb +48 -0
  62. data/examples/edwards_smoke.rb +87 -0
  63. data/examples/edwards_tls_smoke.rb +73 -0
  64. data/examples/encrypted_id_token_smoke.rb +73 -0
  65. data/examples/encryption_tls_smoke.rb +123 -0
  66. data/examples/extensions_smoke.rb +226 -0
  67. data/examples/fixtures/edwards-requests.json +30 -0
  68. data/examples/hmac_id_token_smoke.rb +72 -0
  69. data/examples/migration.rb +18 -0
  70. data/examples/mtls_smoke.rb +395 -0
  71. data/examples/ping_smoke.rb +226 -0
  72. data/examples/registration_smoke.rb +73 -0
  73. data/examples/server.rb +14 -0
  74. data/examples/smoke.rb +46 -0
  75. data/examples/symmetric_id_token_smoke.rb +83 -0
  76. data/lib/rodauth/ciba/authorization_details.rb +60 -0
  77. data/lib/rodauth/ciba/dpop.rb +250 -0
  78. data/lib/rodauth/ciba/http.rb +69 -0
  79. data/lib/rodauth/ciba/id_token_encryption.rb +175 -0
  80. data/lib/rodauth/ciba/jwks_cache.rb +149 -0
  81. data/lib/rodauth/ciba/mtls.rb +174 -0
  82. data/lib/rodauth/ciba/pairwise.rb +105 -0
  83. data/lib/rodauth/ciba/registration.rb +489 -0
  84. data/lib/rodauth/ciba/schema.rb +182 -0
  85. data/lib/rodauth/ciba/version.rb +6 -0
  86. data/lib/rodauth/ciba.rb +4 -0
  87. data/lib/rodauth/features/ciba.rb +2185 -0
  88. metadata +231 -0
@@ -0,0 +1,3221 @@
1
+ {
2
+ "title": "Current CIBA audit overlay",
3
+ "as_of": "2026-09-30",
4
+ "catalog": "requirements-audit.json",
5
+ "scope_note": "Incremental re-audit of the original 159-row catalog, not a reduced replacement scope or a complete normative inventory. Other RFCs and node-specific behavior remain tracked in alignment-roadmap.md. Historical verified/excluded statuses are not automatically carried forward.",
6
+ "status_legend": {
7
+ "protocol_boundary_verified": "Specific gem protocol behavior has direct evidence; application/client obligations remain separate.",
8
+ "partial": "Evidence covers only part of the row or leaves a policy difference unresolved.",
9
+ "app_contract": "Application obligation documented, not proven for a deployment.",
10
+ "client_only": "Client obligation outside OP implementation.",
11
+ "pending": "Not yet re-audited against current optional extensions.",
12
+ "reference_unsupported": "Conditional on a feature unsupported by both the pinned reference and gem. No implementation/conformance pass is claimed; revisit if the reference target or enabled scope changes."
13
+ },
14
+ "reviewed_items": [
15
+ {
16
+ "id": "CIBA-001",
17
+ "label": "CIBA grant識別子",
18
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.4",
19
+ "status": "protocol_boundary_verified",
20
+ "scope": "baseline discovery and opt-in CIBA client registration; optional combinations remain separately audited",
21
+ "finding": "The standard CIBA grant identifier appears in both metadata documents and drives successful authenticated token dispatch alongside the existing authorization-code flow.",
22
+ "code_refs": [
23
+ "lib/rodauth/features/ciba.rb",
24
+ "lib/rodauth/ciba/registration.rb"
25
+ ],
26
+ "test_refs": [
27
+ {
28
+ "file": "test/ciba_protocol_test.rb",
29
+ "method": "test_discovered_custom_backchannel_route_accepts_requests"
30
+ },
31
+ {
32
+ "file": "test/ciba_configuration_test.rb",
33
+ "method": "test_upstream_jwt_authentication_coexists_with_ciba_and_discovery"
34
+ }
35
+ ],
36
+ "execution": "docs/validation/discovery-registration-audit-current.txt"
37
+ },
38
+ {
39
+ "id": "CIBA-002",
40
+ "label": "Discoveryの対応モード",
41
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.4",
42
+ "status": "protocol_boundary_verified",
43
+ "scope": "baseline discovery and opt-in CIBA client registration; optional combinations remain separately audited",
44
+ "finding": "Default discovery advertises poll only; enabling ping advertises poll and ping. Push is not advertised. Both metadata documents agree in the custom-route test.",
45
+ "code_refs": [
46
+ "lib/rodauth/features/ciba.rb",
47
+ "lib/rodauth/ciba/registration.rb"
48
+ ],
49
+ "test_refs": [
50
+ {
51
+ "file": "test/ciba_protocol_test.rb",
52
+ "method": "test_discovered_custom_backchannel_route_accepts_requests"
53
+ },
54
+ {
55
+ "file": "test/ciba_ping_test.rb",
56
+ "method": "test_ping_metadata_acceptance_rollback_expiry_and_private_data_cleanup"
57
+ }
58
+ ],
59
+ "execution": "docs/validation/discovery-registration-audit-current.txt"
60
+ },
61
+ {
62
+ "id": "CIBA-003",
63
+ "label": "Discoveryの開始URL",
64
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.4",
65
+ "status": "protocol_boundary_verified",
66
+ "scope": "baseline discovery and opt-in CIBA client registration; optional combinations remain separately audited",
67
+ "finding": "A configured custom Backchannel route is advertised in OAuth and OIDC discovery, and an actual request to that discovered URL creates the pending record. Deployment proxy/alias rewriting is audited separately.",
68
+ "code_refs": [
69
+ "lib/rodauth/features/ciba.rb",
70
+ "lib/rodauth/ciba/registration.rb"
71
+ ],
72
+ "test_refs": [
73
+ {
74
+ "file": "test/ciba_protocol_test.rb",
75
+ "method": "test_discovered_custom_backchannel_route_accepts_requests"
76
+ }
77
+ ],
78
+ "execution": "docs/validation/discovery-registration-audit-current.txt"
79
+ },
80
+ {
81
+ "id": "CIBA-004",
82
+ "label": "署名要求の対応表明",
83
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.4",
84
+ "status": "protocol_boundary_verified",
85
+ "scope": "signed authentication requests enabled; configured asymmetric algorithms",
86
+ "finding": "Configured signing algorithms appear in Discovery; disabled feature omission has baseline coverage.",
87
+ "code_refs": [
88
+ "lib/rodauth/features/ciba.rb",
89
+ "docs/signed-requests.md"
90
+ ],
91
+ "test_refs": [
92
+ {
93
+ "file": "test/ciba_signed_request_test.rb",
94
+ "method": "test_signed_request_registration_discovery_and_client_authentication"
95
+ }
96
+ ],
97
+ "execution": "docs/validation/signed-request-audit-current.txt"
98
+ },
99
+ {
100
+ "id": "CIBA-005",
101
+ "label": "user_codeの対応表明",
102
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.4",
103
+ "status": "protocol_boundary_verified",
104
+ "scope": "user-code feature enabled unless otherwise stated",
105
+ "finding": "Discovery follows the feature flag; enabled metadata is asserted directly.",
106
+ "code_refs": [
107
+ "lib/rodauth/features/ciba.rb",
108
+ "docs/user-code.md"
109
+ ],
110
+ "test_refs": [
111
+ {
112
+ "file": "test/ciba_user_code_test.rb",
113
+ "method": "test_user_code_not_persisted_and_does_not_replace_customer_approval"
114
+ }
115
+ ],
116
+ "execution": "docs/validation/user-code-audit-current.txt"
117
+ },
118
+ {
119
+ "id": "CIBA-006",
120
+ "label": "Discoveryのgrant_types",
121
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.4",
122
+ "status": "protocol_boundary_verified",
123
+ "scope": "baseline discovery and opt-in CIBA client registration; optional combinations remain separately audited",
124
+ "finding": "Both discovery documents include the CIBA grant identifier while preserving upstream grants.",
125
+ "code_refs": [
126
+ "lib/rodauth/features/ciba.rb",
127
+ "lib/rodauth/ciba/registration.rb"
128
+ ],
129
+ "test_refs": [
130
+ {
131
+ "file": "test/ciba_protocol_test.rb",
132
+ "method": "test_discovered_custom_backchannel_route_accepts_requests"
133
+ }
134
+ ],
135
+ "execution": "docs/validation/discovery-registration-audit-current.txt"
136
+ },
137
+ {
138
+ "id": "CIBA-007",
139
+ "label": "認証方式メタデータの共有",
140
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.4",
141
+ "status": "protocol_boundary_verified",
142
+ "scope": "Configured Basic/post, private_key_jwt/client_secret_jwt (fourteen algorithms), PKI/self-signed TLS; deployment trust and arbitrary extension combinations excluded",
143
+ "finding": "OAuth and OIDC Discovery advertise the same actual authentication-method list. The legacy assertion-type URN is removed from output only; underlying upstream dispatch and unrelated RSA clients remain unchanged. Configured Basic/post, JWT and TLS have separate direct flow evidence. Four-test three-DB regression includes shared metadata, twelve-algorithm JWT authentication and ordinary-flow coexistence; reference HTTP Discovery also excludes the URN.",
144
+ "code_refs": [
145
+ "lib/rodauth/features/ciba.rb",
146
+ "lib/rodauth/ciba/registration.rb",
147
+ "docs/research/client-assertion-algorithm-contract.md"
148
+ ],
149
+ "test_refs": [
150
+ {
151
+ "file": "test/ciba_security_test.rb",
152
+ "method": "test_discovery_preserves_upstream_authentication_algorithms_for_both_endpoints"
153
+ },
154
+ {
155
+ "file": "test/ciba_auth_algorithm_matrix_test.rb",
156
+ "method": "test_configured_client_assertion_algorithms_at_both_ciba_endpoints"
157
+ },
158
+ {
159
+ "file": "test/ciba_registration_test.rb",
160
+ "method": "test_ciba_registration_rejects_assertion_type_as_authentication_method"
161
+ },
162
+ {
163
+ "file": "test/ciba_edwards_auth_test.rb",
164
+ "method": "test_edwards_client_authentication_at_both_endpoints"
165
+ },
166
+ {
167
+ "file": "test/ciba_edwards_auth_remote_test.rb",
168
+ "method": "test_edwards_client_authentication_remote_rotation_failure_and_ordinary_grant"
169
+ },
170
+ {
171
+ "file": "test/ciba_edwards_auth_test.rb",
172
+ "method": "test_edwards_authentication_configuration_preserves_unrelated_rsa_clients"
173
+ },
174
+ {
175
+ "file": "test/ciba_registration_test.rb",
176
+ "method": "test_ciba_registration_rejects_assertion_type_as_authentication_method"
177
+ }
178
+ ],
179
+ "execution": "docs/validation/client-auth-metadata-urn-matrix.txt"
180
+ },
181
+ {
182
+ "id": "CIBA-008",
183
+ "label": "認証署名アルゴリズムの共有",
184
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.4",
185
+ "status": "protocol_boundary_verified",
186
+ "scope": "explicitly configured twelve RS/PS/ES/HS client assertion algorithms; other algorithm families not advertised by this fixture",
187
+ "finding": "Both discovery documents retain upstream authentication algorithms and add explicitly configured CIBA client assertion algorithms. Twelve RS/PS/ES/HS algorithms and Ed25519/EdDSA have direct endpoint verification evidence, wrong-key rejection and gem token issuance. OP ID Token signing configuration is unchanged. This covers the configured fourteen algorithms, not arbitrary backend extensions.",
188
+ "code_refs": [
189
+ "lib/rodauth/features/ciba.rb",
190
+ "lib/rodauth/ciba/registration.rb",
191
+ "docs/research/client-assertion-algorithm-contract.md"
192
+ ],
193
+ "test_refs": [
194
+ {
195
+ "file": "test/ciba_security_test.rb",
196
+ "method": "test_discovery_preserves_upstream_authentication_algorithms_for_both_endpoints"
197
+ },
198
+ {
199
+ "file": "test/ciba_auth_algorithm_matrix_test.rb",
200
+ "method": "test_configured_client_assertion_algorithms_at_both_ciba_endpoints"
201
+ }
202
+ ],
203
+ "execution": "docs/validation/client-auth-algorithms-matrix.txt"
204
+ },
205
+ {
206
+ "id": "CIBA-009",
207
+ "label": "登録済み配送モード",
208
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.4",
209
+ "status": "protocol_boundary_verified",
210
+ "scope": "baseline discovery and opt-in CIBA client registration; optional combinations remain separately audited",
211
+ "finding": "Static clients with missing, multiple or push delivery-mode values fail eligibility before persistence. DCR also rejects missing or unavailable modes without inserting a client; enabled ping has separate acceptance evidence.",
212
+ "code_refs": [
213
+ "lib/rodauth/features/ciba.rb",
214
+ "lib/rodauth/ciba/registration.rb"
215
+ ],
216
+ "test_refs": [
217
+ {
218
+ "file": "test/ciba_configuration_test.rb",
219
+ "method": "test_unavailable_or_unsupported_client_metadata_is_rejected"
220
+ },
221
+ {
222
+ "file": "test/ciba_registration_test.rb",
223
+ "method": "test_invalid_registration_metadata_does_not_persist"
224
+ }
225
+ ],
226
+ "execution": "docs/validation/discovery-registration-audit-current.txt"
227
+ },
228
+ {
229
+ "id": "CIBA-010",
230
+ "label": "CIBA grantのクライアント登録",
231
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.4",
232
+ "status": "protocol_boundary_verified",
233
+ "scope": "baseline discovery and opt-in CIBA client registration; optional combinations remain separately audited",
234
+ "finding": "A static client lacking the CIBA grant is rejected. Opt-in DCR with the CIBA grant creates a client that successfully starts, approves and redeems a request. This supersedes the initial audit evidence that DCR CIBA was wholly unavailable.",
235
+ "code_refs": [
236
+ "lib/rodauth/features/ciba.rb",
237
+ "lib/rodauth/ciba/registration.rb"
238
+ ],
239
+ "test_refs": [
240
+ {
241
+ "file": "test/ciba_configuration_test.rb",
242
+ "method": "test_unavailable_or_unsupported_client_metadata_is_rejected"
243
+ },
244
+ {
245
+ "file": "test/ciba_registration_test.rb",
246
+ "method": "test_dynamic_poll_registration_without_browser_metadata_and_complete_flow"
247
+ }
248
+ ],
249
+ "execution": "docs/validation/discovery-registration-audit-current.txt"
250
+ },
251
+ {
252
+ "id": "CIBA-011",
253
+ "label": "通知URL登録",
254
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.4",
255
+ "status": "protocol_boundary_verified",
256
+ "scope": "ping enabled; statements shared with push are assessed for ping only",
257
+ "finding": "Ping client eligibility requires an HTTPS registered endpoint; changed destinations cannot receive saved credentials. Push is not implemented.",
258
+ "code_refs": [
259
+ "lib/rodauth/features/ciba.rb",
260
+ "lib/rodauth/ciba/http.rb",
261
+ "docs/ping.md"
262
+ ],
263
+ "test_refs": [
264
+ {
265
+ "file": "test/ciba_ping_test.rb",
266
+ "method": "test_ping_rejects_bad_tokens_and_uses_current_registered_destination"
267
+ }
268
+ ],
269
+ "execution": "docs/validation/ping-current-endpoint-matrix.txt"
270
+ },
271
+ {
272
+ "id": "CIBA-012",
273
+ "label": "署名要求アルゴリズム登録",
274
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.4",
275
+ "status": "protocol_boundary_verified",
276
+ "scope": "signed authentication requests enabled; configured asymmetric algorithms",
277
+ "finding": "Registered algorithm gates signed input; independent client authentication remains required. DCR composition is separately covered.",
278
+ "code_refs": [
279
+ "lib/rodauth/features/ciba.rb",
280
+ "docs/signed-requests.md"
281
+ ],
282
+ "test_refs": [
283
+ {
284
+ "file": "test/ciba_signed_request_test.rb",
285
+ "method": "test_signed_request_registration_discovery_and_client_authentication"
286
+ }
287
+ ],
288
+ "execution": "docs/validation/signed-request-audit-current.txt"
289
+ },
290
+ {
291
+ "id": "CIBA-013",
292
+ "label": "user_codeクライアント設定",
293
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.4",
294
+ "status": "partial",
295
+ "scope": "user-code feature enabled unless otherwise stated",
296
+ "finding": "Enabled clients accept explicit false and omitted metadata under the application policy. Disabled-feature clients declaring true are rejected, a stricter eligibility policy; this is not proof of identical handling in all deployments.",
297
+ "code_refs": [
298
+ "lib/rodauth/features/ciba.rb",
299
+ "docs/user-code.md"
300
+ ],
301
+ "test_refs": [
302
+ {
303
+ "file": "test/ciba_user_code_test.rb",
304
+ "method": "test_user_code_input_and_optional_client_policy"
305
+ }
306
+ ],
307
+ "execution": "docs/validation/user-code-audit-current.txt"
308
+ },
309
+ {
310
+ "id": "CIBA-014",
311
+ "label": "登録された認証方式",
312
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.4",
313
+ "status": "protocol_boundary_verified",
314
+ "scope": "Configured Basic/post, private_key_jwt/client_secret_jwt (fourteen algorithms), PKI/self-signed TLS; deployment trust and arbitrary extension combinations excluded",
315
+ "finding": "Configured methods have direct endpoint authentication/negative evidence. Fourteen RS/PS/ES/HS/Edwards algorithms have reference HTTP and gem verification evidence; Edwards adds DCR, remote HTTP rotation/failure, installed HTTPS retrieval with untrusted-TLS rejection, replay protection and ordinary-flow coexistence. A CIBA Edwards-only configuration preserves unrelated RSA client authentication and upstream metadata. See client-auth-edwards-scope-matrix.txt and client-auth-edwards-https-installed.txt. This is bounded protocol evidence, not deployment certification.",
316
+ "code_refs": [
317
+ "lib/rodauth/features/ciba.rb",
318
+ "lib/rodauth/ciba/registration.rb",
319
+ "docs/research/client-assertion-algorithm-contract.md"
320
+ ],
321
+ "test_refs": [
322
+ {
323
+ "file": "test/ciba_configuration_test.rb",
324
+ "method": "test_upstream_jwt_authentication_coexists_with_ciba_and_discovery"
325
+ },
326
+ {
327
+ "file": "test/ciba_protocol_test.rb",
328
+ "method": "test_post_client_authentication"
329
+ },
330
+ {
331
+ "file": "test/ciba_registration_test.rb",
332
+ "method": "test_dynamic_poll_registration_without_browser_metadata_and_complete_flow"
333
+ },
334
+ {
335
+ "file": "test/ciba_auth_algorithm_matrix_test.rb",
336
+ "method": "test_configured_client_assertion_algorithms_at_both_ciba_endpoints"
337
+ },
338
+ {
339
+ "file": "test/ciba_registration_test.rb",
340
+ "method": "test_ciba_registration_rejects_assertion_type_as_authentication_method"
341
+ },
342
+ {
343
+ "file": "test/ciba_edwards_auth_test.rb",
344
+ "method": "test_edwards_client_authentication_at_both_endpoints"
345
+ },
346
+ {
347
+ "file": "test/ciba_edwards_auth_remote_test.rb",
348
+ "method": "test_edwards_client_authentication_remote_rotation_failure_and_ordinary_grant"
349
+ },
350
+ {
351
+ "file": "test/ciba_edwards_auth_test.rb",
352
+ "method": "test_edwards_authentication_configuration_preserves_unrelated_rsa_clients"
353
+ }
354
+ ],
355
+ "execution": "docs/validation/client-auth-edwards-scope-matrix.txt"
356
+ },
357
+ {
358
+ "id": "CIBA-015",
359
+ "label": "pairwise sector算出",
360
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.4",
361
+ "status": "protocol_boundary_verified",
362
+ "scope": "optional pairwise poll/ping clients; no push",
363
+ "finding": "CIBA sector derives from registered remote JWKS or explicit sector URI, rather than redirect URI; nondefault port matches measured node URL.host behavior. Application owns identifier mapping.",
364
+ "code_refs": [
365
+ "lib/rodauth/ciba/pairwise.rb",
366
+ "lib/rodauth/ciba/mtls.rb",
367
+ "docs/pairwise.md"
368
+ ],
369
+ "test_refs": [
370
+ {
371
+ "file": "test/ciba_pairwise_test.rb",
372
+ "method": "test_pairwise_ciba_issuance_preserves_internal_identity_and_sector_stability"
373
+ }
374
+ ],
375
+ "execution": "docs/validation/pairwise-mtls-matrix.txt"
376
+ },
377
+ {
378
+ "id": "CIBA-016",
379
+ "label": "pairwise DCR検証",
380
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.4",
381
+ "status": "protocol_boundary_verified",
382
+ "scope": "optional pairwise poll/ping clients; no push",
383
+ "finding": "Pairwise registration requires remote JWKS and validates explicit sector-document membership; hybrid browser clients include their redirect URIs. Verified TLS, redirect limits and rejection cases have installed-artifact evidence.",
384
+ "code_refs": [
385
+ "lib/rodauth/ciba/pairwise.rb",
386
+ "lib/rodauth/ciba/mtls.rb",
387
+ "docs/pairwise.md"
388
+ ],
389
+ "test_refs": [
390
+ {
391
+ "file": "test/ciba_pairwise_test.rb",
392
+ "method": "test_pairwise_sector_document_requires_keys_and_hybrid_redirects"
393
+ }
394
+ ],
395
+ "execution": "docs/validation/pairwise-mtls-matrix.txt"
396
+ },
397
+ {
398
+ "id": "CIBA-017",
399
+ "label": "pairwise鍵所有証明",
400
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.4",
401
+ "status": "protocol_boundary_verified",
402
+ "scope": "optional pairwise poll/ping clients; no push",
403
+ "finding": "Configured pairwise clients require private_key_jwt or self_signed_tls_client_auth with registered remote key material. Missing keys and Basic authentication reject; a signed request alone does not waive this restriction in either gem or reference. Current private-key/pairwise and certificate-proof tests pass on three DBs, with separate installed TLS and reference HTTP/TLS evidence. This verifies the reference-supported proof methods, not push or arbitrary app identity policy.",
404
+ "code_refs": [
405
+ "lib/rodauth/ciba/pairwise.rb",
406
+ "lib/rodauth/ciba/mtls.rb",
407
+ "docs/pairwise.md"
408
+ ],
409
+ "test_refs": [
410
+ {
411
+ "file": "test/ciba_pairwise_mtls_test.rb",
412
+ "method": "test_pairwise_self_signed_mtls_jwt"
413
+ },
414
+ {
415
+ "file": "test/ciba_pairwise_test.rb",
416
+ "method": "test_pairwise_dynamic_registration_reuses_same_eligibility_boundary"
417
+ },
418
+ {
419
+ "file": "test/ciba_pairwise_test.rb",
420
+ "method": "test_pairwise_signed_request_does_not_waive_client_authentication_policy"
421
+ }
422
+ ],
423
+ "execution": "docs/validation/pairwise-signature-audit-current.txt"
424
+ },
425
+ {
426
+ "id": "CIBA-018",
427
+ "label": "push pairwise sector",
428
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.4",
429
+ "status": "reference_unsupported",
430
+ "scope": "push mode, unsupported by pinned node 9.12.2 and the gem; poll/ping remain in scope",
431
+ "finding": "Conditional push behavior is not implemented or advertised. Pinned node 9.12.2 rejects push provider configuration; the gem rejects push registration and request eligibility. This records non-applicability to the shared enabled modes, not a passing push implementation.",
432
+ "code_refs": [
433
+ "lib/rodauth/features/ciba.rb",
434
+ "lib/rodauth/ciba/registration.rb",
435
+ "docs/research/push-reference-boundary.md"
436
+ ],
437
+ "test_refs": [],
438
+ "execution": "docs/validation/node-push-boundary.txt"
439
+ },
440
+ {
441
+ "id": "CIBA-019",
442
+ "label": "poll配送",
443
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.5",
444
+ "status": "protocol_boundary_verified",
445
+ "scope": "CIBA protocol transport and registered authentication; deployment and arbitrary method combinations remain separate",
446
+ "finding": "Approved poll requests obtain a signed ID Token and access token through the token endpoint, followed by single-use rejection.",
447
+ "code_refs": [
448
+ "lib/rodauth/features/ciba.rb",
449
+ "docs/api.md"
450
+ ],
451
+ "test_refs": [
452
+ {
453
+ "file": "test/ciba_integration_test.rb",
454
+ "method": "test_approved_request_issues_customer_id_token_once"
455
+ }
456
+ ],
457
+ "execution": "docs/validation/auth-transport-audit-current.txt"
458
+ },
459
+ {
460
+ "id": "CIBA-020",
461
+ "label": "ping配送",
462
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.5",
463
+ "status": "protocol_boundary_verified",
464
+ "scope": "ping enabled; statements shared with push are assessed for ping only",
465
+ "finding": "Approval/denial persists before notification; authenticated retrieval remains possible despite send failure. This matches the measured reference save-before-send boundary.",
466
+ "code_refs": [
467
+ "lib/rodauth/features/ciba.rb",
468
+ "lib/rodauth/ciba/http.rb",
469
+ "docs/ping.md"
470
+ ],
471
+ "test_refs": [
472
+ {
473
+ "file": "test/ciba_ping_test.rb",
474
+ "method": "test_ping_delivery_failure_keeps_result_and_retry_is_separate"
475
+ }
476
+ ],
477
+ "execution": "docs/validation/ping-audit-current.txt"
478
+ },
479
+ {
480
+ "id": "CIBA-021",
481
+ "label": "push配送",
482
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.5",
483
+ "status": "reference_unsupported",
484
+ "scope": "push mode, unsupported by pinned node 9.12.2 and the gem; poll/ping remain in scope",
485
+ "finding": "Conditional push behavior is not implemented or advertised. Pinned node 9.12.2 rejects push provider configuration; the gem rejects push registration and request eligibility. This records non-applicability to the shared enabled modes, not a passing push implementation.",
486
+ "code_refs": [
487
+ "lib/rodauth/features/ciba.rb",
488
+ "lib/rodauth/ciba/registration.rb",
489
+ "docs/research/push-reference-boundary.md"
490
+ ],
491
+ "test_refs": [],
492
+ "execution": "docs/validation/node-push-boundary.txt"
493
+ },
494
+ {
495
+ "id": "CIBA-022",
496
+ "label": "push sender-constrained token",
497
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.5",
498
+ "status": "reference_unsupported",
499
+ "scope": "push mode, unsupported by pinned node 9.12.2 and the gem; poll/ping remain in scope",
500
+ "finding": "Conditional push behavior is not implemented or advertised. Pinned node 9.12.2 rejects push provider configuration; the gem rejects push registration and request eligibility. This records non-applicability to the shared enabled modes, not a passing push implementation.",
501
+ "code_refs": [
502
+ "lib/rodauth/features/ciba.rb",
503
+ "lib/rodauth/ciba/registration.rb",
504
+ "docs/research/push-reference-boundary.md"
505
+ ],
506
+ "test_refs": [],
507
+ "execution": "docs/validation/node-push-boundary.txt"
508
+ },
509
+ {
510
+ "id": "CIBA-023",
511
+ "label": "開始APIのTLS",
512
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.7",
513
+ "status": "protocol_boundary_verified",
514
+ "scope": "CIBA protocol transport and registered authentication; deployment and arbitrary method combinations remain separate",
515
+ "finding": "Authenticated HTTP requests are rejected before state changes; HTTPS Rack requests are accepted. Actual TLS termination and trusted proxy configuration remain deployment responsibilities with separate TLS fixtures.",
516
+ "code_refs": [
517
+ "lib/rodauth/features/ciba.rb",
518
+ "docs/api.md"
519
+ ],
520
+ "test_refs": [
521
+ {
522
+ "file": "test/ciba_protocol_test.rb",
523
+ "method": "test_ciba_endpoints_require_tls_post_and_form_before_state_changes"
524
+ },
525
+ {
526
+ "file": "test/ciba_protocol_test.rb",
527
+ "method": "test_rack_inputs_without_rewind_work_on_both_endpoints"
528
+ },
529
+ {
530
+ "file": "test/ciba_configuration_test.rb",
531
+ "method": "test_invalid_utf8_and_oversized_body_are_rejected"
532
+ }
533
+ ],
534
+ "execution": "docs/validation/auth-transport-audit-current.txt"
535
+ },
536
+ {
537
+ "id": "CIBA-024",
538
+ "label": "開始APIのPOSTとform",
539
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.7.1",
540
+ "status": "protocol_boundary_verified",
541
+ "scope": "CIBA protocol transport and registered authentication; deployment and arbitrary method combinations remain separate",
542
+ "finding": "HTTPS POST form input is accepted, including non-rewindable request bodies. JSON and GET do not issue requests or tokens; malformed UTF8/form input is rejected. Backchannel GET is 404, token GET with CIBA grant is invalid_request.",
543
+ "code_refs": [
544
+ "lib/rodauth/features/ciba.rb",
545
+ "docs/api.md"
546
+ ],
547
+ "test_refs": [
548
+ {
549
+ "file": "test/ciba_protocol_test.rb",
550
+ "method": "test_ciba_endpoints_require_tls_post_and_form_before_state_changes"
551
+ },
552
+ {
553
+ "file": "test/ciba_protocol_test.rb",
554
+ "method": "test_rack_inputs_without_rewind_work_on_both_endpoints"
555
+ },
556
+ {
557
+ "file": "test/ciba_configuration_test.rb",
558
+ "method": "test_invalid_utf8_and_oversized_body_are_rejected"
559
+ }
560
+ ],
561
+ "execution": "docs/validation/auth-transport-audit-current.txt"
562
+ },
563
+ {
564
+ "id": "CIBA-025",
565
+ "label": "開始APIのクライアント認証",
566
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.7.1",
567
+ "status": "protocol_boundary_verified",
568
+ "scope": "Configured Basic/post, private_key_jwt/client_secret_jwt (fourteen algorithms), PKI/self-signed TLS; deployment trust and arbitrary extension combinations excluded",
569
+ "finding": "Configured methods have direct endpoint authentication/negative evidence. Fourteen RS/PS/ES/HS/Edwards algorithms have reference HTTP and gem verification evidence; Edwards adds DCR, remote HTTP rotation/failure, installed HTTPS retrieval with untrusted-TLS rejection, replay protection and ordinary-flow coexistence. A CIBA Edwards-only configuration preserves unrelated RSA client authentication and upstream metadata. See client-auth-edwards-scope-matrix.txt and client-auth-edwards-https-installed.txt. This is bounded protocol evidence, not deployment certification.",
570
+ "code_refs": [
571
+ "lib/rodauth/features/ciba.rb",
572
+ "docs/api.md",
573
+ "docs/research/client-assertion-algorithm-contract.md"
574
+ ],
575
+ "test_refs": [
576
+ {
577
+ "file": "test/ciba_security_test.rb",
578
+ "method": "test_jwt_client_assertion_requires_issuer_expiry_and_jti"
579
+ },
580
+ {
581
+ "file": "test/ciba_security_test.rb",
582
+ "method": "test_jwt_client_assertion_is_single_use"
583
+ },
584
+ {
585
+ "file": "test/ciba_security_test.rb",
586
+ "method": "test_malformed_assertions_are_authentication_errors_at_both_ciba_endpoints"
587
+ },
588
+ {
589
+ "file": "test/ciba_security_test.rb",
590
+ "method": "test_backchannel_ignores_other_grant_parameters_without_bypassing_client_authentication"
591
+ },
592
+ {
593
+ "file": "test/ciba_security_test.rb",
594
+ "method": "test_assertion_subject_cannot_override_explicit_client_id"
595
+ },
596
+ {
597
+ "file": "test/ciba_auth_algorithm_matrix_test.rb",
598
+ "method": "test_configured_client_assertion_algorithms_at_both_ciba_endpoints"
599
+ },
600
+ {
601
+ "file": "test/ciba_registration_test.rb",
602
+ "method": "test_ciba_registration_rejects_assertion_type_as_authentication_method"
603
+ },
604
+ {
605
+ "file": "test/ciba_edwards_auth_test.rb",
606
+ "method": "test_edwards_client_authentication_at_both_endpoints"
607
+ },
608
+ {
609
+ "file": "test/ciba_edwards_auth_remote_test.rb",
610
+ "method": "test_edwards_client_authentication_remote_rotation_failure_and_ordinary_grant"
611
+ },
612
+ {
613
+ "file": "test/ciba_edwards_auth_test.rb",
614
+ "method": "test_edwards_authentication_configuration_preserves_unrelated_rsa_clients"
615
+ }
616
+ ],
617
+ "execution": "docs/validation/client-auth-edwards-scope-matrix.txt"
618
+ },
619
+ {
620
+ "id": "CIBA-026",
621
+ "label": "JWT audienceのissuer受理",
622
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.7.1",
623
+ "status": "protocol_boundary_verified",
624
+ "scope": "CIBA protocol transport and registered authentication; deployment and arbitrary method combinations remain separate",
625
+ "finding": "Issuer audience is accepted for private_key_jwt at Backchannel and for private_key_jwt/client_secret_jwt CIBA issuance and refresh; unrelated token flows retain their prior audience rules.",
626
+ "code_refs": [
627
+ "lib/rodauth/features/ciba.rb",
628
+ "docs/api.md"
629
+ ],
630
+ "test_refs": [
631
+ {
632
+ "file": "test/ciba_configuration_test.rb",
633
+ "method": "test_upstream_jwt_authentication_coexists_with_ciba_and_discovery"
634
+ },
635
+ {
636
+ "file": "test/ciba_assertion_refresh_test.rb",
637
+ "method": "test_ciba_private_key_assertion_refresh_accepts_issuer_audience"
638
+ },
639
+ {
640
+ "file": "test/ciba_assertion_refresh_test.rb",
641
+ "method": "test_ciba_secret_assertion_refresh_accepts_issuer_audience"
642
+ }
643
+ ],
644
+ "execution": "docs/validation/auth-transport-audit-current.txt"
645
+ },
646
+ {
647
+ "id": "CIBA-027",
648
+ "label": "JWT audienceのToken URL受理",
649
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.7.1",
650
+ "status": "protocol_boundary_verified",
651
+ "scope": "CIBA protocol transport and registered authentication; deployment and arbitrary method combinations remain separate",
652
+ "finding": "Token endpoint URL is accepted as private_key_jwt audience at Backchannel, then the same client can complete and collect tokens.",
653
+ "code_refs": [
654
+ "lib/rodauth/features/ciba.rb",
655
+ "docs/api.md"
656
+ ],
657
+ "test_refs": [
658
+ {
659
+ "file": "test/ciba_configuration_test.rb",
660
+ "method": "test_upstream_jwt_authentication_coexists_with_ciba_and_discovery"
661
+ }
662
+ ],
663
+ "execution": "docs/validation/auth-transport-audit-current.txt"
664
+ },
665
+ {
666
+ "id": "CIBA-028",
667
+ "label": "JWT audienceのBackchannel URL受理",
668
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.7.1",
669
+ "status": "protocol_boundary_verified",
670
+ "scope": "CIBA protocol transport and registered authentication; deployment and arbitrary method combinations remain separate",
671
+ "finding": "Backchannel endpoint URL is accepted as private_key_jwt audience at Backchannel; resulting approved issuance succeeds.",
672
+ "code_refs": [
673
+ "lib/rodauth/features/ciba.rb",
674
+ "docs/api.md"
675
+ ],
676
+ "test_refs": [
677
+ {
678
+ "file": "test/ciba_configuration_test.rb",
679
+ "method": "test_upstream_jwt_authentication_coexists_with_ciba_and_discovery"
680
+ }
681
+ ],
682
+ "execution": "docs/validation/auth-transport-audit-current.txt"
683
+ },
684
+ {
685
+ "id": "CIBA-029",
686
+ "label": "JWT audienceのissuer推奨",
687
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.7.1",
688
+ "status": "client_only",
689
+ "scope": "CIBA protocol transport and registered authentication; deployment and arbitrary method combinations remain separate",
690
+ "finding": "The recommendation to choose issuer audience is a client responsibility. OP acceptance tests establish support but do not prove external clients follow the recommendation.",
691
+ "code_refs": [
692
+ "lib/rodauth/features/ciba.rb",
693
+ "docs/api.md"
694
+ ],
695
+ "test_refs": [],
696
+ "execution": null
697
+ },
698
+ {
699
+ "id": "CIBA-030",
700
+ "label": "scope必須",
701
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.7.1",
702
+ "status": "protocol_boundary_verified",
703
+ "scope": "baseline request parameters and enabled hint-token boundary; UI and deployment policy remain external",
704
+ "finding": "Missing scope fails before acceptance; malformed scope has a distinct invalid_scope response.",
705
+ "code_refs": [
706
+ "lib/rodauth/features/ciba.rb",
707
+ "docs/api.md"
708
+ ],
709
+ "test_refs": [
710
+ {
711
+ "file": "test/ciba_requirements_test.rb",
712
+ "method": "test_scope_syntax_errors_are_invalid_scope"
713
+ }
714
+ ],
715
+ "execution": "docs/validation/request-parameters-audit-current.txt"
716
+ },
717
+ {
718
+ "id": "CIBA-031",
719
+ "label": "openid scope",
720
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.7.1",
721
+ "status": "protocol_boundary_verified",
722
+ "scope": "baseline request parameters and enabled hint-token boundary; UI and deployment policy remain external",
723
+ "finding": "A scope set without openid is rejected for CIBA.",
724
+ "code_refs": [
725
+ "lib/rodauth/features/ciba.rb",
726
+ "docs/api.md"
727
+ ],
728
+ "test_refs": [
729
+ {
730
+ "file": "test/ciba_protocol_test.rb",
731
+ "method": "test_request_validation_and_unknown_parameters"
732
+ }
733
+ ],
734
+ "execution": "docs/validation/request-parameters-audit-current.txt"
735
+ },
736
+ {
737
+ "id": "CIBA-032",
738
+ "label": "追加scope",
739
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.7.1",
740
+ "status": "protocol_boundary_verified",
741
+ "scope": "baseline request parameters and enabled hint-token boundary; UI and deployment policy remain external",
742
+ "finding": "An additional read scope allowed by both server and client survives acceptance and issuance.",
743
+ "code_refs": [
744
+ "lib/rodauth/features/ciba.rb",
745
+ "docs/api.md"
746
+ ],
747
+ "test_refs": [
748
+ {
749
+ "file": "test/ciba_security_test.rb",
750
+ "method": "test_additional_authorized_scopes_survive_acceptance_and_token_issuance"
751
+ }
752
+ ],
753
+ "execution": "docs/validation/request-parameters-audit-current.txt"
754
+ },
755
+ {
756
+ "id": "CIBA-033",
757
+ "label": "通知トークン必須条件",
758
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.7.1",
759
+ "status": "protocol_boundary_verified",
760
+ "scope": "ping enabled; statements shared with push are assessed for ping only",
761
+ "finding": "Ping requires a nonempty notification token before persistence. Push remains outside the implementation.",
762
+ "code_refs": [
763
+ "lib/rodauth/features/ciba.rb",
764
+ "lib/rodauth/ciba/http.rb",
765
+ "docs/ping.md"
766
+ ],
767
+ "test_refs": [
768
+ {
769
+ "file": "test/ciba_ping_test.rb",
770
+ "method": "test_ping_rejects_bad_tokens_and_uses_current_registered_destination"
771
+ }
772
+ ],
773
+ "execution": "docs/validation/ping-current-endpoint-matrix.txt"
774
+ },
775
+ {
776
+ "id": "CIBA-034",
777
+ "label": "通知トークンの長さと構文",
778
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.7.1",
779
+ "status": "protocol_boundary_verified",
780
+ "scope": "ping enabled; statements shared with push are assessed for ping only",
781
+ "finding": "Bearer syntax and1024-character ASCII boundary checked; CRLF, misplaced padding and non-ASCII rejected without pending records.",
782
+ "code_refs": [
783
+ "lib/rodauth/features/ciba.rb",
784
+ "lib/rodauth/ciba/http.rb",
785
+ "docs/ping.md"
786
+ ],
787
+ "test_refs": [
788
+ {
789
+ "file": "test/ciba_ping_test.rb",
790
+ "method": "test_ping_notification_token_bearer_syntax_and_maximum_length"
791
+ }
792
+ ],
793
+ "execution": "docs/validation/ping-audit-current.txt"
794
+ },
795
+ {
796
+ "id": "CIBA-035",
797
+ "label": "通知トークンentropy",
798
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.7.1",
799
+ "status": "client_only",
800
+ "scope": "ping enabled; statements shared with push are assessed for ping only",
801
+ "finding": "Required entropy is a client generation obligation. No syntax or length check can prove randomness. Minimum128/recommended160 bits are documented.",
802
+ "code_refs": [
803
+ "lib/rodauth/features/ciba.rb",
804
+ "lib/rodauth/ciba/http.rb",
805
+ "docs/ping.md"
806
+ ],
807
+ "test_refs": [],
808
+ "execution": null
809
+ },
810
+ {
811
+ "id": "CIBA-036",
812
+ "label": "acr_values受理",
813
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.7.1",
814
+ "status": "protocol_boundary_verified",
815
+ "scope": "baseline request parameters and enabled hint-token boundary; UI and deployment policy remain external",
816
+ "finding": "Requested ACR preference order is retained in the frozen application dispatch snapshot; the gem does not choose an authentication method.",
817
+ "code_refs": [
818
+ "lib/rodauth/features/ciba.rb",
819
+ "docs/api.md"
820
+ ],
821
+ "test_refs": [
822
+ {
823
+ "file": "test/ciba_protocol_test.rb",
824
+ "method": "test_login_hint_is_application_defined_and_unknown_fields_cannot_set_state"
825
+ }
826
+ ],
827
+ "execution": "docs/validation/request-parameters-audit-current.txt"
828
+ },
829
+ {
830
+ "id": "CIBA-037",
831
+ "label": "達成したacrの返却",
832
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.7.1",
833
+ "status": "protocol_boundary_verified",
834
+ "scope": "baseline request parameters and enabled hint-token boundary; UI and deployment policy remain external",
835
+ "finding": "ID Token carries the achieved ACR supplied at completion, even when different from requested preferences. Truthfulness and adequacy of the application authentication are not proven.",
836
+ "code_refs": [
837
+ "lib/rodauth/features/ciba.rb",
838
+ "docs/api.md"
839
+ ],
840
+ "test_refs": [
841
+ {
842
+ "file": "test/ciba_protocol_test.rb",
843
+ "method": "test_login_hint_is_application_defined_and_unknown_fields_cannot_set_state"
844
+ }
845
+ ],
846
+ "execution": "docs/validation/request-parameters-audit-current.txt"
847
+ },
848
+ {
849
+ "id": "CIBA-038",
850
+ "label": "login_hint_token",
851
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.7.1",
852
+ "status": "protocol_boundary_verified",
853
+ "scope": "optional hint mechanisms enabled where applicable",
854
+ "finding": "Authenticated client is passed to the required application resolver; identity eligibility and raw-value exclusion are checked. Token-format validation belongs to the application.",
855
+ "code_refs": [
856
+ "lib/rodauth/features/ciba.rb",
857
+ "docs/login-hint-token.md",
858
+ "docs/id-token-hint.md"
859
+ ],
860
+ "test_refs": [
861
+ {
862
+ "file": "test/ciba_hint_token_test.rb",
863
+ "method": "test_hint_token_resolver_receives_authenticated_client_and_does_not_persist_raw_token"
864
+ }
865
+ ],
866
+ "execution": "docs/validation/hint-audit-current.txt"
867
+ },
868
+ {
869
+ "id": "CIBA-039",
870
+ "label": "id_token_hint",
871
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.7.1",
872
+ "status": "protocol_boundary_verified",
873
+ "scope": "optional hint mechanisms enabled where applicable",
874
+ "finding": "Verified ID Token identity creates a new pending request; approval is not inherited.",
875
+ "code_refs": [
876
+ "lib/rodauth/features/ciba.rb",
877
+ "docs/login-hint-token.md",
878
+ "docs/id-token-hint.md"
879
+ ],
880
+ "test_refs": [
881
+ {
882
+ "file": "test/ciba_id_token_hint_test.rb",
883
+ "method": "test_id_hint_expired_token_is_only_an_identity_hint"
884
+ }
885
+ ],
886
+ "execution": "docs/validation/hint-audit-current.txt"
887
+ },
888
+ {
889
+ "id": "CIBA-040",
890
+ "label": "暗号化id_token_hintの復号",
891
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.7.1",
892
+ "status": "client_only",
893
+ "scope": "optional hint mechanisms enabled where applicable",
894
+ "finding": "Decrypting an encrypted ID Token before submitting its signed inner token is a Client duty. A real nested JWE is rejected by the gem; the decrypted signed hint is accepted. This matches measured node behavior, not missing OP decryption support.",
895
+ "code_refs": [
896
+ "lib/rodauth/features/ciba.rb",
897
+ "docs/login-hint-token.md",
898
+ "docs/id-token-hint.md"
899
+ ],
900
+ "test_refs": [
901
+ {
902
+ "file": "test/ciba_id_token_hint_test.rb",
903
+ "method": "test_id_hint_rejects_valid_nested_encryption_before_resolving_identity"
904
+ }
905
+ ],
906
+ "execution": "docs/validation/hint-audit-current.txt"
907
+ },
908
+ {
909
+ "id": "CIBA-041",
910
+ "label": "login_hint",
911
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.7.1",
912
+ "status": "protocol_boundary_verified",
913
+ "scope": "baseline request parameters and enabled hint-token boundary; UI and deployment policy remain external",
914
+ "finding": "A non-email customer reference resolves through an application callback in authenticated-client context. No built-in email interpretation is required.",
915
+ "code_refs": [
916
+ "lib/rodauth/features/ciba.rb",
917
+ "docs/api.md"
918
+ ],
919
+ "test_refs": [
920
+ {
921
+ "file": "test/ciba_protocol_test.rb",
922
+ "method": "test_login_hint_is_application_defined_and_unknown_fields_cannot_set_state"
923
+ }
924
+ ],
925
+ "execution": "docs/validation/request-parameters-audit-current.txt"
926
+ },
927
+ {
928
+ "id": "CIBA-042",
929
+ "label": "binding_messageの受理と引継ぎ",
930
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.7.1",
931
+ "status": "app_contract",
932
+ "scope": "baseline request parameters and enabled hint-token boundary; UI and deployment policy remain external",
933
+ "finding": "Binding message is preserved for the application dispatch snapshot. Display on AD/CD, safe rendering and end-user confirmation remain application/client duties, not proven by the Ruby snapshot test.",
934
+ "code_refs": [
935
+ "lib/rodauth/features/ciba.rb",
936
+ "docs/api.md"
937
+ ],
938
+ "test_refs": [
939
+ {
940
+ "file": "test/ciba_protocol_test.rb",
941
+ "method": "test_login_hint_is_application_defined_and_unknown_fields_cannot_set_state"
942
+ }
943
+ ],
944
+ "execution": "docs/validation/request-parameters-audit-current.txt"
945
+ },
946
+ {
947
+ "id": "CIBA-043",
948
+ "label": "binding_messageの関連付け",
949
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.7.1",
950
+ "status": "client_only",
951
+ "scope": "baseline request parameters and enabled hint-token boundary; UI and deployment policy remain external",
952
+ "finding": "The client must choose a meaningful correlation message. OP storage and dispatch cannot prove the correlation seen by the end-user.",
953
+ "code_refs": [
954
+ "lib/rodauth/features/ciba.rb",
955
+ "docs/api.md"
956
+ ],
957
+ "test_refs": [],
958
+ "execution": null
959
+ },
960
+ {
961
+ "id": "CIBA-044",
962
+ "label": "binding_messageの表示適性",
963
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.7.1",
964
+ "status": "protocol_boundary_verified",
965
+ "scope": "baseline request parameters and enabled hint-token boundary; UI and deployment policy remain external",
966
+ "finding": "The default node-aligned policy accepts 1–20 characters from its limited ASCII set and rejects whitespace, control and other characters. Applications may replace this display policy and own the resulting UI safety.",
967
+ "code_refs": [
968
+ "lib/rodauth/features/ciba.rb",
969
+ "docs/api.md"
970
+ ],
971
+ "test_refs": [
972
+ {
973
+ "file": "test/ciba_alignment_test.rb",
974
+ "method": "test_binding_message_default_matches_node_oidc_provider_policy"
975
+ },
976
+ {
977
+ "file": "test/ciba_alignment_test.rb",
978
+ "method": "test_application_can_replace_binding_message_policy"
979
+ }
980
+ ],
981
+ "execution": "docs/validation/request-parameters-audit-current.txt"
982
+ },
983
+ {
984
+ "id": "CIBA-045",
985
+ "label": "user_code",
986
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.7.1",
987
+ "status": "protocol_boundary_verified",
988
+ "scope": "user-code feature enabled unless otherwise stated",
989
+ "finding": "Mandatory application verifier receives resolved account/client/code before insertion or dispatch; rejection has no pending request. Production verifier correctness remains application-owned.",
990
+ "code_refs": [
991
+ "lib/rodauth/features/ciba.rb",
992
+ "docs/user-code.md"
993
+ ],
994
+ "test_refs": [
995
+ {
996
+ "file": "test/ciba_user_code_test.rb",
997
+ "method": "test_user_code_requires_explicit_callback_and_checks_before_device_dispatch"
998
+ }
999
+ ],
1000
+ "execution": "docs/validation/user-code-audit-current.txt"
1001
+ },
1002
+ {
1003
+ "id": "CIBA-046",
1004
+ "label": "requested_expiry構文",
1005
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.7.1",
1006
+ "status": "protocol_boundary_verified",
1007
+ "scope": "baseline request parameters and enabled hint-token boundary; UI and deployment policy remain external",
1008
+ "finding": "Unsigned requested_expiry accepts positive decimal syntax and rejects zero, negatives, fractions and nonnumeric strings. Signed JSON-number handling is audited separately.",
1009
+ "code_refs": [
1010
+ "lib/rodauth/features/ciba.rb",
1011
+ "docs/api.md"
1012
+ ],
1013
+ "test_refs": [
1014
+ {
1015
+ "file": "test/ciba_protocol_test.rb",
1016
+ "method": "test_expiry_binding_context_and_offline_access"
1017
+ }
1018
+ ],
1019
+ "execution": "docs/validation/request-parameters-audit-current.txt"
1020
+ },
1021
+ {
1022
+ "id": "CIBA-047",
1023
+ "label": "requested_expiryの採用",
1024
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.7.1",
1025
+ "status": "protocol_boundary_verified",
1026
+ "scope": "baseline request parameters and enabled hint-token boundary; UI and deployment policy remain external",
1027
+ "finding": "Requested lifetime is used up to the configured maximum; the default and cap are directly asserted. Callback elapsed-time limits remain in CIBA-080.",
1028
+ "code_refs": [
1029
+ "lib/rodauth/features/ciba.rb",
1030
+ "docs/api.md"
1031
+ ],
1032
+ "test_refs": [
1033
+ {
1034
+ "file": "test/ciba_alignment_test.rb",
1035
+ "method": "test_default_request_lifetime_matches_node_policy"
1036
+ }
1037
+ ],
1038
+ "execution": "docs/validation/request-parameters-audit-current.txt"
1039
+ },
1040
+ {
1041
+ "id": "CIBA-048",
1042
+ "label": "hintはちょうど一つ",
1043
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.7.1",
1044
+ "status": "protocol_boundary_verified",
1045
+ "scope": "baseline request parameters and enabled hint-token boundary; UI and deployment policy remain external",
1046
+ "finding": "Exactly one recognized hint name is required; absent, empty and mixed hint inputs fail before resolver dispatch. The opt-in token resolver tests validate this with optional hints enabled.",
1047
+ "code_refs": [
1048
+ "lib/rodauth/features/ciba.rb",
1049
+ "docs/api.md"
1050
+ ],
1051
+ "test_refs": [
1052
+ {
1053
+ "file": "test/ciba_hint_token_test.rb",
1054
+ "method": "test_hint_token_input_exclusivity_size_and_unknown_user"
1055
+ }
1056
+ ],
1057
+ "execution": "docs/validation/request-parameters-audit-current.txt"
1058
+ },
1059
+ {
1060
+ "id": "CIBA-049",
1061
+ "label": "署名要求のJWT形式",
1062
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.7.1.1",
1063
+ "status": "protocol_boundary_verified",
1064
+ "scope": "signed authentication requests enabled; configured asymmetric algorithms",
1065
+ "finding": "Signed inner parameters determine new pending work; normal request validation still applies.",
1066
+ "code_refs": [
1067
+ "lib/rodauth/features/ciba.rb",
1068
+ "docs/signed-requests.md"
1069
+ ],
1070
+ "test_refs": [
1071
+ {
1072
+ "file": "test/ciba_signed_request_test.rb",
1073
+ "method": "test_signed_request_isolated_parameters_new_approval_and_repeated_submission"
1074
+ }
1075
+ ],
1076
+ "execution": "docs/validation/signed-request-audit-current.txt"
1077
+ },
1078
+ {
1079
+ "id": "CIBA-050",
1080
+ "label": "署名要求の非対称署名",
1081
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.7.1.1",
1082
+ "status": "protocol_boundary_verified",
1083
+ "scope": "configured RS/PS/ES algorithms and Ed25519/EdDSA with Ed25519 curve; signed CIBA requests only",
1084
+ "finding": "All eleven configured algorithm names have reference/gem acceptance and wrong-key rejection evidence. Edwards Node/jose fixed vectors pass inline and actual HTTP remote JWKS on three DBs, reject payload tampering, and issue verified ID Tokens from the installed artifact with opaque/JWT access tokens. No global JWT/client-auth or Ed448 capability is implied.",
1085
+ "code_refs": [
1086
+ "lib/rodauth/features/ciba.rb",
1087
+ "docs/signed-requests.md",
1088
+ "docs/research/alignment-partial-triage.md"
1089
+ ],
1090
+ "test_refs": [
1091
+ {
1092
+ "file": "test/ciba_signed_request_test.rb",
1093
+ "method": "test_signed_request_configured_asymmetric_algorithms_and_encrypted_shape"
1094
+ },
1095
+ {
1096
+ "file": "test/ciba_edwards_request_test.rb",
1097
+ "method": "test_edwards_signed_requests_and_key_rejection"
1098
+ },
1099
+ {
1100
+ "file": "test/ciba_edwards_request_test.rb",
1101
+ "method": "test_node_generated_edwards_vectors_with_inline_keys"
1102
+ },
1103
+ {
1104
+ "file": "test/ciba_edwards_request_test.rb",
1105
+ "method": "test_node_generated_edwards_vectors_with_remote_keys"
1106
+ }
1107
+ ],
1108
+ "execution": "docs/validation/edwards-vectors-matrix.txt"
1109
+ },
1110
+ {
1111
+ "id": "CIBA-051",
1112
+ "label": "署名要求のaud",
1113
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.7.1.1",
1114
+ "status": "protocol_boundary_verified",
1115
+ "scope": "signed authentication requests enabled; configured asymmetric algorithms",
1116
+ "finding": "OP issuer audience membership is checked; incorrect/missing audience rejected. Array audience path is code-reviewed but not directly covered by this test.",
1117
+ "code_refs": [
1118
+ "lib/rodauth/features/ciba.rb",
1119
+ "docs/signed-requests.md"
1120
+ ],
1121
+ "test_refs": [
1122
+ {
1123
+ "file": "test/ciba_signed_request_test.rb",
1124
+ "method": "test_signed_request_rejects_bad_claims_and_keys_before_persistence"
1125
+ }
1126
+ ],
1127
+ "execution": "docs/validation/signed-request-audit-current.txt"
1128
+ },
1129
+ {
1130
+ "id": "CIBA-052",
1131
+ "label": "署名要求のiss",
1132
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.7.1.1",
1133
+ "status": "protocol_boundary_verified",
1134
+ "scope": "signed authentication requests enabled; configured asymmetric algorithms",
1135
+ "finding": "Request issuer must match the independently authenticated client.",
1136
+ "code_refs": [
1137
+ "lib/rodauth/features/ciba.rb",
1138
+ "docs/signed-requests.md"
1139
+ ],
1140
+ "test_refs": [
1141
+ {
1142
+ "file": "test/ciba_signed_request_test.rb",
1143
+ "method": "test_signed_request_rejects_bad_claims_and_keys_before_persistence"
1144
+ }
1145
+ ],
1146
+ "execution": "docs/validation/signed-request-audit-current.txt"
1147
+ },
1148
+ {
1149
+ "id": "CIBA-053",
1150
+ "label": "署名要求のexp",
1151
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.7.1.1",
1152
+ "status": "protocol_boundary_verified",
1153
+ "scope": "signed authentication requests enabled; configured asymmetric algorithms",
1154
+ "finding": "Required finite numeric exp, including fractional NumericDate, accepted only while unexpired under configured tolerance. Missing/string/boolean/array/expired values rejected before persistence.",
1155
+ "code_refs": [
1156
+ "lib/rodauth/features/ciba.rb",
1157
+ "docs/signed-requests.md"
1158
+ ],
1159
+ "test_refs": [
1160
+ {
1161
+ "file": "test/ciba_signed_request_test.rb",
1162
+ "method": "test_signed_request_rejects_bad_claims_and_keys_before_persistence"
1163
+ },
1164
+ {
1165
+ "file": "test/ciba_signed_request_test.rb",
1166
+ "method": "test_signed_request_numeric_dates_match_reference_without_inheriting_approval"
1167
+ }
1168
+ ],
1169
+ "execution": "docs/validation/signed-numericdate-matrix.txt"
1170
+ },
1171
+ {
1172
+ "id": "CIBA-054",
1173
+ "label": "署名要求のiat",
1174
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.7.1.1",
1175
+ "status": "protocol_boundary_verified",
1176
+ "scope": "signed authentication requests enabled; configured asymmetric algorithms",
1177
+ "finding": "Required finite numeric iat, including fractional and future values, matches measured reference acceptance. No independent future-iat restriction; valid exp/nbf and explicit customer approval still required.",
1178
+ "code_refs": [
1179
+ "lib/rodauth/features/ciba.rb",
1180
+ "docs/signed-requests.md"
1181
+ ],
1182
+ "test_refs": [
1183
+ {
1184
+ "file": "test/ciba_signed_request_test.rb",
1185
+ "method": "test_signed_request_rejects_bad_claims_and_keys_before_persistence"
1186
+ },
1187
+ {
1188
+ "file": "test/ciba_signed_request_test.rb",
1189
+ "method": "test_signed_request_numeric_dates_match_reference_without_inheriting_approval"
1190
+ }
1191
+ ],
1192
+ "execution": "docs/validation/signed-numericdate-matrix.txt"
1193
+ },
1194
+ {
1195
+ "id": "CIBA-055",
1196
+ "label": "署名要求のnbf",
1197
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.7.1.1",
1198
+ "status": "protocol_boundary_verified",
1199
+ "scope": "signed authentication requests enabled; configured asymmetric algorithms",
1200
+ "finding": "Required finite numeric nbf, including fractional NumericDate, checked against current time and configured tolerance. Future and malformed values rejected before persistence.",
1201
+ "code_refs": [
1202
+ "lib/rodauth/features/ciba.rb",
1203
+ "docs/signed-requests.md"
1204
+ ],
1205
+ "test_refs": [
1206
+ {
1207
+ "file": "test/ciba_signed_request_test.rb",
1208
+ "method": "test_signed_request_rejects_bad_claims_and_keys_before_persistence"
1209
+ },
1210
+ {
1211
+ "file": "test/ciba_signed_request_test.rb",
1212
+ "method": "test_signed_request_numeric_dates_match_reference_without_inheriting_approval"
1213
+ }
1214
+ ],
1215
+ "execution": "docs/validation/signed-numericdate-matrix.txt"
1216
+ },
1217
+ {
1218
+ "id": "CIBA-056",
1219
+ "label": "署名要求のjti",
1220
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.7.1.1",
1221
+ "status": "protocol_boundary_verified",
1222
+ "scope": "signed authentication requests enabled; configured asymmetric algorithms",
1223
+ "finding": "Like the reference, signed authentication requests require a present string jti, including empty strings; null/non-string values reject. Repeated identical requests produce distinct auth_req_id values with new pending approval, including after prior issuance. Identifier uniqueness remains a client obligation. This is separate from client authentication assertions, whose nonempty-jti and atomic replay checks are unchanged.",
1224
+ "code_refs": [
1225
+ "lib/rodauth/features/ciba.rb",
1226
+ "docs/signed-requests.md"
1227
+ ],
1228
+ "test_refs": [
1229
+ {
1230
+ "file": "test/ciba_signed_request_test.rb",
1231
+ "method": "test_signed_request_isolated_parameters_new_approval_and_repeated_submission"
1232
+ },
1233
+ {
1234
+ "file": "test/ciba_signed_request_test.rb",
1235
+ "method": "test_signed_request_empty_jti_matches_reference_without_reusing_approval"
1236
+ }
1237
+ ],
1238
+ "execution": "docs/validation/signed-jti-matrix.txt"
1239
+ },
1240
+ {
1241
+ "id": "CIBA-057",
1242
+ "label": "署名要求のrequested_expiry型",
1243
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.7.1.1",
1244
+ "status": "protocol_boundary_verified",
1245
+ "scope": "signed authentication requests enabled; configured asymmetric algorithms",
1246
+ "finding": "Integer and numeric-string requested_expiry are accepted through the ordinary expiry validator.",
1247
+ "code_refs": [
1248
+ "lib/rodauth/features/ciba.rb",
1249
+ "docs/signed-requests.md"
1250
+ ],
1251
+ "test_refs": [
1252
+ {
1253
+ "file": "test/ciba_signed_request_test.rb",
1254
+ "method": "test_signed_request_claims_resources_and_rar_use_only_inner_values"
1255
+ }
1256
+ ],
1257
+ "execution": "docs/validation/signed-request-audit-current.txt"
1258
+ },
1259
+ {
1260
+ "id": "CIBA-058",
1261
+ "label": "署名要求の内外混在禁止",
1262
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.7.1.1",
1263
+ "status": "client_only",
1264
+ "scope": "signed authentication requests enabled; configured asymmetric algorithms",
1265
+ "finding": "Client must place authentication request parameters inside the JWT. OP ignores nonconforming outer protocol values rather than merging them; separate client authentication remains outside. Do not classify tolerated client input as evidence of client compliance.",
1266
+ "code_refs": [
1267
+ "lib/rodauth/features/ciba.rb",
1268
+ "docs/signed-requests.md"
1269
+ ],
1270
+ "test_refs": [
1271
+ {
1272
+ "file": "test/ciba_signed_request_test.rb",
1273
+ "method": "test_signed_request_isolated_parameters_new_approval_and_repeated_submission"
1274
+ }
1275
+ ],
1276
+ "execution": "docs/validation/signed-request-audit-current.txt"
1277
+ },
1278
+ {
1279
+ "id": "CIBA-059",
1280
+ "label": "暗号化要求非対応",
1281
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.7.1.1",
1282
+ "status": "protocol_boundary_verified",
1283
+ "scope": "signed authentication requests enabled; configured asymmetric algorithms",
1284
+ "finding": "Five-part encrypted request shape is rejected; only three-part signed JWT requests enter verification.",
1285
+ "code_refs": [
1286
+ "lib/rodauth/features/ciba.rb",
1287
+ "docs/signed-requests.md"
1288
+ ],
1289
+ "test_refs": [
1290
+ {
1291
+ "file": "test/ciba_signed_request_test.rb",
1292
+ "method": "test_signed_request_configured_asymmetric_algorithms_and_encrypted_shape"
1293
+ }
1294
+ ],
1295
+ "execution": "docs/validation/signed-request-audit-current.txt"
1296
+ },
1297
+ {
1298
+ "id": "CIBA-060",
1299
+ "label": "user_codeはOPパスワードと別",
1300
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.7.1.2",
1301
+ "status": "app_contract",
1302
+ "scope": "user-code feature enabled unless otherwise stated",
1303
+ "finding": "Documentation now explicitly requires a separate code from the OP login password. No application password/code policy is implemented or audited.",
1304
+ "code_refs": [
1305
+ "lib/rodauth/features/ciba.rb",
1306
+ "docs/user-code.md"
1307
+ ],
1308
+ "test_refs": [],
1309
+ "execution": null
1310
+ },
1311
+ {
1312
+ "id": "CIBA-061",
1313
+ "label": "user_codeの例外ポリシー",
1314
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.7.1.2",
1315
+ "status": "protocol_boundary_verified",
1316
+ "scope": "user-code feature enabled unless otherwise stated",
1317
+ "finding": "Callback can explicitly allow omission for a client/user. Tests cover false/omitted client metadata; arbitrary per-user policy correctness is not established.",
1318
+ "code_refs": [
1319
+ "lib/rodauth/features/ciba.rb",
1320
+ "docs/user-code.md"
1321
+ ],
1322
+ "test_refs": [
1323
+ {
1324
+ "file": "test/ciba_user_code_test.rb",
1325
+ "method": "test_user_code_input_and_optional_client_policy"
1326
+ }
1327
+ ],
1328
+ "execution": "docs/validation/user-code-audit-current.txt"
1329
+ },
1330
+ {
1331
+ "id": "CIBA-062",
1332
+ "label": "user_codeの都度入力",
1333
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.7.1.2",
1334
+ "status": "client_only",
1335
+ "scope": "user-code feature enabled unless otherwise stated",
1336
+ "finding": "Client-side collection/non-storage is outside this OP gem. Gem-side removal from snapshots is separately tested and does not prove this client requirement.",
1337
+ "code_refs": [
1338
+ "lib/rodauth/features/ciba.rb",
1339
+ "docs/user-code.md"
1340
+ ],
1341
+ "test_refs": [
1342
+ {
1343
+ "file": "test/ciba_user_code_test.rb",
1344
+ "method": "test_user_code_not_persisted_and_does_not_replace_customer_approval"
1345
+ }
1346
+ ],
1347
+ "execution": "docs/validation/user-code-audit-current.txt"
1348
+ },
1349
+ {
1350
+ "id": "CIBA-063",
1351
+ "label": "user_code変更手段",
1352
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.7.1.2",
1353
+ "status": "app_contract",
1354
+ "scope": "user-code feature enabled unless otherwise stated",
1355
+ "finding": "Application-owned code enrollment/change lifecycle is documented. No production change UI is supplied or tested.",
1356
+ "code_refs": [
1357
+ "lib/rodauth/features/ciba.rb",
1358
+ "docs/user-code.md"
1359
+ ],
1360
+ "test_refs": [],
1361
+ "execution": null
1362
+ },
1363
+ {
1364
+ "id": "CIBA-064",
1365
+ "label": "登録方式による認証検証",
1366
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.7.2",
1367
+ "status": "protocol_boundary_verified",
1368
+ "scope": "Configured Basic/post, private_key_jwt/client_secret_jwt (fourteen algorithms), PKI/self-signed TLS; deployment trust and arbitrary extension combinations excluded",
1369
+ "finding": "Configured methods have direct endpoint authentication/negative evidence. Fourteen RS/PS/ES/HS/Edwards algorithms have reference HTTP and gem verification evidence; Edwards adds DCR, remote HTTP rotation/failure, installed HTTPS retrieval with untrusted-TLS rejection, replay protection and ordinary-flow coexistence. A CIBA Edwards-only configuration preserves unrelated RSA client authentication and upstream metadata. See client-auth-edwards-scope-matrix.txt and client-auth-edwards-https-installed.txt. This is bounded protocol evidence, not deployment certification.",
1370
+ "code_refs": [
1371
+ "lib/rodauth/features/ciba.rb",
1372
+ "docs/api.md",
1373
+ "docs/research/client-assertion-algorithm-contract.md"
1374
+ ],
1375
+ "test_refs": [
1376
+ {
1377
+ "file": "test/ciba_protocol_test.rb",
1378
+ "method": "test_post_client_authentication"
1379
+ },
1380
+ {
1381
+ "file": "test/ciba_security_test.rb",
1382
+ "method": "test_jwt_client_assertion_requires_issuer_expiry_and_jti"
1383
+ },
1384
+ {
1385
+ "file": "test/ciba_auth_algorithm_matrix_test.rb",
1386
+ "method": "test_configured_client_assertion_algorithms_at_both_ciba_endpoints"
1387
+ },
1388
+ {
1389
+ "file": "test/ciba_registration_test.rb",
1390
+ "method": "test_ciba_registration_rejects_assertion_type_as_authentication_method"
1391
+ },
1392
+ {
1393
+ "file": "test/ciba_edwards_auth_test.rb",
1394
+ "method": "test_edwards_client_authentication_at_both_endpoints"
1395
+ },
1396
+ {
1397
+ "file": "test/ciba_edwards_auth_remote_test.rb",
1398
+ "method": "test_edwards_client_authentication_remote_rotation_failure_and_ordinary_grant"
1399
+ },
1400
+ {
1401
+ "file": "test/ciba_edwards_auth_test.rb",
1402
+ "method": "test_edwards_authentication_configuration_preserves_unrelated_rsa_clients"
1403
+ }
1404
+ ],
1405
+ "execution": "docs/validation/client-auth-edwards-scope-matrix.txt"
1406
+ },
1407
+ {
1408
+ "id": "CIBA-065",
1409
+ "label": "公開鍵認証の推奨",
1410
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.7.2",
1411
+ "status": "app_contract",
1412
+ "scope": "CIBA protocol transport and registered authentication; deployment and arbitrary method combinations remain separate",
1413
+ "finding": "Prefer public-key client authentication when provisioning clients. The gem supports asymmetric methods but intentionally does not prohibit shared-secret authentication across the OP; deployment selection is not proven by feature support.",
1414
+ "code_refs": [
1415
+ "lib/rodauth/features/ciba.rb",
1416
+ "docs/api.md"
1417
+ ],
1418
+ "test_refs": [],
1419
+ "execution": null
1420
+ },
1421
+ {
1422
+ "id": "CIBA-066",
1423
+ "label": "署名要求検証",
1424
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.7.2",
1425
+ "status": "protocol_boundary_verified",
1426
+ "scope": "signed authentication requests enabled; configured asymmetric algorithms",
1427
+ "finding": "Configured eleven asymmetric algorithms have valid/wrong-key evidence (RS/PS/ES plus Ed25519/EdDSA). Required claims, NumericDate, jti type, issuer/audience, key selection/use/alg/key_ops, duplicate JSON, nested requests and encrypted shape have direct rejection tests. Edwards includes independent Node/jose vectors and remote keys. Current three-DB regressions pass; custom JOSE profiles and production key custody are not claimed.",
1428
+ "code_refs": [
1429
+ "lib/rodauth/features/ciba.rb",
1430
+ "docs/signed-requests.md"
1431
+ ],
1432
+ "test_refs": [
1433
+ {
1434
+ "file": "test/ciba_signed_request_test.rb",
1435
+ "method": "test_signed_request_rejects_bad_claims_and_keys_before_persistence"
1436
+ },
1437
+ {
1438
+ "file": "test/ciba_signed_request_test.rb",
1439
+ "method": "test_signed_request_configured_asymmetric_algorithms_and_encrypted_shape"
1440
+ },
1441
+ {
1442
+ "file": "test/ciba_signed_request_test.rb",
1443
+ "method": "test_signed_request_key_selection_duplicate_json_and_migration_preservation"
1444
+ },
1445
+ {
1446
+ "file": "test/ciba_edwards_request_test.rb",
1447
+ "method": "test_edwards_signed_requests_and_key_rejection"
1448
+ },
1449
+ {
1450
+ "file": "test/ciba_edwards_request_test.rb",
1451
+ "method": "test_node_generated_edwards_vectors_with_remote_keys"
1452
+ }
1453
+ ],
1454
+ "execution": "docs/validation/pairwise-signature-audit-current.txt"
1455
+ },
1456
+ {
1457
+ "id": "CIBA-067",
1458
+ "label": "認証要求パラメータ検証",
1459
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.7.2",
1460
+ "status": "protocol_boundary_verified",
1461
+ "scope": "Supported authentication parameter parser and callback boundaries, enumerated in docs/research/request-parameter-inventory.md; policy equivalence and deployment callback correctness are separate.",
1462
+ "finding": "The supported parameter inventory is reconciled against the request route, common parser, feature validators and current full-suite tests. It covers transport/duplicates, scope, all enabled hints, binding/expiry/ACR, signed requests, user codes, ping notification tokens, nonce, claims/resources/RAR, max_age, request_context and ignored inputs. Application semantics and the explicit user-code/hint/cache policy differences remain separately tracked; this row does not assert those policies are identical or accepted.",
1463
+ "code_refs": [
1464
+ "lib/rodauth/features/ciba.rb",
1465
+ "docs/api.md",
1466
+ "docs/research/request-parameter-inventory.md"
1467
+ ],
1468
+ "test_refs": [
1469
+ {
1470
+ "file": "test/ciba_protocol_test.rb",
1471
+ "method": "test_request_validation_and_unknown_parameters"
1472
+ },
1473
+ {
1474
+ "file": "test/ciba_protocol_test.rb",
1475
+ "method": "test_expiry_binding_context_and_offline_access"
1476
+ },
1477
+ {
1478
+ "file": "test/ciba_protocol_test.rb",
1479
+ "method": "test_login_hint_is_application_defined_and_unknown_fields_cannot_set_state"
1480
+ },
1481
+ {
1482
+ "file": "test/ciba_ping_test.rb",
1483
+ "method": "test_signed_ping_required_fields_cannot_be_supplied_outside_signature"
1484
+ },
1485
+ {
1486
+ "file": "test/ciba_max_age_test.rb",
1487
+ "method": "test_max_age_invalid_values_do_not_dispatch_or_persist"
1488
+ }
1489
+ ],
1490
+ "execution": "docs/validation/completion-errors-full-ruby33.txt",
1491
+ "additional_execution": "docs/validation/signed-ping-required-fields.txt"
1492
+ },
1493
+ {
1494
+ "id": "CIBA-068",
1495
+ "label": "複数hintのエラー",
1496
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.7.2",
1497
+ "status": "protocol_boundary_verified",
1498
+ "scope": "baseline request parameters and enabled hint-token boundary; UI and deployment policy remain external",
1499
+ "finding": "Multiple hint names return invalid_request before resolving or saving the request, including opt-in login_hint_token combinations.",
1500
+ "code_refs": [
1501
+ "lib/rodauth/features/ciba.rb",
1502
+ "docs/api.md"
1503
+ ],
1504
+ "test_refs": [
1505
+ {
1506
+ "file": "test/ciba_hint_token_test.rb",
1507
+ "method": "test_hint_token_input_exclusivity_size_and_unknown_user"
1508
+ }
1509
+ ],
1510
+ "execution": "docs/validation/request-parameters-audit-current.txt"
1511
+ },
1512
+ {
1513
+ "id": "CIBA-069",
1514
+ "label": "hintとユーザーの検証",
1515
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.7.2",
1516
+ "status": "protocol_boundary_verified",
1517
+ "scope": "baseline request parameters and enabled hint-token boundary; UI and deployment policy remain external",
1518
+ "finding": "Resolved accounts must remain eligible; a disabled account is rejected and a different completion account cannot approve the request. Arbitrary resolver correctness is application-owned.",
1519
+ "code_refs": [
1520
+ "lib/rodauth/features/ciba.rb",
1521
+ "docs/api.md"
1522
+ ],
1523
+ "test_refs": [
1524
+ {
1525
+ "file": "test/ciba_hint_token_test.rb",
1526
+ "method": "test_hint_token_resolved_user_still_requires_eligible_account_and_matching_approval"
1527
+ },
1528
+ {
1529
+ "file": "test/ciba_protocol_test.rb",
1530
+ "method": "test_login_hint_is_application_defined_and_unknown_fields_cannot_set_state"
1531
+ }
1532
+ ],
1533
+ "execution": "docs/validation/request-parameters-audit-current.txt"
1534
+ },
1535
+ {
1536
+ "id": "CIBA-070",
1537
+ "label": "hintポリシーの伝達",
1538
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.7.2",
1539
+ "status": "app_contract",
1540
+ "scope": "baseline request parameters and enabled hint-token boundary; UI and deployment policy remain external",
1541
+ "finding": "Accepted hint formats, issuer trust and age policy must be communicated by each deployment. Documentation describes the integration responsibility; no production client agreement is tested.",
1542
+ "code_refs": [
1543
+ "lib/rodauth/features/ciba.rb",
1544
+ "docs/api.md"
1545
+ ],
1546
+ "test_refs": [],
1547
+ "execution": null
1548
+ },
1549
+ {
1550
+ "id": "CIBA-071",
1551
+ "label": "不正または不明hintのエラー",
1552
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.7.2",
1553
+ "status": "protocol_boundary_verified",
1554
+ "scope": "baseline request parameters and enabled hint-token boundary; UI and deployment policy remain external",
1555
+ "finding": "Malformed hints return invalid_request; well-shaped unresolved hints return unknown_user_id before persistence.",
1556
+ "code_refs": [
1557
+ "lib/rodauth/features/ciba.rb",
1558
+ "docs/api.md"
1559
+ ],
1560
+ "test_refs": [
1561
+ {
1562
+ "file": "test/ciba_hint_token_test.rb",
1563
+ "method": "test_hint_token_input_exclusivity_size_and_unknown_user"
1564
+ },
1565
+ {
1566
+ "file": "test/ciba_protocol_test.rb",
1567
+ "method": "test_request_validation_and_unknown_parameters"
1568
+ }
1569
+ ],
1570
+ "execution": "docs/validation/request-parameters-audit-current.txt"
1571
+ },
1572
+ {
1573
+ "id": "CIBA-072",
1574
+ "label": "必須パラメータ検証",
1575
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.7.2",
1576
+ "status": "protocol_boundary_verified",
1577
+ "scope": "Mandatory presence and exclusive hint selection for enabled poll/ping, signed requests and application-required user code; optional-value validation remains CIBA-067.",
1578
+ "finding": "The supported mandatory parameter inventory is reconciled in docs/research/required-parameter-inventory.md. Direct tests cover scope, exclusive hints, registered request JWT, its six required claims, ping notification token and application-required user code. Actual signed omissions and missing/empty combined fields cannot be supplied by valid unsigned outer values; rejection occurs without persistence or device dispatch. Client authentication remains independently required. This verifies required presence/selection, not every optional value or application policy.",
1579
+ "code_refs": [
1580
+ "lib/rodauth/features/ciba.rb",
1581
+ "docs/api.md",
1582
+ "docs/research/required-parameter-inventory.md"
1583
+ ],
1584
+ "test_refs": [
1585
+ {
1586
+ "file": "test/ciba_protocol_test.rb",
1587
+ "method": "test_request_validation_and_unknown_parameters"
1588
+ },
1589
+ {
1590
+ "file": "test/ciba_hint_token_test.rb",
1591
+ "method": "test_hint_token_input_exclusivity_size_and_unknown_user"
1592
+ },
1593
+ {
1594
+ "file": "test/ciba_ping_test.rb",
1595
+ "method": "test_signed_ping_required_fields_cannot_be_supplied_outside_signature"
1596
+ },
1597
+ {
1598
+ "file": "test/ciba_signed_request_test.rb",
1599
+ "method": "test_signed_request_missing_required_fields_cannot_use_outer_values"
1600
+ },
1601
+ {
1602
+ "file": "test/ciba_requirements_test.rb",
1603
+ "method": "test_scope_syntax_errors_are_invalid_scope"
1604
+ },
1605
+ {
1606
+ "file": "test/ciba_signed_request_test.rb",
1607
+ "method": "test_signed_request_registration_discovery_and_client_authentication"
1608
+ },
1609
+ {
1610
+ "file": "test/ciba_signed_request_test.rb",
1611
+ "method": "test_signed_request_rejects_bad_claims_and_keys_before_persistence"
1612
+ },
1613
+ {
1614
+ "file": "test/ciba_ping_test.rb",
1615
+ "method": "test_ping_rejects_bad_tokens_and_uses_current_registered_destination"
1616
+ },
1617
+ {
1618
+ "file": "test/ciba_user_code_test.rb",
1619
+ "method": "test_user_code_requires_explicit_callback_and_checks_before_device_dispatch"
1620
+ }
1621
+ ],
1622
+ "execution": "docs/validation/alignment-consolidated-ruby33.txt",
1623
+ "additional_execution": "docs/validation/signed-ping-required-fields.txt",
1624
+ "omission_execution": "docs/validation/signed-required-omissions.txt"
1625
+ },
1626
+ {
1627
+ "id": "CIBA-073",
1628
+ "label": "未知パラメータの無視",
1629
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.7.2",
1630
+ "status": "protocol_boundary_verified",
1631
+ "scope": "baseline request parameters and enabled hint-token boundary; UI and deployment policy remain external",
1632
+ "finding": "Unknown parameters are ignored, including names resembling internal account, status and expiry fields. They neither override persisted state nor appear in the application snapshot.",
1633
+ "code_refs": [
1634
+ "lib/rodauth/features/ciba.rb",
1635
+ "docs/api.md"
1636
+ ],
1637
+ "test_refs": [
1638
+ {
1639
+ "file": "test/ciba_protocol_test.rb",
1640
+ "method": "test_login_hint_is_application_defined_and_unknown_fields_cannot_set_state"
1641
+ }
1642
+ ],
1643
+ "execution": "docs/validation/request-parameters-audit-current.txt"
1644
+ },
1645
+ {
1646
+ "id": "CIBA-074",
1647
+ "label": "開始エラーの形式",
1648
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.7.2",
1649
+ "status": "protocol_boundary_verified",
1650
+ "scope": "baseline request parameters and enabled hint-token boundary; UI and deployment policy remain external",
1651
+ "finding": "Validation failures produce JSON protocol errors with the expected HTTP status and no token/request identifiers. Internal exceptions return server_error without private text.",
1652
+ "code_refs": [
1653
+ "lib/rodauth/features/ciba.rb",
1654
+ "docs/api.md"
1655
+ ],
1656
+ "test_refs": [
1657
+ {
1658
+ "file": "test/ciba_requirements_test.rb",
1659
+ "method": "test_authentication_error_envelopes_do_not_expose_tokens_or_internal_errors"
1660
+ }
1661
+ ],
1662
+ "execution": "docs/validation/request-parameters-audit-current.txt"
1663
+ },
1664
+ {
1665
+ "id": "CIBA-075",
1666
+ "label": "受付成功HTTP 200",
1667
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.7.3",
1668
+ "status": "protocol_boundary_verified",
1669
+ "scope": "acknowledgement generation and baseline poll; client obligations separately classified",
1670
+ "finding": "Validated baseline requests return HTTP 200; invalid hints, scopes and unsupported parameters do not receive successful acknowledgement.",
1671
+ "code_refs": [
1672
+ "lib/rodauth/features/ciba.rb",
1673
+ "lib/rodauth/ciba/schema.rb"
1674
+ ],
1675
+ "test_refs": [
1676
+ {
1677
+ "file": "test/ciba_protocol_test.rb",
1678
+ "method": "test_request_validation_and_unknown_parameters"
1679
+ }
1680
+ ],
1681
+ "execution": "docs/validation/acknowledgement-audit-current.txt"
1682
+ },
1683
+ {
1684
+ "id": "CIBA-076",
1685
+ "label": "auth_req_id必須と一意性",
1686
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.7.3",
1687
+ "status": "protocol_boundary_verified",
1688
+ "scope": "acknowledgement generation and baseline poll; client obligations separately classified",
1689
+ "finding": "Each accepted request receives a fresh base64url identifier. Its SHA256 digest has a database unique constraint; two observed identifiers differ. Forced RNG collision recovery is not tested.",
1690
+ "code_refs": [
1691
+ "lib/rodauth/features/ciba.rb",
1692
+ "lib/rodauth/ciba/schema.rb"
1693
+ ],
1694
+ "test_refs": [
1695
+ {
1696
+ "file": "test/ciba_requirements_test.rb",
1697
+ "method": "test_auth_req_id_has_required_entropy_and_restricted_characters"
1698
+ }
1699
+ ],
1700
+ "execution": "docs/validation/acknowledgement-audit-current.txt"
1701
+ },
1702
+ {
1703
+ "id": "CIBA-077",
1704
+ "label": "auth_req_id entropy",
1705
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.7.3",
1706
+ "status": "protocol_boundary_verified",
1707
+ "scope": "acknowledgement generation and baseline poll; client obligations separately classified",
1708
+ "finding": "Source review confirms SecureRandom.urlsafe_base64(32), supplying 256 random input bits. Tests check encoding and distinct samples, not statistical entropy or the platform RNG implementation.",
1709
+ "code_refs": [
1710
+ "lib/rodauth/features/ciba.rb",
1711
+ "lib/rodauth/ciba/schema.rb"
1712
+ ],
1713
+ "test_refs": [
1714
+ {
1715
+ "file": "test/ciba_requirements_test.rb",
1716
+ "method": "test_auth_req_id_has_required_entropy_and_restricted_characters"
1717
+ }
1718
+ ],
1719
+ "execution": "docs/validation/acknowledgement-audit-current.txt"
1720
+ },
1721
+ {
1722
+ "id": "CIBA-078",
1723
+ "label": "auth_req_id文字集合",
1724
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.7.3",
1725
+ "status": "protocol_boundary_verified",
1726
+ "scope": "acknowledgement generation and baseline poll; client obligations separately classified",
1727
+ "finding": "The 43-character unpadded base64url output uses only the permitted character set; direct response assertions cover the encoding.",
1728
+ "code_refs": [
1729
+ "lib/rodauth/features/ciba.rb",
1730
+ "lib/rodauth/ciba/schema.rb"
1731
+ ],
1732
+ "test_refs": [
1733
+ {
1734
+ "file": "test/ciba_requirements_test.rb",
1735
+ "method": "test_auth_req_id_has_required_entropy_and_restricted_characters"
1736
+ }
1737
+ ],
1738
+ "execution": "docs/validation/acknowledgement-audit-current.txt"
1739
+ },
1740
+ {
1741
+ "id": "CIBA-079",
1742
+ "label": "auth_req_idのopaque扱い",
1743
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.7.3",
1744
+ "status": "client_only",
1745
+ "scope": "acknowledgement generation and baseline poll; client obligations separately classified",
1746
+ "finding": "Opaque handling is a Client obligation. The OP generation test cannot prove how external clients interpret or store identifiers.",
1747
+ "code_refs": [],
1748
+ "test_refs": [],
1749
+ "execution": null
1750
+ },
1751
+ {
1752
+ "id": "CIBA-080",
1753
+ "label": "expires_in",
1754
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.7.3",
1755
+ "status": "partial",
1756
+ "scope": "acknowledgement generation and baseline poll; client obligations separately classified",
1757
+ "finding": "Positive integer lifetime, configured maximum and exact expiry are tested. The gem records its timestamp after client/hint validation; elapsed time before that timestamp is not accounted for as request-receipt time. Therefore the catalog requirement is only partially established. Deterministic callback-delay tests now establish identical timing in node 9.12.2 and the gem, including acknowledgement after expiry when dispatch exceeds lifetime; this is a shared limitation, not an unmeasured parity gap.",
1758
+ "code_refs": [
1759
+ "lib/rodauth/features/ciba.rb",
1760
+ "lib/rodauth/ciba/schema.rb",
1761
+ "docs/research/acknowledgement-time-contract.md"
1762
+ ],
1763
+ "test_refs": [
1764
+ {
1765
+ "file": "test/ciba_requirements_test.rb",
1766
+ "method": "test_requested_expiry_expires_at_the_exact_boundary"
1767
+ },
1768
+ {
1769
+ "file": "test/ciba_alignment_test.rb",
1770
+ "method": "test_default_request_lifetime_matches_node_policy"
1771
+ },
1772
+ {
1773
+ "file": "test/ciba_requirements_test.rb",
1774
+ "method": "test_acknowledgement_numeric_fields_and_configuration_limits"
1775
+ },
1776
+ {
1777
+ "file": "test/ciba_requirements_test.rb",
1778
+ "method": "test_acknowledgement_time_origin_matches_reference_application_delays"
1779
+ }
1780
+ ],
1781
+ "execution": "docs/validation/acknowledgement-audit-current.txt"
1782
+ },
1783
+ {
1784
+ "id": "CIBA-081",
1785
+ "label": "interval",
1786
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.7.3",
1787
+ "status": "protocol_boundary_verified",
1788
+ "scope": "acknowledgement generation and baseline poll; client obligations separately classified",
1789
+ "finding": "Returned interval is an integer: 1, 5 and the configured 32-bit maximum are accepted. Zero, negative, fractional, string and overflow configuration values are rejected. The reference OP omits this optional field; the gem explicitly advertises its polling policy.",
1790
+ "code_refs": [
1791
+ "lib/rodauth/features/ciba.rb",
1792
+ "lib/rodauth/ciba/schema.rb"
1793
+ ],
1794
+ "test_refs": [
1795
+ {
1796
+ "file": "test/ciba_requirements_test.rb",
1797
+ "method": "test_acknowledgement_numeric_fields_and_configuration_limits"
1798
+ }
1799
+ ],
1800
+ "execution": "docs/validation/acknowledgement-audit-current.txt"
1801
+ },
1802
+ {
1803
+ "id": "CIBA-082",
1804
+ "label": "interval既定値",
1805
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.7.3",
1806
+ "status": "client_only",
1807
+ "scope": "acknowledgement generation and baseline poll; client obligations separately classified",
1808
+ "finding": "The five-second fallback when interval is omitted is a Client obligation; the gem normally returns an explicit interval.",
1809
+ "code_refs": [],
1810
+ "test_refs": [],
1811
+ "execution": null
1812
+ },
1813
+ {
1814
+ "id": "CIBA-083",
1815
+ "label": "未知応答パラメータ",
1816
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.7.3",
1817
+ "status": "client_only",
1818
+ "scope": "acknowledgement generation and baseline poll; client obligations separately classified",
1819
+ "finding": "Ignoring unknown acknowledgement fields is a Client obligation, not evidence about OP request-parameter parsing.",
1820
+ "code_refs": [],
1821
+ "test_refs": [],
1822
+ "execution": null
1823
+ },
1824
+ {
1825
+ "id": "CIBA-084",
1826
+ "label": "受付応答の必須項目確認",
1827
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.7.4",
1828
+ "status": "client_only",
1829
+ "scope": "acknowledgement generation and baseline poll; client obligations separately classified",
1830
+ "finding": "Client validation of required HTTP200 acknowledgement fields is outside this OP gem; valid gem responses do not prove client validation.",
1831
+ "code_refs": [],
1832
+ "test_refs": [],
1833
+ "execution": null
1834
+ },
1835
+ {
1836
+ "id": "CIBA-085",
1837
+ "label": "auth_req_id保持",
1838
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.7.4",
1839
+ "status": "client_only",
1840
+ "scope": "application/client boundaries and optional polling policies; no production deployment certification",
1841
+ "finding": "External clients must retain auth_req_id. OP storage is not evidence of client persistence.",
1842
+ "code_refs": [
1843
+ "lib/rodauth/features/ciba.rb",
1844
+ "docs/api.md"
1845
+ ],
1846
+ "test_refs": [],
1847
+ "execution": null
1848
+ },
1849
+ {
1850
+ "id": "CIBA-086",
1851
+ "label": "クライアント期限管理",
1852
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.7.4",
1853
+ "status": "client_only",
1854
+ "scope": "application/client boundaries and optional polling policies; no production deployment certification",
1855
+ "finding": "Callback cleanup and expiry tracking belong to the client; no production client cleanup is tested.",
1856
+ "code_refs": [
1857
+ "lib/rodauth/features/ciba.rb",
1858
+ "docs/api.md"
1859
+ ],
1860
+ "test_refs": [],
1861
+ "execution": null
1862
+ },
1863
+ {
1864
+ "id": "CIBA-087",
1865
+ "label": "認証チャネルとacrの選択",
1866
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.8",
1867
+ "status": "app_contract",
1868
+ "scope": "application/client boundaries and optional polling policies; no production deployment certification",
1869
+ "finding": "The dispatch snapshot exposes requested ACR preferences and the resolved account. Channel selection and actual authentication assurance remain application-owned.",
1870
+ "code_refs": [
1871
+ "lib/rodauth/features/ciba.rb",
1872
+ "docs/api.md"
1873
+ ],
1874
+ "test_refs": [
1875
+ {
1876
+ "file": "test/ciba_protocol_test.rb",
1877
+ "method": "test_login_hint_is_application_defined_and_unknown_fields_cannot_set_state"
1878
+ }
1879
+ ],
1880
+ "execution": "docs/validation/application-boundaries-audit-current.txt"
1881
+ },
1882
+ {
1883
+ "id": "CIBA-088",
1884
+ "label": "認証後の承認取得",
1885
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.8",
1886
+ "status": "app_contract",
1887
+ "scope": "application/client boundaries and optional polling policies; no production deployment certification",
1888
+ "finding": "The gem prevents issuance before explicit approval and checks the completion account. Authenticating the human and obtaining informed consent are application responsibilities, not established by an internal API call.",
1889
+ "code_refs": [
1890
+ "lib/rodauth/features/ciba.rb",
1891
+ "docs/api.md"
1892
+ ],
1893
+ "test_refs": [
1894
+ {
1895
+ "file": "test/ciba_integration_test.rb",
1896
+ "method": "test_unapproved_poll_responses_never_include_tokens"
1897
+ }
1898
+ ],
1899
+ "execution": "docs/validation/application-boundaries-audit-current.txt"
1900
+ },
1901
+ {
1902
+ "id": "CIBA-089",
1903
+ "label": "登録モード以外へ配送しない",
1904
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.10",
1905
+ "status": "protocol_boundary_verified",
1906
+ "scope": "Registered poll/ping mode and current endpoint at dispatch; no cancellation or distributed cache coherence guarantee",
1907
+ "finding": "Aligned with measured provider9.12.2 HTTP management overlap: retry uses current registered endpoint with saved notification credential, switching to poll rejects retry, and in-flight sends retain their selected destination. Gem barrier tests use real management PUT and passed on SQLite/PostgreSQL/MySQL; token collection succeeds once. HTTPS metadata and existing outbound transport validation remain active.",
1908
+ "code_refs": [
1909
+ "lib/rodauth/features/ciba.rb",
1910
+ "docs/api.md"
1911
+ ],
1912
+ "test_refs": [
1913
+ {
1914
+ "file": "test/ciba_ping_test.rb",
1915
+ "method": "test_ping_approval_denial_and_private_delivery_storage"
1916
+ },
1917
+ {
1918
+ "file": "test/ciba_ping_test.rb",
1919
+ "method": "test_ping_metadata_acceptance_rollback_expiry_and_private_data_cleanup"
1920
+ },
1921
+ {
1922
+ "file": "test/ciba_ping_test.rb",
1923
+ "method": "test_ping_management_change_during_send_preserves_destination_and_saved_result"
1924
+ }
1925
+ ],
1926
+ "execution": "docs/validation/ping-current-endpoint-matrix.txt"
1927
+ },
1928
+ {
1929
+ "id": "CIBA-090",
1930
+ "label": "Token Endpoint認証",
1931
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.10.1",
1932
+ "status": "protocol_boundary_verified",
1933
+ "scope": "CIBA protocol transport and registered authentication; deployment and arbitrary method combinations remain separate",
1934
+ "finding": "Token collection without client authentication is rejected without issuing a grant; registered assertion and post authentication succeed. CIBA authentication rejects replayed assertions and inappropriate explicit client identity.",
1935
+ "code_refs": [
1936
+ "lib/rodauth/features/ciba.rb",
1937
+ "docs/api.md"
1938
+ ],
1939
+ "test_refs": [
1940
+ {
1941
+ "file": "test/ciba_integration_test.rb",
1942
+ "method": "test_client_authentication_is_required_at_both_endpoints"
1943
+ }
1944
+ ],
1945
+ "execution": "docs/validation/auth-transport-audit-current.txt"
1946
+ },
1947
+ {
1948
+ "id": "CIBA-091",
1949
+ "label": "クライアントpoll間隔",
1950
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.10.1",
1951
+ "status": "client_only",
1952
+ "scope": "application/client boundaries and optional polling policies; no production deployment certification",
1953
+ "finding": "The client must obey the minimum polling interval. Server slow_down enforcement does not prove client compliance.",
1954
+ "code_refs": [
1955
+ "lib/rodauth/features/ciba.rb",
1956
+ "docs/api.md"
1957
+ ],
1958
+ "test_refs": [],
1959
+ "execution": null
1960
+ },
1961
+ {
1962
+ "id": "CIBA-092",
1963
+ "label": "long polling",
1964
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.10.1",
1965
+ "status": "reference_unsupported",
1966
+ "scope": "application/client boundaries and optional polling policies; no production deployment certification",
1967
+ "finding": "Neither the selected node grant handler nor the gem implements a wait-for-result long-poll loop; pending requests return an error. The optional long-poll capability is not claimed.",
1968
+ "code_refs": [
1969
+ "lib/rodauth/features/ciba.rb",
1970
+ "docs/api.md"
1971
+ ],
1972
+ "test_refs": [],
1973
+ "execution": null
1974
+ },
1975
+ {
1976
+ "id": "CIBA-093",
1977
+ "label": "OP応答時間",
1978
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.10.1",
1979
+ "status": "app_contract",
1980
+ "scope": "application/client boundaries and optional polling policies; no production deployment certification",
1981
+ "finding": "Unverified deployment obligation, not a passed timing guarantee. The gem has no hard30-second poll deadline across queues, DB waits and arbitrary hooks. The original catalog already assigns gem+deployment responsibility. docs/operations.md specifies end-to-end timeout budgeting, contention measurement and ambiguous post-commit timeout handling; an integrating service must supply production evidence.",
1982
+ "code_refs": [
1983
+ "lib/rodauth/features/ciba.rb",
1984
+ "docs/api.md",
1985
+ "docs/operations.md"
1986
+ ],
1987
+ "test_refs": [],
1988
+ "execution": null
1989
+ },
1990
+ {
1991
+ "id": "CIBA-094",
1992
+ "label": "重複poll禁止",
1993
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.10.1",
1994
+ "status": "client_only",
1995
+ "scope": "application/client boundaries and optional polling policies; no production deployment certification",
1996
+ "finding": "Clients must not overlap requests for one auth_req_id. Defensive concurrent redemption tests do not prove external client behavior.",
1997
+ "code_refs": [
1998
+ "lib/rodauth/features/ciba.rb",
1999
+ "docs/api.md"
2000
+ ],
2001
+ "test_refs": [],
2002
+ "execution": null
2003
+ },
2004
+ {
2005
+ "id": "CIBA-095",
2006
+ "label": "503とRetry-After",
2007
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.10.1",
2008
+ "status": "protocol_boundary_verified",
2009
+ "scope": "application/client boundaries and optional polling policies; no production deployment certification",
2010
+ "finding": "Injected DB lock timeout at acceptance and issuance yields 503 temporarily_unavailable with Retry-After and rolls back pending/grant mutation. This does not establish all production overload behavior.",
2011
+ "code_refs": [
2012
+ "lib/rodauth/features/ciba.rb",
2013
+ "docs/api.md"
2014
+ ],
2015
+ "test_refs": [
2016
+ {
2017
+ "file": "test/ciba_security_test.rb",
2018
+ "method": "test_lock_timeout_returns_503_with_retry_after_and_rolls_back"
2019
+ }
2020
+ ],
2021
+ "execution": "docs/validation/application-boundaries-audit-current.txt"
2022
+ },
2023
+ {
2024
+ "id": "CIBA-096",
2025
+ "label": "Retry-After遵守",
2026
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.10.1",
2027
+ "status": "client_only",
2028
+ "scope": "application/client boundaries and optional polling policies; no production deployment certification",
2029
+ "finding": "Respecting Retry-After is a client duty. Emitting the header does not establish client retries.",
2030
+ "code_refs": [
2031
+ "lib/rodauth/features/ciba.rb",
2032
+ "docs/api.md"
2033
+ ],
2034
+ "test_refs": [],
2035
+ "execution": null
2036
+ },
2037
+ {
2038
+ "id": "CIBA-097",
2039
+ "label": "pingクライアントのpoll許容",
2040
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.10.1",
2041
+ "status": "protocol_boundary_verified",
2042
+ "scope": "ping enabled; statements shared with push are assessed for ping only",
2043
+ "finding": "Ping requests can be polled while pending and after approval; no successful notification receipt is needed to collect a saved result.",
2044
+ "code_refs": [
2045
+ "lib/rodauth/features/ciba.rb",
2046
+ "lib/rodauth/ciba/http.rb",
2047
+ "docs/ping.md"
2048
+ ],
2049
+ "test_refs": [
2050
+ {
2051
+ "file": "test/ciba_ping_test.rb",
2052
+ "method": "test_ping_approval_denial_and_private_delivery_storage"
2053
+ }
2054
+ ],
2055
+ "execution": "docs/validation/ping-audit-current.txt"
2056
+ },
2057
+ {
2058
+ "id": "CIBA-098",
2059
+ "label": "Token POST form",
2060
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.10.1",
2061
+ "status": "protocol_boundary_verified",
2062
+ "scope": "baseline poll token exchange on SQLite, PostgreSQL and MySQL; optional combinations audited separately",
2063
+ "finding": "A form-encoded POST with non-rewindable Rack input successfully redeems an approved request. This is positive transport evidence, not an exhaustive charset or malformed-media matrix.",
2064
+ "code_refs": [
2065
+ "lib/rodauth/features/ciba.rb"
2066
+ ],
2067
+ "test_refs": [
2068
+ {
2069
+ "file": "test/ciba_protocol_test.rb",
2070
+ "method": "test_rack_inputs_without_rewind_work_on_both_endpoints"
2071
+ }
2072
+ ],
2073
+ "execution": "docs/validation/token-exchange-audit-current.txt"
2074
+ },
2075
+ {
2076
+ "id": "CIBA-099",
2077
+ "label": "Token grant_type必須",
2078
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.10.1",
2079
+ "status": "protocol_boundary_verified",
2080
+ "scope": "baseline poll token exchange on SQLite, PostgreSQL and MySQL; optional combinations audited separately",
2081
+ "finding": "Missing grant_type fails with invalid_request; successful requests use the exact CIBA grant value. Other OAuth grants retain their upstream dispatch.",
2082
+ "code_refs": [
2083
+ "lib/rodauth/features/ciba.rb"
2084
+ ],
2085
+ "test_refs": [
2086
+ {
2087
+ "file": "test/ciba_security_test.rb",
2088
+ "method": "test_ciba_token_required_parameters_and_error_response_contract"
2089
+ }
2090
+ ],
2091
+ "execution": "docs/validation/token-exchange-audit-current.txt"
2092
+ },
2093
+ {
2094
+ "id": "CIBA-100",
2095
+ "label": "Token auth_req_id必須",
2096
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.10.1",
2097
+ "status": "protocol_boundary_verified",
2098
+ "scope": "baseline poll token exchange on SQLite, PostgreSQL and MySQL; optional combinations audited separately",
2099
+ "finding": "Missing and empty auth_req_id fail with invalid_request; an unissued identifier fails with invalid_grant without token persistence.",
2100
+ "code_refs": [
2101
+ "lib/rodauth/features/ciba.rb"
2102
+ ],
2103
+ "test_refs": [
2104
+ {
2105
+ "file": "test/ciba_security_test.rb",
2106
+ "method": "test_ciba_token_required_parameters_and_error_response_contract"
2107
+ }
2108
+ ],
2109
+ "execution": "docs/validation/token-exchange-audit-current.txt"
2110
+ },
2111
+ {
2112
+ "id": "CIBA-101",
2113
+ "label": "auth_req_idのクライアント束縛",
2114
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.10.1",
2115
+ "status": "protocol_boundary_verified",
2116
+ "scope": "baseline poll token exchange on SQLite, PostgreSQL and MySQL; optional combinations audited separately",
2117
+ "finding": "The request lookup binds its digest to the authenticated client. A different authenticated client cannot redeem it or alter the request; wrong account completion and exact expiry also reject issuance.",
2118
+ "code_refs": [
2119
+ "lib/rodauth/features/ciba.rb"
2120
+ ],
2121
+ "test_refs": [
2122
+ {
2123
+ "file": "test/ciba_integration_test.rb",
2124
+ "method": "test_other_identity_client_and_expiry_cannot_issue"
2125
+ }
2126
+ ],
2127
+ "execution": "docs/validation/token-exchange-audit-current.txt"
2128
+ },
2129
+ {
2130
+ "id": "CIBA-102",
2131
+ "label": "成功Token応答",
2132
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.10.1.1",
2133
+ "status": "protocol_boundary_verified",
2134
+ "scope": "baseline poll token exchange on SQLite, PostgreSQL and MySQL; optional combinations audited separately",
2135
+ "finding": "Approved baseline issuance returns access_token, signed issuer/audience-verified ID Token, bearer token type, positive integer lifetime and no-store/no-cache headers. This does not certify every optional claims/resource/sender-binding combination.",
2136
+ "code_refs": [
2137
+ "lib/rodauth/features/ciba.rb"
2138
+ ],
2139
+ "test_refs": [
2140
+ {
2141
+ "file": "test/ciba_integration_test.rb",
2142
+ "method": "test_approved_request_issues_customer_id_token_once"
2143
+ }
2144
+ ],
2145
+ "execution": "docs/validation/token-exchange-audit-current.txt"
2146
+ },
2147
+ {
2148
+ "id": "CIBA-103",
2149
+ "label": "成功後の一回限り消費",
2150
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.10.1.1",
2151
+ "status": "protocol_boundary_verified",
2152
+ "scope": "baseline poll token exchange on SQLite, PostgreSQL and MySQL; optional combinations audited separately",
2153
+ "finding": "Sequential redemption is rejected after success. Ten two-connection races per DB each yield exactly one successful signed response and one invalid_grant, with one grant per request. Arbitrary hooks and distributed adapters are outside this test.",
2154
+ "code_refs": [
2155
+ "lib/rodauth/features/ciba.rb"
2156
+ ],
2157
+ "test_refs": [
2158
+ {
2159
+ "file": "test/ciba_integration_test.rb",
2160
+ "method": "test_approved_request_issues_customer_id_token_once"
2161
+ },
2162
+ {
2163
+ "file": "test/ciba_integration_test.rb",
2164
+ "method": "test_concurrent_polls_issue_one_grant"
2165
+ }
2166
+ ],
2167
+ "execution": "docs/validation/token-exchange-audit-current.txt"
2168
+ },
2169
+ {
2170
+ "id": "CIBA-104",
2171
+ "label": "認証承認前のToken禁止",
2172
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.10.1.1",
2173
+ "status": "protocol_boundary_verified",
2174
+ "scope": "baseline poll token exchange on SQLite, PostgreSQL and MySQL; optional combinations audited separately",
2175
+ "finding": "Pending, throttled-pending and denied requests return errors without access_token, id_token or refresh_token and create no OAuth grant. Customer authentication itself is supplied through the application completion boundary.",
2176
+ "code_refs": [
2177
+ "lib/rodauth/features/ciba.rb"
2178
+ ],
2179
+ "test_refs": [
2180
+ {
2181
+ "file": "test/ciba_integration_test.rb",
2182
+ "method": "test_pending_poll_updates_survive_json_halt"
2183
+ },
2184
+ {
2185
+ "file": "test/ciba_protocol_test.rb",
2186
+ "method": "test_denial_and_expired_completion"
2187
+ },
2188
+ {
2189
+ "file": "test/ciba_integration_test.rb",
2190
+ "method": "test_unapproved_poll_responses_never_include_tokens"
2191
+ }
2192
+ ],
2193
+ "execution": "docs/validation/token-exchange-audit-current.txt"
2194
+ },
2195
+ {
2196
+ "id": "CIBA-105",
2197
+ "label": "ping HTTP POST",
2198
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.10.2",
2199
+ "status": "protocol_boundary_verified",
2200
+ "scope": "ping enabled; statements shared with push are assessed for ping only",
2201
+ "finding": "Application completion sends POST for approval and denial after commit. Expiry does not require a callback. Transaction rollback sends none.",
2202
+ "code_refs": [
2203
+ "lib/rodauth/features/ciba.rb",
2204
+ "lib/rodauth/ciba/http.rb",
2205
+ "docs/ping.md"
2206
+ ],
2207
+ "test_refs": [
2208
+ {
2209
+ "file": "test/ciba_ping_test.rb",
2210
+ "method": "test_ping_approval_denial_and_private_delivery_storage"
2211
+ }
2212
+ ],
2213
+ "execution": "docs/validation/ping-audit-current.txt"
2214
+ },
2215
+ {
2216
+ "id": "CIBA-106",
2217
+ "label": "ping bearer認証",
2218
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.10.2",
2219
+ "status": "protocol_boundary_verified",
2220
+ "scope": "ping enabled; statements shared with push are assessed for ping only",
2221
+ "finding": "Outgoing Authorization Bearer contains the request notification token; signed requests cannot be overridden by an outer value.",
2222
+ "code_refs": [
2223
+ "lib/rodauth/features/ciba.rb",
2224
+ "lib/rodauth/ciba/http.rb",
2225
+ "docs/ping.md"
2226
+ ],
2227
+ "test_refs": [
2228
+ {
2229
+ "file": "test/ciba_ping_test.rb",
2230
+ "method": "test_ping_with_signed_request_and_user_code_uses_only_signed_notification_token"
2231
+ }
2232
+ ],
2233
+ "execution": "docs/validation/ping-audit-current.txt"
2234
+ },
2235
+ {
2236
+ "id": "CIBA-107",
2237
+ "label": "ping payload",
2238
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.10.2",
2239
+ "status": "protocol_boundary_verified",
2240
+ "scope": "ping enabled; statements shared with push are assessed for ping only",
2241
+ "finding": "Only auth_req_id is sent as JSON; no tokens or consent payload accompany a ping.",
2242
+ "code_refs": [
2243
+ "lib/rodauth/features/ciba.rb",
2244
+ "lib/rodauth/ciba/http.rb",
2245
+ "docs/ping.md"
2246
+ ],
2247
+ "test_refs": [
2248
+ {
2249
+ "file": "test/ciba_ping_test.rb",
2250
+ "method": "test_ping_approval_denial_and_private_delivery_storage"
2251
+ }
2252
+ ],
2253
+ "execution": "docs/validation/ping-audit-current.txt"
2254
+ },
2255
+ {
2256
+ "id": "CIBA-108",
2257
+ "label": "pingクライアント検証",
2258
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.10.2",
2259
+ "status": "client_only",
2260
+ "scope": "ping enabled; statements shared with push are assessed for ping only",
2261
+ "finding": "Receiver validation of bearer/auth_req_id association and invalid-bearer401 is outside this OP. Existing sender tests do not establish a production receiver implementation.",
2262
+ "code_refs": [
2263
+ "lib/rodauth/features/ciba.rb",
2264
+ "lib/rodauth/ciba/http.rb",
2265
+ "docs/ping.md"
2266
+ ],
2267
+ "test_refs": [],
2268
+ "execution": null
2269
+ },
2270
+ {
2271
+ "id": "CIBA-109",
2272
+ "label": "ping応答処理",
2273
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.10.2",
2274
+ "status": "protocol_boundary_verified",
2275
+ "scope": "ping enabled; statements shared with push are assessed for ping only",
2276
+ "finding": "Ping accepts200/204 based on headers and closes without reading or draining the body. A real peer declaring10MB and withholding it observes immediate closure; installed/reference TLS fixtures accept140,000 ignored bytes. JWKS/sector body limits, TLS verification, address and redirect policies remain in force.",
2277
+ "code_refs": [
2278
+ "lib/rodauth/features/ciba.rb",
2279
+ "lib/rodauth/ciba/http.rb",
2280
+ "docs/ping.md",
2281
+ "lib/rodauth/ciba/http.rb"
2282
+ ],
2283
+ "test_refs": [
2284
+ {
2285
+ "file": "test/ciba_ping_test.rb",
2286
+ "method": "test_ping_approval_denial_and_private_delivery_storage"
2287
+ },
2288
+ {
2289
+ "file": "test/ciba_http_test.rb",
2290
+ "method": "test_header_only_response_closes_without_waiting_for_body"
2291
+ }
2292
+ ],
2293
+ "execution": "docs/validation/ping-response-body-current.txt"
2294
+ },
2295
+ {
2296
+ "id": "CIBA-110",
2297
+ "label": "pingリダイレクト禁止",
2298
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.10.2",
2299
+ "status": "protocol_boundary_verified",
2300
+ "scope": "ping enabled; statements shared with push are assessed for ping only",
2301
+ "finding": "Shared HTTP transport issues one request with no redirect handling. Installed TLS smoke rejects302 and sends only on explicit retry; this is not merely a mock assertion.",
2302
+ "code_refs": [
2303
+ "lib/rodauth/features/ciba.rb",
2304
+ "lib/rodauth/ciba/http.rb",
2305
+ "docs/ping.md",
2306
+ "examples/ping_smoke.rb"
2307
+ ],
2308
+ "test_refs": [],
2309
+ "execution": "docs/validation/mtls-remote-installed-final.txt"
2310
+ },
2311
+ {
2312
+ "id": "CIBA-111",
2313
+ "label": "ping後の取得",
2314
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.10.2",
2315
+ "status": "client_only",
2316
+ "scope": "ping enabled; statements shared with push are assessed for ping only",
2317
+ "finding": "The client retrieves tokens after validating a notification. OP tests demonstrate retrieval works, not that every client performs the required validation.",
2318
+ "code_refs": [
2319
+ "lib/rodauth/features/ciba.rb",
2320
+ "lib/rodauth/ciba/http.rb",
2321
+ "docs/ping.md"
2322
+ ],
2323
+ "test_refs": [
2324
+ {
2325
+ "file": "test/ciba_ping_test.rb",
2326
+ "method": "test_ping_approval_denial_and_private_delivery_storage"
2327
+ }
2328
+ ],
2329
+ "execution": "docs/validation/ping-audit-current.txt"
2330
+ },
2331
+ {
2332
+ "id": "CIBA-112",
2333
+ "label": "通知Endpoint TLS",
2334
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.9",
2335
+ "status": "protocol_boundary_verified",
2336
+ "scope": "ping enabled; statements shared with push are assessed for ping only",
2337
+ "finding": "Ping endpoints require HTTPS; installed smoke uses verified TLS and rejects an untrusted receiver before credentials arrive. Arbitrary deployments remain application-owned.",
2338
+ "code_refs": [
2339
+ "lib/rodauth/features/ciba.rb",
2340
+ "lib/rodauth/ciba/http.rb",
2341
+ "docs/ping.md",
2342
+ "examples/ping_smoke.rb"
2343
+ ],
2344
+ "test_refs": [],
2345
+ "execution": "docs/validation/mtls-remote-installed-final.txt"
2346
+ },
2347
+ {
2348
+ "id": "CIBA-113",
2349
+ "label": "通知Endpoint bearer認証",
2350
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.9",
2351
+ "status": "protocol_boundary_verified",
2352
+ "scope": "ping enabled; statements shared with push are assessed for ping only",
2353
+ "finding": "Ping sends the saved client_notification_token as Bearer; receiver verification remains a separate client duty.",
2354
+ "code_refs": [
2355
+ "lib/rodauth/features/ciba.rb",
2356
+ "lib/rodauth/ciba/http.rb",
2357
+ "docs/ping.md"
2358
+ ],
2359
+ "test_refs": [
2360
+ {
2361
+ "file": "test/ciba_ping_test.rb",
2362
+ "method": "test_ping_approval_denial_and_private_delivery_storage"
2363
+ }
2364
+ ],
2365
+ "execution": "docs/validation/ping-audit-current.txt"
2366
+ },
2367
+ {
2368
+ "id": "CIBA-114",
2369
+ "label": "push成功payload",
2370
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.10.3.1",
2371
+ "status": "reference_unsupported",
2372
+ "scope": "push mode, unsupported by pinned node 9.12.2 and the gem; poll/ping remain in scope",
2373
+ "finding": "Conditional push behavior is not implemented or advertised. Pinned node 9.12.2 rejects push provider configuration; the gem rejects push registration and request eligibility. This records non-applicability to the shared enabled modes, not a passing push implementation.",
2374
+ "code_refs": [
2375
+ "lib/rodauth/features/ciba.rb",
2376
+ "lib/rodauth/ciba/registration.rb",
2377
+ "docs/research/push-reference-boundary.md"
2378
+ ],
2379
+ "test_refs": [],
2380
+ "execution": "docs/validation/node-push-boundary.txt"
2381
+ },
2382
+ {
2383
+ "id": "CIBA-115",
2384
+ "label": "push at_hash",
2385
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.10.3.1",
2386
+ "status": "reference_unsupported",
2387
+ "scope": "push mode, unsupported by pinned node 9.12.2 and the gem; poll/ping remain in scope",
2388
+ "finding": "Conditional push behavior is not implemented or advertised. Pinned node 9.12.2 rejects push provider configuration; the gem rejects push registration and request eligibility. This records non-applicability to the shared enabled modes, not a passing push implementation.",
2389
+ "code_refs": [
2390
+ "lib/rodauth/features/ciba.rb",
2391
+ "lib/rodauth/ciba/registration.rb",
2392
+ "docs/research/push-reference-boundary.md"
2393
+ ],
2394
+ "test_refs": [],
2395
+ "execution": "docs/validation/node-push-boundary.txt"
2396
+ },
2397
+ {
2398
+ "id": "CIBA-116",
2399
+ "label": "push auth_req_id claim",
2400
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.10.3.1",
2401
+ "status": "reference_unsupported",
2402
+ "scope": "push mode, unsupported by pinned node 9.12.2 and the gem; poll/ping remain in scope",
2403
+ "finding": "Conditional push behavior is not implemented or advertised. Pinned node 9.12.2 rejects push provider configuration; the gem rejects push registration and request eligibility. This records non-applicability to the shared enabled modes, not a passing push implementation.",
2404
+ "code_refs": [
2405
+ "lib/rodauth/features/ciba.rb",
2406
+ "lib/rodauth/ciba/registration.rb",
2407
+ "docs/research/push-reference-boundary.md"
2408
+ ],
2409
+ "test_refs": [],
2410
+ "execution": "docs/validation/node-push-boundary.txt"
2411
+ },
2412
+ {
2413
+ "id": "CIBA-117",
2414
+ "label": "push rt_hash",
2415
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.10.3.1",
2416
+ "status": "reference_unsupported",
2417
+ "scope": "push mode, unsupported by pinned node 9.12.2 and the gem; poll/ping remain in scope",
2418
+ "finding": "Conditional push behavior is not implemented or advertised. Pinned node 9.12.2 rejects push provider configuration; the gem rejects push registration and request eligibility. This records non-applicability to the shared enabled modes, not a passing push implementation.",
2419
+ "code_refs": [
2420
+ "lib/rodauth/features/ciba.rb",
2421
+ "lib/rodauth/ciba/registration.rb",
2422
+ "docs/research/push-reference-boundary.md"
2423
+ ],
2424
+ "test_refs": [],
2425
+ "execution": "docs/validation/node-push-boundary.txt"
2426
+ },
2427
+ {
2428
+ "id": "CIBA-118",
2429
+ "label": "push受信検証",
2430
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.10.3.1",
2431
+ "status": "client_only",
2432
+ "scope": "push mode, unsupported by pinned node 9.12.2 and the gem; poll/ping remain in scope",
2433
+ "finding": "External push Client obligation; neither implementation provides push delivery, and no push client behavior is tested.",
2434
+ "code_refs": [
2435
+ "lib/rodauth/features/ciba.rb",
2436
+ "lib/rodauth/ciba/registration.rb",
2437
+ "docs/research/push-reference-boundary.md"
2438
+ ],
2439
+ "test_refs": [],
2440
+ "execution": "docs/validation/node-push-boundary.txt"
2441
+ },
2442
+ {
2443
+ "id": "CIBA-119",
2444
+ "label": "push応答処理",
2445
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.10.3.1",
2446
+ "status": "reference_unsupported",
2447
+ "scope": "push mode, unsupported by pinned node 9.12.2 and the gem; poll/ping remain in scope",
2448
+ "finding": "Conditional push behavior is not implemented or advertised. Pinned node 9.12.2 rejects push provider configuration; the gem rejects push registration and request eligibility. This records non-applicability to the shared enabled modes, not a passing push implementation.",
2449
+ "code_refs": [
2450
+ "lib/rodauth/features/ciba.rb",
2451
+ "lib/rodauth/ciba/registration.rb",
2452
+ "docs/research/push-reference-boundary.md"
2453
+ ],
2454
+ "test_refs": [],
2455
+ "execution": "docs/validation/node-push-boundary.txt"
2456
+ },
2457
+ {
2458
+ "id": "CIBA-120",
2459
+ "label": "pushリダイレクト禁止",
2460
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.10.3.1",
2461
+ "status": "reference_unsupported",
2462
+ "scope": "push mode, unsupported by pinned node 9.12.2 and the gem; poll/ping remain in scope",
2463
+ "finding": "Conditional push behavior is not implemented or advertised. Pinned node 9.12.2 rejects push provider configuration; the gem rejects push registration and request eligibility. This records non-applicability to the shared enabled modes, not a passing push implementation.",
2464
+ "code_refs": [
2465
+ "lib/rodauth/features/ciba.rb",
2466
+ "lib/rodauth/ciba/registration.rb",
2467
+ "docs/research/push-reference-boundary.md"
2468
+ ],
2469
+ "test_refs": [],
2470
+ "execution": "docs/validation/node-push-boundary.txt"
2471
+ },
2472
+ {
2473
+ "id": "CIBA-121",
2474
+ "label": "push未知パラメータ",
2475
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.10.3.1",
2476
+ "status": "client_only",
2477
+ "scope": "push mode, unsupported by pinned node 9.12.2 and the gem; poll/ping remain in scope",
2478
+ "finding": "External push Client obligation; neither implementation provides push delivery, and no push client behavior is tested.",
2479
+ "code_refs": [
2480
+ "lib/rodauth/features/ciba.rb",
2481
+ "lib/rodauth/ciba/registration.rb",
2482
+ "docs/research/push-reference-boundary.md"
2483
+ ],
2484
+ "test_refs": [],
2485
+ "execution": "docs/validation/node-push-boundary.txt"
2486
+ },
2487
+ {
2488
+ "id": "CIBA-122",
2489
+ "label": "Tokenエラー形式",
2490
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.11",
2491
+ "status": "protocol_boundary_verified",
2492
+ "scope": "CIBA error envelopes and baseline poll; authentication transports additionally exercised by the three-DB subset",
2493
+ "finding": "Required-parameter and unknown-request errors are JSON with cache suppression and no error_uri. Early authentication halts now receive no-store/no-cache from the CIBA HTTP boundary.",
2494
+ "code_refs": [
2495
+ "lib/rodauth/features/ciba.rb",
2496
+ "docs/research/error-response-reference-contract.md"
2497
+ ],
2498
+ "test_refs": [
2499
+ {
2500
+ "file": "test/ciba_security_test.rb",
2501
+ "method": "test_ciba_token_required_parameters_and_error_response_contract"
2502
+ }
2503
+ ],
2504
+ "execution": "docs/validation/error-cache-matrix.txt"
2505
+ },
2506
+ {
2507
+ "id": "CIBA-123",
2508
+ "label": "authorization_pending",
2509
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.11",
2510
+ "status": "protocol_boundary_verified",
2511
+ "scope": "CIBA error envelopes and baseline poll; authentication transports additionally exercised by the three-DB subset",
2512
+ "finding": "Pending requests return authorization_pending and persist polling timestamps without issuing tokens.",
2513
+ "code_refs": [
2514
+ "lib/rodauth/features/ciba.rb",
2515
+ "docs/research/error-response-reference-contract.md"
2516
+ ],
2517
+ "test_refs": [
2518
+ {
2519
+ "file": "test/ciba_integration_test.rb",
2520
+ "method": "test_pending_poll_updates_survive_json_halt"
2521
+ }
2522
+ ],
2523
+ "execution": "docs/validation/error-cache-matrix.txt"
2524
+ },
2525
+ {
2526
+ "id": "CIBA-124",
2527
+ "label": "slow_down",
2528
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.11",
2529
+ "status": "partial",
2530
+ "scope": "CIBA error envelopes and baseline poll; authentication transports additionally exercised by the three-DB subset",
2531
+ "finding": "Repeated early pending polls return slow_down and add five seconds to the saved interval, including concurrent calls. The reference delegates polling control to application policy; identical default throttling behavior is not claimed.",
2532
+ "code_refs": [
2533
+ "lib/rodauth/features/ciba.rb",
2534
+ "docs/research/error-response-reference-contract.md"
2535
+ ],
2536
+ "test_refs": [
2537
+ {
2538
+ "file": "test/ciba_integration_test.rb",
2539
+ "method": "test_pending_poll_updates_survive_json_halt"
2540
+ },
2541
+ {
2542
+ "file": "test/ciba_lifecycle_test.rb",
2543
+ "method": "test_concurrent_pending_polls_both_receive_retryable_results"
2544
+ }
2545
+ ],
2546
+ "execution": "docs/validation/error-cache-matrix.txt"
2547
+ },
2548
+ {
2549
+ "id": "CIBA-125",
2550
+ "label": "expired_token",
2551
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.11",
2552
+ "status": "protocol_boundary_verified",
2553
+ "scope": "CIBA error envelopes and baseline poll; authentication transports additionally exercised by the three-DB subset",
2554
+ "finding": "An approved request at its exact expiry returns expired_token without issuing a grant.",
2555
+ "code_refs": [
2556
+ "lib/rodauth/features/ciba.rb",
2557
+ "docs/research/error-response-reference-contract.md"
2558
+ ],
2559
+ "test_refs": [
2560
+ {
2561
+ "file": "test/ciba_integration_test.rb",
2562
+ "method": "test_other_identity_client_and_expiry_cannot_issue"
2563
+ }
2564
+ ],
2565
+ "execution": "docs/validation/error-cache-matrix.txt"
2566
+ },
2567
+ {
2568
+ "id": "CIBA-126",
2569
+ "label": "access_denied",
2570
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.11",
2571
+ "status": "protocol_boundary_verified",
2572
+ "scope": "CIBA error envelopes and baseline poll; authentication transports additionally exercised by the three-DB subset",
2573
+ "finding": "Application denial returns access_denied on poll. This is token retrieval after denial, distinct from pre-interaction HTTP403 policy rejection.",
2574
+ "code_refs": [
2575
+ "lib/rodauth/features/ciba.rb",
2576
+ "docs/research/error-response-reference-contract.md"
2577
+ ],
2578
+ "test_refs": [
2579
+ {
2580
+ "file": "test/ciba_protocol_test.rb",
2581
+ "method": "test_denial_and_expired_completion"
2582
+ }
2583
+ ],
2584
+ "execution": "docs/validation/error-cache-matrix.txt"
2585
+ },
2586
+ {
2587
+ "id": "CIBA-127",
2588
+ "label": "invalid_grant",
2589
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.11",
2590
+ "status": "protocol_boundary_verified",
2591
+ "scope": "CIBA error envelopes and baseline poll; authentication transports additionally exercised by the three-DB subset",
2592
+ "finding": "Unknown request identifiers and identifiers owned by another authenticated client return invalid_grant without issuing tokens or mutating the foreign request.",
2593
+ "code_refs": [
2594
+ "lib/rodauth/features/ciba.rb",
2595
+ "docs/research/error-response-reference-contract.md"
2596
+ ],
2597
+ "test_refs": [
2598
+ {
2599
+ "file": "test/ciba_integration_test.rb",
2600
+ "method": "test_other_identity_client_and_expiry_cannot_issue"
2601
+ },
2602
+ {
2603
+ "file": "test/ciba_security_test.rb",
2604
+ "method": "test_ciba_token_required_parameters_and_error_response_contract"
2605
+ }
2606
+ ],
2607
+ "execution": "docs/validation/error-cache-matrix.txt"
2608
+ },
2609
+ {
2610
+ "id": "CIBA-128",
2611
+ "label": "繰返し過剰pollの拒否",
2612
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.11",
2613
+ "status": "reference_unsupported",
2614
+ "scope": "application/client boundaries and optional polling policies; no production deployment certification",
2615
+ "finding": "Optional terminal invalid_request after repeated fast polling is not implemented by either baseline. Gem continues slow_down with interval increases; node pending handler has no equivalent built-in throttling.",
2616
+ "code_refs": [
2617
+ "lib/rodauth/features/ciba.rb",
2618
+ "docs/api.md"
2619
+ ],
2620
+ "test_refs": [],
2621
+ "execution": null
2622
+ },
2623
+ {
2624
+ "id": "CIBA-129",
2625
+ "label": "invalid_request後の停止",
2626
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.11",
2627
+ "status": "client_only",
2628
+ "scope": "application/client boundaries and optional polling policies; no production deployment certification",
2629
+ "finding": "Stopping polls after invalid_request is an external client duty, not an OP feature.",
2630
+ "code_refs": [
2631
+ "lib/rodauth/features/ciba.rb",
2632
+ "docs/api.md"
2633
+ ],
2634
+ "test_refs": [],
2635
+ "execution": null
2636
+ },
2637
+ {
2638
+ "id": "CIBA-130",
2639
+ "label": "pushクライアントのToken拒否",
2640
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.11",
2641
+ "status": "protocol_boundary_verified",
2642
+ "scope": "push mode, unsupported by pinned node 9.12.2 and the gem; poll/ping remain in scope",
2643
+ "finding": "A client changed to push cannot redeem an existing approved request: unauthorized_client is returned, with the request unchanged and no OAuth grant. Push is also rejected at registration.",
2644
+ "code_refs": [
2645
+ "lib/rodauth/features/ciba.rb",
2646
+ "lib/rodauth/ciba/registration.rb",
2647
+ "docs/research/push-reference-boundary.md"
2648
+ ],
2649
+ "test_refs": [
2650
+ {
2651
+ "file": "test/ciba_configuration_test.rb",
2652
+ "method": "test_push_client_cannot_redeem_existing_ciba_request"
2653
+ }
2654
+ ],
2655
+ "execution": "docs/validation/push-boundary-audit-current.txt"
2656
+ },
2657
+ {
2658
+ "id": "CIBA-131",
2659
+ "label": "pushエラーJSON",
2660
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.12",
2661
+ "status": "reference_unsupported",
2662
+ "scope": "push mode, unsupported by pinned node 9.12.2 and the gem; poll/ping remain in scope",
2663
+ "finding": "Conditional push behavior is not implemented or advertised. Pinned node 9.12.2 rejects push provider configuration; the gem rejects push registration and request eligibility. This records non-applicability to the shared enabled modes, not a passing push implementation.",
2664
+ "code_refs": [
2665
+ "lib/rodauth/features/ciba.rb",
2666
+ "lib/rodauth/ciba/registration.rb",
2667
+ "docs/research/push-reference-boundary.md"
2668
+ ],
2669
+ "test_refs": [],
2670
+ "execution": "docs/validation/node-push-boundary.txt"
2671
+ },
2672
+ {
2673
+ "id": "CIBA-132",
2674
+ "label": "push error_description文字集合",
2675
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.12",
2676
+ "status": "reference_unsupported",
2677
+ "scope": "push mode, unsupported by pinned node 9.12.2 and the gem; poll/ping remain in scope",
2678
+ "finding": "Conditional push behavior is not implemented or advertised. Pinned node 9.12.2 rejects push provider configuration; the gem rejects push registration and request eligibility. This records non-applicability to the shared enabled modes, not a passing push implementation.",
2679
+ "code_refs": [
2680
+ "lib/rodauth/features/ciba.rb",
2681
+ "lib/rodauth/ciba/registration.rb",
2682
+ "docs/research/push-reference-boundary.md"
2683
+ ],
2684
+ "test_refs": [],
2685
+ "execution": "docs/validation/node-push-boundary.txt"
2686
+ },
2687
+ {
2688
+ "id": "CIBA-133",
2689
+ "label": "push access_denied",
2690
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.12",
2691
+ "status": "reference_unsupported",
2692
+ "scope": "push mode, unsupported by pinned node 9.12.2 and the gem; poll/ping remain in scope",
2693
+ "finding": "Conditional push behavior is not implemented or advertised. Pinned node 9.12.2 rejects push provider configuration; the gem rejects push registration and request eligibility. This records non-applicability to the shared enabled modes, not a passing push implementation.",
2694
+ "code_refs": [
2695
+ "lib/rodauth/features/ciba.rb",
2696
+ "lib/rodauth/ciba/registration.rb",
2697
+ "docs/research/push-reference-boundary.md"
2698
+ ],
2699
+ "test_refs": [],
2700
+ "execution": "docs/validation/node-push-boundary.txt"
2701
+ },
2702
+ {
2703
+ "id": "CIBA-134",
2704
+ "label": "push expired_token",
2705
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.12",
2706
+ "status": "reference_unsupported",
2707
+ "scope": "push mode, unsupported by pinned node 9.12.2 and the gem; poll/ping remain in scope",
2708
+ "finding": "Conditional push behavior is not implemented or advertised. Pinned node 9.12.2 rejects push provider configuration; the gem rejects push registration and request eligibility. This records non-applicability to the shared enabled modes, not a passing push implementation.",
2709
+ "code_refs": [
2710
+ "lib/rodauth/features/ciba.rb",
2711
+ "lib/rodauth/ciba/registration.rb",
2712
+ "docs/research/push-reference-boundary.md"
2713
+ ],
2714
+ "test_refs": [],
2715
+ "execution": "docs/validation/node-push-boundary.txt"
2716
+ },
2717
+ {
2718
+ "id": "CIBA-135",
2719
+ "label": "push transaction_failed",
2720
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.12",
2721
+ "status": "reference_unsupported",
2722
+ "scope": "push mode, unsupported by pinned node 9.12.2 and the gem; poll/ping remain in scope",
2723
+ "finding": "Conditional push behavior is not implemented or advertised. Pinned node 9.12.2 rejects push provider configuration; the gem rejects push registration and request eligibility. This records non-applicability to the shared enabled modes, not a passing push implementation.",
2724
+ "code_refs": [
2725
+ "lib/rodauth/features/ciba.rb",
2726
+ "lib/rodauth/ciba/registration.rb",
2727
+ "docs/research/push-reference-boundary.md"
2728
+ ],
2729
+ "test_refs": [],
2730
+ "execution": "docs/validation/node-push-boundary.txt"
2731
+ },
2732
+ {
2733
+ "id": "CIBA-136",
2734
+ "label": "開始エラーJSON",
2735
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.13",
2736
+ "status": "protocol_boundary_verified",
2737
+ "scope": "CIBA error envelopes and baseline poll; authentication transports additionally exercised by the three-DB subset",
2738
+ "finding": "Six rejection/failure paths return JSON with ASCII error codes, no tokens or request identifiers, and cache suppression. Unexpected exceptions do not expose their messages.",
2739
+ "code_refs": [
2740
+ "lib/rodauth/features/ciba.rb",
2741
+ "docs/research/error-response-reference-contract.md"
2742
+ ],
2743
+ "test_refs": [
2744
+ {
2745
+ "file": "test/ciba_requirements_test.rb",
2746
+ "method": "test_authentication_error_envelopes_do_not_expose_tokens_or_internal_errors"
2747
+ }
2748
+ ],
2749
+ "execution": "docs/validation/error-cache-matrix.txt"
2750
+ },
2751
+ {
2752
+ "id": "CIBA-137",
2753
+ "label": "error_description文字集合",
2754
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.13",
2755
+ "status": "protocol_boundary_verified",
2756
+ "scope": "CIBA error envelopes and baseline poll; authentication transports additionally exercised by the three-DB subset",
2757
+ "finding": "Allowed ASCII error descriptions survive; quotes, backslashes, newlines and non-ASCII custom descriptions are omitted.",
2758
+ "code_refs": [
2759
+ "lib/rodauth/features/ciba.rb",
2760
+ "docs/research/error-response-reference-contract.md"
2761
+ ],
2762
+ "test_refs": [
2763
+ {
2764
+ "file": "test/ciba_requirements_test.rb",
2765
+ "method": "test_authentication_error_description_keeps_allowed_ascii_and_omits_unsafe_text"
2766
+ }
2767
+ ],
2768
+ "execution": "docs/validation/error-cache-matrix.txt"
2769
+ },
2770
+ {
2771
+ "id": "CIBA-138",
2772
+ "label": "error_uri文字集合",
2773
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.13",
2774
+ "status": "partial",
2775
+ "scope": "CIBA error envelopes and baseline poll; authentication transports additionally exercised by the three-DB subset",
2776
+ "finding": "The tested upstream responses do not emit error_uri. No custom URI injection mechanism or URI-syntax sanitizer is established; the conditional field is absent rather than positively validated.",
2777
+ "code_refs": [
2778
+ "lib/rodauth/features/ciba.rb",
2779
+ "docs/research/error-response-reference-contract.md"
2780
+ ],
2781
+ "test_refs": [
2782
+ {
2783
+ "file": "test/ciba_requirements_test.rb",
2784
+ "method": "test_authentication_error_description_keeps_allowed_ascii_and_omits_unsafe_text"
2785
+ }
2786
+ ],
2787
+ "execution": "docs/validation/error-cache-matrix.txt"
2788
+ },
2789
+ {
2790
+ "id": "CIBA-139",
2791
+ "label": "400 invalid_request",
2792
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.13",
2793
+ "status": "protocol_boundary_verified",
2794
+ "scope": "CIBA error envelopes and baseline poll; authentication transports additionally exercised by the three-DB subset",
2795
+ "finding": "Missing or malformed parameters, duplicate form fields and conflicting hints return HTTP400 invalid_request. Specific optional hint combinations have separate evidence.",
2796
+ "code_refs": [
2797
+ "lib/rodauth/features/ciba.rb",
2798
+ "docs/research/error-response-reference-contract.md"
2799
+ ],
2800
+ "test_refs": [
2801
+ {
2802
+ "file": "test/ciba_protocol_test.rb",
2803
+ "method": "test_duplicate_parameters_are_rejected"
2804
+ },
2805
+ {
2806
+ "file": "test/ciba_protocol_test.rb",
2807
+ "method": "test_request_validation_and_unknown_parameters"
2808
+ }
2809
+ ],
2810
+ "execution": "docs/validation/error-cache-matrix.txt"
2811
+ },
2812
+ {
2813
+ "id": "CIBA-140",
2814
+ "label": "400 invalid_scope",
2815
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.13",
2816
+ "status": "protocol_boundary_verified",
2817
+ "scope": "CIBA error envelopes and baseline poll; authentication transports additionally exercised by the three-DB subset",
2818
+ "finding": "Missing scope returns invalid_request; present malformed or disallowed scopes return HTTP400 invalid_scope.",
2819
+ "code_refs": [
2820
+ "lib/rodauth/features/ciba.rb",
2821
+ "docs/research/error-response-reference-contract.md"
2822
+ ],
2823
+ "test_refs": [
2824
+ {
2825
+ "file": "test/ciba_requirements_test.rb",
2826
+ "method": "test_scope_syntax_errors_are_invalid_scope"
2827
+ }
2828
+ ],
2829
+ "execution": "docs/validation/error-cache-matrix.txt"
2830
+ },
2831
+ {
2832
+ "id": "CIBA-141",
2833
+ "label": "400 expired_login_hint_token",
2834
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.13",
2835
+ "status": "protocol_boundary_verified",
2836
+ "scope": "optional hint mechanisms enabled where applicable",
2837
+ "finding": "Application expiry errors become HTTP400 expired_login_hint_token; unexpected resolver errors become HTTP500 without pending records or dispatch. The gem does not infer arbitrary token expiry.",
2838
+ "code_refs": [
2839
+ "lib/rodauth/features/ciba.rb",
2840
+ "docs/login-hint-token.md",
2841
+ "docs/id-token-hint.md"
2842
+ ],
2843
+ "test_refs": [
2844
+ {
2845
+ "file": "test/ciba_hint_token_test.rb",
2846
+ "method": "test_hint_token_expiry_and_resolver_failure_precede_persistence"
2847
+ }
2848
+ ],
2849
+ "execution": "docs/validation/hint-audit-current.txt"
2850
+ },
2851
+ {
2852
+ "id": "CIBA-142",
2853
+ "label": "400 unknown_user_id",
2854
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.13",
2855
+ "status": "protocol_boundary_verified",
2856
+ "scope": "CIBA error envelopes and baseline poll; authentication transports additionally exercised by the three-DB subset",
2857
+ "finding": "A validly shaped but unresolved login_hint returns HTTP400 unknown_user_id before request persistence.",
2858
+ "code_refs": [
2859
+ "lib/rodauth/features/ciba.rb",
2860
+ "docs/research/error-response-reference-contract.md"
2861
+ ],
2862
+ "test_refs": [
2863
+ {
2864
+ "file": "test/ciba_protocol_test.rb",
2865
+ "method": "test_request_validation_and_unknown_parameters"
2866
+ }
2867
+ ],
2868
+ "execution": "docs/validation/error-cache-matrix.txt"
2869
+ },
2870
+ {
2871
+ "id": "CIBA-143",
2872
+ "label": "400 unauthorized_client",
2873
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.13",
2874
+ "status": "protocol_boundary_verified",
2875
+ "scope": "CIBA error envelopes and baseline poll; authentication transports additionally exercised by the three-DB subset",
2876
+ "finding": "Clients lacking CIBA eligibility return HTTP400 unauthorized_client without creating requests; registered mode and grant changes are checked.",
2877
+ "code_refs": [
2878
+ "lib/rodauth/features/ciba.rb",
2879
+ "docs/research/error-response-reference-contract.md"
2880
+ ],
2881
+ "test_refs": [
2882
+ {
2883
+ "file": "test/ciba_configuration_test.rb",
2884
+ "method": "test_unavailable_or_unsupported_client_metadata_is_rejected"
2885
+ }
2886
+ ],
2887
+ "execution": "docs/validation/error-cache-matrix.txt"
2888
+ },
2889
+ {
2890
+ "id": "CIBA-144",
2891
+ "label": "400 missing_user_code",
2892
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.13",
2893
+ "status": "protocol_boundary_verified",
2894
+ "scope": "user-code feature enabled unless otherwise stated",
2895
+ "finding": "Application-declared missing code yields the protocol error before dispatch.",
2896
+ "code_refs": [
2897
+ "lib/rodauth/features/ciba.rb",
2898
+ "docs/user-code.md"
2899
+ ],
2900
+ "test_refs": [
2901
+ {
2902
+ "file": "test/ciba_user_code_test.rb",
2903
+ "method": "test_user_code_requires_explicit_callback_and_checks_before_device_dispatch"
2904
+ }
2905
+ ],
2906
+ "execution": "docs/validation/user-code-audit-current.txt"
2907
+ },
2908
+ {
2909
+ "id": "CIBA-145",
2910
+ "label": "400 invalid_user_code",
2911
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.13",
2912
+ "status": "protocol_boundary_verified",
2913
+ "scope": "user-code feature enabled unless otherwise stated",
2914
+ "finding": "False/nil validation yields invalid_user_code; malformed input instead fails request validation.",
2915
+ "code_refs": [
2916
+ "lib/rodauth/features/ciba.rb",
2917
+ "docs/user-code.md"
2918
+ ],
2919
+ "test_refs": [
2920
+ {
2921
+ "file": "test/ciba_user_code_test.rb",
2922
+ "method": "test_user_code_requires_explicit_callback_and_checks_before_device_dispatch"
2923
+ }
2924
+ ],
2925
+ "execution": "docs/validation/user-code-audit-current.txt"
2926
+ },
2927
+ {
2928
+ "id": "CIBA-146",
2929
+ "label": "400 invalid_binding_message",
2930
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.13",
2931
+ "status": "protocol_boundary_verified",
2932
+ "scope": "CIBA error envelopes and baseline poll; authentication transports additionally exercised by the three-DB subset",
2933
+ "finding": "An oversized binding message returns HTTP400 invalid_binding_message before request persistence. Application-specific acceptable message content is separately configurable.",
2934
+ "code_refs": [
2935
+ "lib/rodauth/features/ciba.rb",
2936
+ "docs/research/error-response-reference-contract.md"
2937
+ ],
2938
+ "test_refs": [
2939
+ {
2940
+ "file": "test/ciba_protocol_test.rb",
2941
+ "method": "test_expiry_binding_context_and_offline_access"
2942
+ }
2943
+ ],
2944
+ "execution": "docs/validation/error-cache-matrix.txt"
2945
+ },
2946
+ {
2947
+ "id": "CIBA-147",
2948
+ "label": "401 invalid_client",
2949
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.13",
2950
+ "status": "protocol_boundary_verified",
2951
+ "scope": "CIBA error envelopes and baseline poll; authentication transports additionally exercised by the three-DB subset",
2952
+ "finding": "Missing client authentication now returns HTTP401 invalid_client rather than400 invalid_request at the Backchannel endpoint and CIBA token polling endpoint. Direct tests cover absent/wrong credentials, Basic challenge, no new pending request, preserved approval, no issued grant and successful authenticated retry. This intentionally supersedes the prior reference-aligned missing-identifier mapping; it is not an exhaustive proof for all optional authentication error paths.",
2953
+ "code_refs": [
2954
+ "lib/rodauth/features/ciba.rb",
2955
+ "docs/research/error-response-reference-contract.md"
2956
+ ],
2957
+ "test_refs": [
2958
+ {
2959
+ "file": "test/ciba_requirements_test.rb",
2960
+ "method": "test_authentication_errors_use_invalid_client_and_http_401"
2961
+ },
2962
+ {
2963
+ "file": "test/ciba_integration_test.rb",
2964
+ "method": "test_client_authentication_is_required_at_both_endpoints"
2965
+ }
2966
+ ],
2967
+ "execution": "docs/validation/missing-client-auth-green.txt"
2968
+ },
2969
+ {
2970
+ "id": "CIBA-148",
2971
+ "label": "403 access_denied",
2972
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.13",
2973
+ "status": "app_contract",
2974
+ "scope": "application/client boundaries and optional polling policies; no production deployment certification",
2975
+ "finding": "An explicit application rejection can send HTTP403 access_denied before persistence or device dispatch. The reference supports explicit OIDCProviderError(403), while its default AccessDenied is 400; gem ProtocolError also defaults to 400. Application policy must choose the appropriate status.",
2976
+ "code_refs": [
2977
+ "lib/rodauth/features/ciba.rb",
2978
+ "docs/api.md"
2979
+ ],
2980
+ "test_refs": [
2981
+ {
2982
+ "file": "test/ciba_requirements_test.rb",
2983
+ "method": "test_application_can_reject_start_with_explicit_403_before_dispatch"
2984
+ }
2985
+ ],
2986
+ "execution": "docs/validation/application-boundaries-audit-current.txt"
2987
+ },
2988
+ {
2989
+ "id": "CIBA-149",
2990
+ "label": "login_hint_token署名",
2991
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.14",
2992
+ "status": "app_contract",
2993
+ "scope": "optional hint mechanisms enabled where applicable",
2994
+ "finding": "Issuer-signature policy is delegated to the token-format resolver. Existing fixtures use opaque references and do not prove signature validation for a production login_hint_token format.",
2995
+ "code_refs": [
2996
+ "lib/rodauth/features/ciba.rb",
2997
+ "docs/login-hint-token.md",
2998
+ "docs/id-token-hint.md"
2999
+ ],
3000
+ "test_refs": [],
3001
+ "execution": null
3002
+ },
3003
+ {
3004
+ "id": "CIBA-150",
3005
+ "label": "通知URLの管理権限",
3006
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.14",
3007
+ "status": "app_contract",
3008
+ "scope": "ping enabled; statements shared with push are assessed for ping only",
3009
+ "finding": "Application should establish notification endpoint administrative ownership. HTTPS/IP filtering and immutable destination snapshots are not proof of client ownership; no universal ownership protocol is supplied.",
3010
+ "code_refs": [
3011
+ "lib/rodauth/features/ciba.rb",
3012
+ "lib/rodauth/ciba/http.rb",
3013
+ "docs/ping.md"
3014
+ ],
3015
+ "test_refs": [],
3016
+ "execution": null
3017
+ },
3018
+ {
3019
+ "id": "CIBA-151",
3020
+ "label": "期限切れid_token_hint許容",
3021
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.14",
3022
+ "status": "partial",
3023
+ "scope": "optional hint mechanisms enabled where applicable",
3024
+ "finding": "Expired ID hints are accepted, with optional maximum age from iat. Default unlimited age while keys remain trusted matches the measured reference; deployment-specific reasonable retention has not been established.",
3025
+ "code_refs": [
3026
+ "lib/rodauth/features/ciba.rb",
3027
+ "docs/login-hint-token.md",
3028
+ "docs/id-token-hint.md"
3029
+ ],
3030
+ "test_refs": [
3031
+ {
3032
+ "file": "test/ciba_id_token_hint_test.rb",
3033
+ "method": "test_id_hint_retained_keys_audience_array_age_and_account_policy"
3034
+ }
3035
+ ],
3036
+ "execution": "docs/validation/hint-audit-current.txt"
3037
+ },
3038
+ {
3039
+ "id": "CIBA-152",
3040
+ "label": "id_token_hintのissuerとaudience",
3041
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.14",
3042
+ "status": "protocol_boundary_verified",
3043
+ "scope": "optional hint mechanisms enabled where applicable",
3044
+ "finding": "Trusted OP issuer and authenticated-client audience membership are verified before subject resolution; wrong issuer/audience are rejected.",
3045
+ "code_refs": [
3046
+ "lib/rodauth/features/ciba.rb",
3047
+ "docs/login-hint-token.md",
3048
+ "docs/id-token-hint.md"
3049
+ ],
3050
+ "test_refs": [
3051
+ {
3052
+ "file": "test/ciba_id_token_hint_test.rb",
3053
+ "method": "test_id_hint_rejects_untrusted_claims_and_signatures_before_subject_resolution"
3054
+ }
3055
+ ],
3056
+ "execution": "docs/validation/hint-audit-current.txt"
3057
+ },
3058
+ {
3059
+ "id": "CIBA-153",
3060
+ "label": "id_token_hint署名",
3061
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.14",
3062
+ "status": "protocol_boundary_verified",
3063
+ "scope": "optional hint mechanisms enabled where applicable",
3064
+ "finding": "Configured asymmetric/Edwards signatures use trusted current or retained OP keys; HMAC issuance and hint verification use the client secret, with no OP-key fallback. Actual issuance/reuse and wrong-key rejection have direct tests. HMAC Basic/POST and hashed/plaintext storage pass three-DB and independent jose checks; installed-gem issuance/refresh/hints and backend secret replacement pass, as do Ruby 3.3/3.4 full suites. DCR generates sufficiently long HS256/384/512 secrets. This verifies the signature boundary, not all deployment rotation policies. Encrypted hints are rejected by both implementations; optional signature-free pairwise acceptance is not required by this catalog guidance.",
3065
+ "code_refs": [
3066
+ "lib/rodauth/features/ciba.rb",
3067
+ "docs/login-hint-token.md",
3068
+ "docs/id-token-hint.md",
3069
+ "docs/research/id-token-hint-reference-contract.md",
3070
+ "docs/id-token-encryption.md"
3071
+ ],
3072
+ "test_refs": [
3073
+ {
3074
+ "file": "test/ciba_id_token_hint_test.rb",
3075
+ "method": "test_id_hint_accepts_actual_op_tokens_with_configured_rsa_ec_and_hmac_keys"
3076
+ },
3077
+ {
3078
+ "file": "test/ciba_edwards_id_token_test.rb",
3079
+ "method": "test_edwards_id_token_issuance_public_keys_and_hints"
3080
+ },
3081
+ {
3082
+ "file": "test/ciba_edwards_id_token_test.rb",
3083
+ "method": "test_edwards_id_token_registration_requires_configured_keys"
3084
+ },
3085
+ {
3086
+ "file": "test/ciba_edwards_id_token_test.rb",
3087
+ "method": "test_edwards_id_token_encryption_does_not_silently_fall_back_to_plaintext"
3088
+ },
3089
+ {
3090
+ "file": "test/ciba_edwards_id_token_test.rb",
3091
+ "method": "test_edwards_id_token_refresh_public_subject"
3092
+ },
3093
+ {
3094
+ "file": "test/ciba_edwards_id_token_test.rb",
3095
+ "method": "test_edwards_id_token_refresh_pairwise_subject"
3096
+ },
3097
+ {
3098
+ "file": "test/ciba_hmac_id_token_test.rb",
3099
+ "method": "test_ciba_hmac_id_tokens_use_authenticated_client_secret"
3100
+ },
3101
+ {
3102
+ "file": "test/ciba_hmac_id_token_test.rb",
3103
+ "method": "test_ciba_hmac_secret_callback_and_missing_secret_rollback"
3104
+ },
3105
+ {
3106
+ "file": "test/ciba_hmac_id_token_test.rb",
3107
+ "method": "test_ciba_hmac_registration_generates_sufficient_client_secret"
3108
+ }
3109
+ ],
3110
+ "execution": "docs/validation/hmac-registration-secret-matrix.txt"
3111
+ },
3112
+ {
3113
+ "id": "CIBA-154",
3114
+ "label": "push Endpoint保護",
3115
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.14",
3116
+ "status": "reference_unsupported",
3117
+ "scope": "push mode, unsupported by pinned node 9.12.2 and the gem; poll/ping remain in scope",
3118
+ "finding": "Conditional push behavior is not implemented or advertised. Pinned node 9.12.2 rejects push provider configuration; the gem rejects push registration and request eligibility. This records non-applicability to the shared enabled modes, not a passing push implementation.",
3119
+ "code_refs": [
3120
+ "lib/rodauth/features/ciba.rb",
3121
+ "lib/rodauth/ciba/registration.rb",
3122
+ "docs/research/push-reference-boundary.md"
3123
+ ],
3124
+ "test_refs": [],
3125
+ "execution": "docs/validation/node-push-boundary.txt"
3126
+ },
3127
+ {
3128
+ "id": "CIBA-155",
3129
+ "label": "業務コンテキストの追加",
3130
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.14",
3131
+ "status": "protocol_boundary_verified",
3132
+ "scope": "application/client boundaries and optional polling policies; no production deployment certification",
3133
+ "finding": "Opt-in request_context is validated in authenticated client context, stored and dispatched; signed input controls it, poll cannot replace it, and it is excluded from identity claims and observation events. Business meaning remains application-specific.",
3134
+ "code_refs": [
3135
+ "lib/rodauth/features/ciba.rb",
3136
+ "docs/api.md"
3137
+ ],
3138
+ "test_refs": [
3139
+ {
3140
+ "file": "test/ciba_request_context_test.rb",
3141
+ "method": "test_request_context_is_validated_stored_and_not_a_token_claim"
3142
+ },
3143
+ {
3144
+ "file": "test/ciba_request_context_test.rb",
3145
+ "method": "test_request_context_signed_input_replaces_outer_context"
3146
+ }
3147
+ ],
3148
+ "execution": "docs/validation/application-boundaries-audit-current.txt"
3149
+ },
3150
+ {
3151
+ "id": "CIBA-156",
3152
+ "label": "プライバシー配慮識別子",
3153
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.15",
3154
+ "status": "app_contract",
3155
+ "scope": "application/client boundaries and optional polling policies; no production deployment certification",
3156
+ "finding": "App-defined opaque login_hint references and token resolvers support alternatives to global identifiers. Actual unlinkability, identifier lifetime and privacy policy are not guaranteed by accepting an arbitrary string.",
3157
+ "code_refs": [
3158
+ "lib/rodauth/features/ciba.rb",
3159
+ "docs/api.md"
3160
+ ],
3161
+ "test_refs": [
3162
+ {
3163
+ "file": "test/ciba_protocol_test.rb",
3164
+ "method": "test_login_hint_is_application_defined_and_unknown_fields_cannot_set_state"
3165
+ }
3166
+ ],
3167
+ "execution": "docs/validation/application-boundaries-audit-current.txt"
3168
+ },
3169
+ {
3170
+ "id": "CIBA-157",
3171
+ "label": "pairwise ID Token hint",
3172
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.15",
3173
+ "status": "protocol_boundary_verified",
3174
+ "scope": "optional hint mechanisms enabled where applicable",
3175
+ "finding": "Actual signed pairwise ID Token maps through an application resolver to a canonical account and creates a request without saved consent. Arbitrary resolver correctness is not proven.",
3176
+ "code_refs": [
3177
+ "lib/rodauth/features/ciba.rb",
3178
+ "docs/login-hint-token.md",
3179
+ "docs/id-token-hint.md"
3180
+ ],
3181
+ "test_refs": [
3182
+ {
3183
+ "file": "test/ciba_pairwise_test.rb",
3184
+ "method": "test_pairwise_jwt_access_token_userinfo_and_hint"
3185
+ }
3186
+ ],
3187
+ "execution": "docs/validation/pairwise-hint-audit.txt"
3188
+ },
3189
+ {
3190
+ "id": "CIBA-158",
3191
+ "label": "一回限り識別子hint token",
3192
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.15",
3193
+ "status": "app_contract",
3194
+ "scope": "optional hint mechanisms enabled where applicable",
3195
+ "finding": "The optional AD-to-CD one-use reference protocol is not implemented. A resolver hook can integrate it; its existence does not prove atomic single-use handling or privacy properties.",
3196
+ "code_refs": [
3197
+ "lib/rodauth/features/ciba.rb",
3198
+ "docs/login-hint-token.md",
3199
+ "docs/id-token-hint.md"
3200
+ ],
3201
+ "test_refs": [],
3202
+ "execution": null
3203
+ },
3204
+ {
3205
+ "id": "CIBA-159",
3206
+ "label": "Discovery Service hint token",
3207
+ "source": "https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.15",
3208
+ "status": "app_contract",
3209
+ "scope": "optional hint mechanisms enabled where applicable",
3210
+ "finding": "The optional discovery-service encrypted login_hint_token format is not implemented. Decryption and issuer/audience policy belong to an application resolver; no complete deployment has been tested.",
3211
+ "code_refs": [
3212
+ "lib/rodauth/features/ciba.rb",
3213
+ "docs/login-hint-token.md",
3214
+ "docs/id-token-hint.md"
3215
+ ],
3216
+ "test_refs": [],
3217
+ "execution": null
3218
+ }
3219
+ ],
3220
+ "pending_ids": []
3221
+ }