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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +34 -0
- data/LICENSE +21 -0
- data/README.md +106 -0
- data/docs/adr/0003-follow-rodauth-hook-conventions.md +9 -0
- data/docs/adr/0004-retain-atomic-issuance-and-stage-alignment.md +16 -0
- data/docs/alignment-closeout.md +136 -0
- data/docs/alignment-roadmap.md +160 -0
- data/docs/api.md +337 -0
- data/docs/authentication-claims.md +80 -0
- data/docs/authorization-details.md +50 -0
- data/docs/claims.md +46 -0
- data/docs/failure-contract.md +34 -0
- data/docs/id-token-encryption.md +288 -0
- data/docs/id-token-hint.md +174 -0
- data/docs/login-hint-token.md +35 -0
- data/docs/max-age.md +65 -0
- data/docs/node-alignment.md +336 -0
- data/docs/operations.md +130 -0
- data/docs/outbound-http.md +52 -0
- data/docs/pairwise.md +76 -0
- data/docs/ping.md +118 -0
- data/docs/protocol-coverage.md +114 -0
- data/docs/refresh-tokens.md +151 -0
- data/docs/release-readiness.md +75 -0
- data/docs/release-validation.md +498 -0
- data/docs/request-context.md +51 -0
- data/docs/requirements-audit-current.json +3221 -0
- data/docs/requirements-audit-current.md +424 -0
- data/docs/requirements-audit.json +3190 -0
- data/docs/requirements-audit.md +175 -0
- data/docs/research/access-token-revocation-reference.md +81 -0
- data/docs/research/alignment-partial-triage.md +50 -0
- data/docs/research/claims-reference-contract.md +33 -0
- data/docs/research/client-assertion-algorithm-contract.md +177 -0
- data/docs/research/completion-error-boundaries.md +56 -0
- data/docs/research/consent-api-evolution.md +59 -0
- data/docs/research/dpop-reference-contract.md +423 -0
- data/docs/research/id-token-hint-reference-contract.md +254 -0
- data/docs/research/mtls-reference-contract.md +449 -0
- data/docs/research/node-ciba-lifecycle.md +30 -0
- data/docs/research/node-oidc-provider-comparison.md +45 -0
- data/docs/research/pairwise-reference-contract.md +264 -0
- data/docs/research/ping-reference-contract.md +165 -0
- data/docs/research/rar-reference-contract.md +55 -0
- data/docs/research/refresh-reference-contract.md +85 -0
- data/docs/research/registration-reference-contract.md +567 -0
- data/docs/research/request-parameter-inventory.md +42 -0
- data/docs/research/required-parameter-inventory.md +39 -0
- data/docs/research/resource-reference-contract.md +40 -0
- data/docs/research/signed-request-reference-contract.md +113 -0
- data/docs/resources.md +55 -0
- data/docs/security-review.md +294 -0
- data/docs/signed-requests.md +162 -0
- data/docs/user-code.md +73 -0
- data/docs/validation/node-alignment-tests.txt +10 -0
- data/examples/client.rb +39 -0
- data/examples/demo_app.rb +121 -0
- data/examples/dpop_smoke.rb +169 -0
- data/examples/ecdh_id_token_smoke.rb +84 -0
- data/examples/edwards_id_token_smoke.rb +48 -0
- data/examples/edwards_smoke.rb +87 -0
- data/examples/edwards_tls_smoke.rb +73 -0
- data/examples/encrypted_id_token_smoke.rb +73 -0
- data/examples/encryption_tls_smoke.rb +123 -0
- data/examples/extensions_smoke.rb +226 -0
- data/examples/fixtures/edwards-requests.json +30 -0
- data/examples/hmac_id_token_smoke.rb +72 -0
- data/examples/migration.rb +18 -0
- data/examples/mtls_smoke.rb +395 -0
- data/examples/ping_smoke.rb +226 -0
- data/examples/registration_smoke.rb +73 -0
- data/examples/server.rb +14 -0
- data/examples/smoke.rb +46 -0
- data/examples/symmetric_id_token_smoke.rb +83 -0
- data/lib/rodauth/ciba/authorization_details.rb +60 -0
- data/lib/rodauth/ciba/dpop.rb +250 -0
- data/lib/rodauth/ciba/http.rb +69 -0
- data/lib/rodauth/ciba/id_token_encryption.rb +175 -0
- data/lib/rodauth/ciba/jwks_cache.rb +149 -0
- data/lib/rodauth/ciba/mtls.rb +174 -0
- data/lib/rodauth/ciba/pairwise.rb +105 -0
- data/lib/rodauth/ciba/registration.rb +489 -0
- data/lib/rodauth/ciba/schema.rb +182 -0
- data/lib/rodauth/ciba/version.rb +6 -0
- data/lib/rodauth/ciba.rb +4 -0
- data/lib/rodauth/features/ciba.rb +2185 -0
- metadata +231 -0
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
# ID Token hint validation boundary
|
|
2
|
+
|
|
3
|
+
2026-09-30. Complete node-oidc-provider 9.12.2 HTTP comparison on Node24.21.0, with an actual issued RS256 ID Token and controlled, re-signed test variants. The original comparison established the implementation contract below. An optional gem implementation now exists; see [its validation policy and remaining differences](../id-token-hint.md).
|
|
4
|
+
|
|
5
|
+
## Measured reference behavior
|
|
6
|
+
|
|
7
|
+
| Input | Result |
|
|
8
|
+
|---|---|
|
|
9
|
+
| Previously issued ID Token | Authentication request accepted with the original account; polling remains authorization_pending until new approval |
|
|
10
|
+
| Correctly signed ID Token expired one hour ago | Accepted as a hint; still needs new approval |
|
|
11
|
+
| Audience array containing the authenticated client and another value | Accepted |
|
|
12
|
+
| Correct audience but azp naming another client | Accepted: this version's helper does not validate azp |
|
|
13
|
+
| Different issuer or audience excluding the current client | invalid_request |
|
|
14
|
+
| Missing subject or future nbf | invalid_request |
|
|
15
|
+
| Modified signature | invalid_request |
|
|
16
|
+
|
|
17
|
+
[Harness](../../test/reference/full-op/lifecycle.mjs), [execution log](../validation/node-full-op-lts.txt). Existing hint-token, resource, claims, RAR and lifecycle scenarios still pass. These tests use one public-subject/RSA configuration; they do not establish HMAC, key rotation, encrypted-hint or pairwise-subject support.
|
|
18
|
+
|
|
19
|
+
`lib/models/id_token.js#validate` chooses the client's configured ID Token signing algorithm, uses the client's symmetric keystore for HS algorithms or the OP keystore otherwise, and verifies the signature, OP issuer, current client audience and string subject while ignoring expiration. `lib/actions/authorization/ciba.js` then resolves the subject as an account and performs the normal new CIBA flow. `lib/helpers/jwt.js#verifyAudience` checks audience membership but does not use the extra ignoreAzp argument passed by its caller. Record that fact rather than assuming azp is checked from the argument name.
|
|
20
|
+
|
|
21
|
+
[CIBA Core §14](https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#SecurityConsiderations) distinguishes a returned ID Token hint from ordinary token use: it discusses accepting expired ID Tokens for a reasonable period while checking issuer, client audience and signature, subject to key retention. This does not make an old ID Token a fresh authentication/authorization result. An implementation needs an explicit hint-validation policy, not globally relaxed access-token verification.
|
|
22
|
+
|
|
23
|
+
## Upstream integration finding
|
|
24
|
+
|
|
25
|
+
In the installed rodauth-oauth 1.7.0 ruby-jwt path, `jwt_decode(..., verify_claims: false)` is insufficient to accept expired hints. A local probe signed two otherwise identical tokens with the fixture OP key, one expiring in 60 seconds and one expired one hour ago. The former returned claims and the latter nil. `verify_claims: false` supplies an empty options hash to JWT.decode; ruby-jwt's expiration default still applies. RP-initiated logout uses this method too, but that usage is not evidence of the required CIBA hint semantics.
|
|
26
|
+
|
|
27
|
+
Do not change the OP-wide decoder to accept expired tokens. Use a dedicated validation path with explicit signature, algorithm and claim rules and an explicit expiration policy for this parameter only. Do not reuse the backchannel client-authentication assertion ledger: an ID Token hint is not a client assertion and is not a one-use authorization grant.
|
|
28
|
+
|
|
29
|
+
## Required gem work
|
|
30
|
+
|
|
31
|
+
1. Add an opt-in capability while preserving default login_hint and optional login_hint_token. Require exactly one hint; do not store raw ID Tokens in request snapshots/events.
|
|
32
|
+
2. Pin validation to the authenticated client's configured ID Token signing algorithm and trusted OP verification keys (or the correct client symmetric secret for HMAC). Define retained-key/kid behavior. Never select verification keys from untrusted token URLs or silently verify without a key.
|
|
33
|
+
3. Validate the OP issuer, current client audience membership, subject shape and applicable time claims explicitly. Specify how old an expired hint may be and how retained keys limit acceptance. Decide and test azp semantics rather than mechanically copying the reference's omission.
|
|
34
|
+
4. Map the validated public subject to an eligible local account through a documented boundary; custom subject encodings cannot be assumed to be account primary keys. Pairwise remains outside the current profile unless its mapping is separately implemented.
|
|
35
|
+
5. Preserve new customer approval, saved-grant account/client binding, request expiry and one-time result consumption. Poll parameters must not replace the selected subject. A successful hint check alone issues no tokens.
|
|
36
|
+
6. Test current/expired hints, wrong issuer/client/key/algorithm, malformed/empty subject, future nbf/iat, multiple hints, unknown/closed accounts, stale signing keys and ordinary access-token expiration regression. Include reference and installed-gem evidence before advertisement.
|
|
37
|
+
|
|
38
|
+
The dedicated verifier, HMAC key-source adaptation, retained-key selection and optional maximum age are now implemented and covered by gem integration tests. Pairwise subjects have a separate opt-in implementation and application resolver tests in `test/ciba_pairwise_test.rb`. The requirements above remain review criteria; local passing tests do not establish all node configurations or algorithms.
|
|
39
|
+
|
|
40
|
+
## Encrypted hint boundary: correction after direct measurement
|
|
41
|
+
|
|
42
|
+
The earlier status treated encrypted hints as a presumed missing parity feature.
|
|
43
|
+
The pinned reference implementation does not decrypt them: `IdToken.validate`
|
|
44
|
+
calls the JWS verifier directly, including in the CIBA route. The presence of
|
|
45
|
+
generic JWT decryption helpers or encrypted ID Token issuance does not establish
|
|
46
|
+
encrypted-hint acceptance.
|
|
47
|
+
|
|
48
|
+
The full HTTP harness now enables node's encryption feature and configures a
|
|
49
|
+
private OP encryption key. It wraps an actual issued RS256 ID Token in a valid
|
|
50
|
+
RSA-OAEP-256/A256GCM JWE with `cty: JWT`, and independently decrypts the envelope
|
|
51
|
+
to verify the fixture. Supplying it as `id_token_hint` returns HTTP400
|
|
52
|
+
`invalid_request` before device dispatch. Its inner signed token is accepted as
|
|
53
|
+
a hint requiring new approval. The complete lifecycle harness still passes.
|
|
54
|
+
[Reference log](../validation/node-encrypted-hint-reference.txt).
|
|
55
|
+
|
|
56
|
+
The gem test similarly constructs and authenticates a real nested JWE using
|
|
57
|
+
OpenSSL, configures an OP encryption key, and checks rejection before subject
|
|
58
|
+
resolution or request creation. The unwrapped signed hint is accepted and stays
|
|
59
|
+
pending. All seven local hint tests pass (100 assertions).
|
|
60
|
+
[Gem log](../validation/encrypted-hint-boundary.txt).
|
|
61
|
+
|
|
62
|
+
Encrypted hints remain unsupported in both measured implementations; this is a
|
|
63
|
+
verified shared boundary, not an outstanding feature needed to match v9.12.2.
|
|
64
|
+
No production decryption code or new gem dependency was added. These tests do
|
|
65
|
+
not cover encrypted ID Token issuance, every encryption algorithm, or upstream
|
|
66
|
+
Ruby's optional JWE backend; they establish the dedicated CIBA hint boundary.
|
|
67
|
+
|
|
68
|
+
## Actual-issuance algorithm comparison
|
|
69
|
+
|
|
70
|
+
A dedicated reference HTTP fixture now issues and cryptographically verifies
|
|
71
|
+
ID Tokens for RS256/384/512, PS256/384/512, ES256/384/512, HS256/384/512,
|
|
72
|
+
Ed25519 and EdDSA. Current and expired hints create only pending requests;
|
|
73
|
+
wrong-key signatures reject. It is part of the reference npm test command.
|
|
74
|
+
[Fixture](../../test/reference/full-op/id-hint-algorithms.mjs),
|
|
75
|
+
[execution](../validation/node-id-hint-algorithms.txt).
|
|
76
|
+
|
|
77
|
+
The gem's actual-issuance matrix now covers all twelve RS/PS/ES/HS choices,
|
|
78
|
+
including independent signature/issuer/audience verification, forged-signature
|
|
79
|
+
rejection before persistence and pending state for current/expired hints.
|
|
80
|
+
[Three-DB execution](../validation/id-hint-algorithms-matrix.txt): seven tests /229
|
|
81
|
+
assertions per database. At that stage the gem used OP HMAC keys while the
|
|
82
|
+
reference used client secrets. The later correction below changes CIBA issuance
|
|
83
|
+
and hint verification together, rather than conflating those key stores.
|
|
84
|
+
|
|
85
|
+
At this comparison stage, the dedicated hint verifier accepted only those
|
|
86
|
+
twelve algorithms. The initial adapter below subsequently adds Edwards. Edwards request and authentication support does not close
|
|
87
|
+
that gap. Token issuance, published verification keys and hint verification
|
|
88
|
+
must be evaluated together before expanding the accepted hint list.
|
|
89
|
+
|
|
90
|
+
## Initial Edwards issuance and hint adapter
|
|
91
|
+
|
|
92
|
+
The CIBA extension now has a separate optional Ed25519/EdDSA ID Token key map,
|
|
93
|
+
without registering a global ruby-jwt algorithm or adding signing keys to the
|
|
94
|
+
upstream default map. It publishes public OKP keys, advertises configured ID
|
|
95
|
+
Token algorithms, signs CIBA ID Tokens and reuses the local Edwards signature
|
|
96
|
+
verifier for hints. Client assertions reuse that cryptographic helper while
|
|
97
|
+
retaining their distinct claims/time/replay policy.
|
|
98
|
+
|
|
99
|
+
Registration without configured keys rejects. Issued signatures, public-key
|
|
100
|
+
bytes, at_hash, current/expired hints, wrong key, issuer/audience/subject/nbf and
|
|
101
|
+
retained/removed keys have direct regression evidence. The reference default
|
|
102
|
+
CIBA token response omits at_hash; a proposed test requiring it failed and was
|
|
103
|
+
corrected to assert absence. Its `lib/models/id_token.js` maps Ed25519/EdDSA to
|
|
104
|
+
SHA-512 when calculating optional token hashes. The gem retains its existing
|
|
105
|
+
at_hash inclusion policy and uses that mapping.
|
|
106
|
+
|
|
107
|
+
[Three-DB regression](../validation/edwards-id-token-matrix.txt),
|
|
108
|
+
[final rollback cases](../validation/edwards-id-token-final-matrix.txt).
|
|
109
|
+
This is an initial runtime implementation, not complete interoperability or
|
|
110
|
+
encrypted-token support. An encryption request fails closed rather than silently
|
|
111
|
+
returning a signed plaintext token. Broader integration evidence is recorded
|
|
112
|
+
below; encrypted ID Token issuance remains unsupported.
|
|
113
|
+
|
|
114
|
+
## Independent Edwards verification of the installed gem
|
|
115
|
+
|
|
116
|
+
`examples/edwards_id_token_smoke.rb` now runs from `bin/verify-package`, issuing
|
|
117
|
+
both algorithm names with opaque and JWT access tokens. Its optional
|
|
118
|
+
`CIBA_EDWARDS_ID_TOKEN_EXPORT` absolute path exports synthetic tokens and public
|
|
119
|
+
JWKS only. The keys are ephemeral and private key material is never exported.
|
|
120
|
+
`test/reference/full-op/verify-gem-edwards-id-tokens.mjs` independently verifies
|
|
121
|
+
all four cases using Node jose: signature, fixed expected issuer/audience/subject,
|
|
122
|
+
JWK thumbprint, SHA-512 at_hash, tampered payload rejection and wrong audience
|
|
123
|
+
rejection. A saved public fixture supports repeatable offline execution; its
|
|
124
|
+
recorded issuance-check time is used, not a claim of current token validity.
|
|
125
|
+
|
|
126
|
+
Reproduce fresh evidence by setting the export path to
|
|
127
|
+
`test/reference/full-op/fixtures/gem-edwards-id-tokens.json` (absolute) when
|
|
128
|
+
running `mise exec ruby -- ruby bin/verify-package`, then run
|
|
129
|
+
`node verify-gem-edwards-id-tokens.mjs` from `test/reference/full-op` with its
|
|
130
|
+
installed jose dependency. The default fixture is explicit historical evidence;
|
|
131
|
+
regenerate it to verify a changed Ruby implementation.
|
|
132
|
+
|
|
133
|
+
[Installed package execution](../validation/edwards-id-token-installed.txt)
|
|
134
|
+
and [independent jose execution](../validation/edwards-id-token-jose.txt) passed.
|
|
135
|
+
This does not establish encrypted ID Token interoperability.
|
|
136
|
+
|
|
137
|
+
## Edwards refresh and pairwise integration
|
|
138
|
+
|
|
139
|
+
`test_edwards_id_token_refresh_public_subject` and
|
|
140
|
+
`test_edwards_id_token_refresh_pairwise_subject` exercise both Ed25519/EdDSA
|
|
141
|
+
with opaque/JWT access tokens. They verify the actual initial and refreshed
|
|
142
|
+
signatures, stable expected subject, audience, authentication time/method,
|
|
143
|
+
at_hash, UserInfo subject, active signing key replacement with old public key
|
|
144
|
+
retention, refresh rotation/replay rejection and signing-failure rollback.
|
|
145
|
+
Pairwise authentication uses the existing private_key_jwt path; these tests do
|
|
146
|
+
not replace the separate key transport coverage or assert every authentication
|
|
147
|
+
combination. They add integration evidence for the gem, not a new measured
|
|
148
|
+
comparison of these combinations in node-oidc-provider.
|
|
149
|
+
|
|
150
|
+
[Three-DB execution](../validation/edwards-id-token-refresh-matrix.txt) passes
|
|
151
|
+
five Edwards ID Token tests /311 assertions on each of SQLite, PostgreSQL and
|
|
152
|
+
MySQL, including these two new integration cases. The independent jose test
|
|
153
|
+
above covers initial issuance, not these refreshed tokens.
|
|
154
|
+
|
|
155
|
+
[Supported Ruby execution](../validation/edwards-id-token-rubies.txt) passes
|
|
156
|
+
the complete current suite on Ruby 3.3 and 3.4: 341 tests /4,774 assertions each,
|
|
157
|
+
zero failures/errors and two SQLite row-lock skips. This does not cover every
|
|
158
|
+
Ruby/database cross-product; the three-DB Edwards matrix uses Ruby 4.0.6.
|
|
159
|
+
|
|
160
|
+
## Encrypted output: measured gap and plaintext fallback correction
|
|
161
|
+
|
|
162
|
+
The reference `encrypted-id-tokens.mjs` now performs actual CIBA issuance and
|
|
163
|
+
refresh for RS256, Ed25519 and EdDSA clients using RSA-OAEP-256/A256GCM recipient
|
|
164
|
+
encryption. jose decrypts the compact JWE, checks cty/kid and verifies the inner
|
|
165
|
+
signature, issuer, audience and subject. [Execution](../validation/node-encrypted-id-tokens.txt)
|
|
166
|
+
passes all three algorithms. Encrypted output is supported by the reference;
|
|
167
|
+
the separately measured rejection of encrypted *input hints* does not remove
|
|
168
|
+
this output requirement.
|
|
169
|
+
|
|
170
|
+
Inspection of rodauth-oauth 1.7.0 `oauth_jwt_base.rb` found that the installed
|
|
171
|
+
ruby-jwt backend ignores encryption options when optional JWE support is absent.
|
|
172
|
+
Its optional JWE path can also return the signed token when no recipient key
|
|
173
|
+
matches. The gem previously guarded only the new Edwards branch, so configured
|
|
174
|
+
RSA CIBA clients could receive plaintext despite requesting encryption.
|
|
175
|
+
[Regression before correction](../validation/id-token-encryption-fallback-red.txt)
|
|
176
|
+
reproduces the unexpected 200 response with a signed three-segment ID Token.
|
|
177
|
+
|
|
178
|
+
The CIBA wrapper now requires a five-segment result with the requested alg/enc
|
|
179
|
+
when encrypted ID Token output is configured. Otherwise it raises a configuration
|
|
180
|
+
error inside the existing issuance transaction; no token is returned and the
|
|
181
|
+
request remains approved. The guard is limited to CIBA ID Token encoding and
|
|
182
|
+
does not change unrelated OAuth encoding. Complete and incomplete encryption
|
|
183
|
+
metadata are tested, followed by successful signed issuance after removing that
|
|
184
|
+
configuration. This guard is not an encryption implementation or cryptographic
|
|
185
|
+
verification of a JWE backend. Actual encrypted output, recipient-key selection,
|
|
186
|
+
metadata defaults and independent decryption remain implementation work.
|
|
187
|
+
|
|
188
|
+
[Final regression matrix](../validation/id-token-encryption-fallback-matrix.txt)
|
|
189
|
+
passes seven tests /350 assertions on each of SQLite, PostgreSQL and MySQL,
|
|
190
|
+
including Edwards issuance/refresh/pairwise and existing refresh rollback.
|
|
191
|
+
|
|
192
|
+
The subsequent optional [recipient encryption implementation](../id-token-encryption.md)
|
|
193
|
+
now supplies an initial successful encrypted-output path using jwe 1.1.1.
|
|
194
|
+
The earlier fallback correction remains for disabled/unsupported configurations.
|
|
195
|
+
It covers RSA-OAEP/RSA-OAEP-256 recipient encryption, six AES content methods,
|
|
196
|
+
Edwards/RSA signatures, initial issuance and refresh. DCR and Discovery apply
|
|
197
|
+
only these CIBA ID Token capabilities without widening unrelated algorithms.
|
|
198
|
+
[Three-DB evidence](../validation/id-token-recipient-encryption-matrix.txt):
|
|
199
|
+
nine tests /1,043 assertions each. [Full local regression](../validation/id-token-recipient-encryption-full.txt):
|
|
200
|
+
345 tests /5,506 assertions, two SQLite row-lock skips.
|
|
201
|
+
[Independent jose decryption](../validation/id-token-recipient-encryption-jose.txt)
|
|
202
|
+
checks 72 issued/refreshed tokens and ciphertext tampering. This does not close
|
|
203
|
+
the broader encryption capability and deployment combinations listed in the
|
|
204
|
+
feature document.
|
|
205
|
+
|
|
206
|
+
The encryption key-selection review subsequently found a concrete difference:
|
|
207
|
+
the gem selected the first eligible key, while the reference ranks matching
|
|
208
|
+
alg/use metadata higher. The correction preserves input order on ties and is
|
|
209
|
+
checked by actual issuance with two different recipient keys.
|
|
210
|
+
[Three-DB regression](../validation/id-token-recipient-priority-matrix.txt)
|
|
211
|
+
passes ten tests /1,047 assertions per database. The final source passes
|
|
212
|
+
[Ruby 3.3/3.4](../validation/id-token-encryption-rubies.txt), 346 tests /5,510
|
|
213
|
+
assertions each (two SQLite row-lock skips), and
|
|
214
|
+
[installed package encryption](../validation/id-token-encryption-installed.txt)
|
|
215
|
+
for initial issuance/refresh with RS256/Ed25519/EdDSA and opaque/JWT access tokens.
|
|
216
|
+
The package probe uses inline keys; it does not establish remote recipient-key
|
|
217
|
+
retrieval or rotation.
|
|
218
|
+
|
|
219
|
+
## Initial client-secret HMAC alignment
|
|
220
|
+
|
|
221
|
+
CIBA HMAC ID Token issuance and hints now use the client secret, matching
|
|
222
|
+
OIDC Core 3.1.3.7 and the measured reference. Verified Basic/POST secrets can be
|
|
223
|
+
reused within the authenticated request even when stored as hashes. An explicit
|
|
224
|
+
`ciba_id_token_hmac_secret(oauth_application:)` callback supports other methods
|
|
225
|
+
with application-managed original secrets. No OP-key fallback is performed;
|
|
226
|
+
non-CIBA JWT and access-token encoding retain their upstream key sources.
|
|
227
|
+
[Contract and migration boundary](../id-token-hint.md#hmac-client-secret-ownership).
|
|
228
|
+
|
|
229
|
+
[Three-DB regression](../validation/hmac-id-token-matrix.txt) passes nine tests
|
|
230
|
+
/421 assertions each; [full local regression](../validation/hmac-id-token-full.txt)
|
|
231
|
+
passes353 tests /5,829 assertions with two SQLite skips. Independent
|
|
232
|
+
[Node jose verification](../validation/hmac-id-token-jose.txt) verifies24 actual
|
|
233
|
+
gem ID Tokens across three algorithms, Basic/POST, hashed/plaintext storage,
|
|
234
|
+
initial issuance/refresh, rejects the OP key and checks at_hash. Its public
|
|
235
|
+
synthetic fixture records verification time for reproducibility and uses only
|
|
236
|
+
fixed test secrets. Subsequent [installed-artifact validation](../validation/hmac-id-token-installed.txt) covers12 HMAC configurations and backend secret replacement. [Ruby3.3/3.4](../validation/hmac-id-token-rubies.txt) each pass354 tests/5,847 assertions with two SQLite skips. DCR now generates sufficiently long secrets for each HMAC algorithm; the updated [three-DB subset](../validation/hmac-registration-secret-matrix.txt) passes10 tests/439 assertions each. This closes the catalog signature-verification boundary, without claiming every deployment rotation policy or a standard secret-rotation API.
|
|
237
|
+
|
|
238
|
+
## Hint validation profile alignment
|
|
239
|
+
|
|
240
|
+
The previous azp/typ/required-integer-time restrictions are removed from the
|
|
241
|
+
hint path. The new [reference execution](../validation/node-id-hint-validation-profile.txt)
|
|
242
|
+
accepts fractional times, optional iat/exp, future iat when exp is present,
|
|
243
|
+
non-numeric ignored exp, another azp, an at+jwt typ and the known b64=true
|
|
244
|
+
critical declaration. Missing issuer/audience/subject, wrong signatures,
|
|
245
|
+
future nbf, nonnumeric iat/nbf and non-string jti remain rejected. The gem follows
|
|
246
|
+
these measured boundaries; finite numeric checks remain for evaluated dates.
|
|
247
|
+
An empty string subject is passed to the application resolver rather than being
|
|
248
|
+
inherently interpreted as a database ID. Application age limits require iat.
|
|
249
|
+
|
|
250
|
+
Every accepted test hint remains pending without inherited approval. RSA and
|
|
251
|
+
Edwards paths are covered; client-assertion and signed-request critical-header
|
|
252
|
+
policy is unchanged. [Ruby3.4 three-DB regression](../validation/id-hint-validation-matrix.txt)
|
|
253
|
+
passes31 tests /983 assertions on each database. The initial local broad filter
|
|
254
|
+
hit four sandbox listener errors; that log is not a passing run.
|