webauthn 3.4.3 → 3.5.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7c4eaef5219f441b2725eecd8a9684b8da36ff9427ac53c7e3feb757fb885a1d
4
- data.tar.gz: 270c8420d39784d301f6978ab0cdbc027afbd2547734781675bea1e170e2ef37
3
+ metadata.gz: a20be10512baef48a31bf98b85727c8819a9b7c995400bad6282648e2120695e
4
+ data.tar.gz: b84352d26add2af3477070c91ef5707134882f99810216d89f09f9c81e1ef909
5
5
  SHA512:
6
- metadata.gz: 9dbe89a7969b1652dacea548169ebd63a87c96e0045dbb6a92970ca09d363c424fad0a9c4bf212512568befb56e0d32fe2b7a49d38eca01e27a9a5947fa80a45
7
- data.tar.gz: 7753da597253ad6919471447288a4da3aab9d7de6f02c1b06ad5b5542a65a34892ad99f83f81f063ffb378156c66a17af5372c98ed76f837de15337b6b9594c7
6
+ metadata.gz: cf7e5872c96bcca1af15245515fa9de6fc89d677e1bf85a0dbced0768e820dddbf7d74d0a1b95b369b1bbe89dcad1cbef453d904d295e1e3ca25326f4b159bce
7
+ data.tar.gz: 58d19414843c25daf60199ed74e3acbc3285d61bc9a66cc6017e41de69de5f70d08c5fe37761c8cea80ad6afbf4e63dc9c7f493584d7436b2c05cf7ade0f5352
@@ -0,0 +1 @@
1
+ github: [cedarcode]
@@ -29,16 +29,12 @@ runs:
29
29
  ./Configure --prefix=$HOME/openssl --libdir=lib linux-x86_64
30
30
  make depend && make -j4 && make install_sw
31
31
  ;;
32
- 3.*)
32
+ 3.* | 4.*)
33
33
  OPENSSL_COMMIT=openssl-
34
34
  OPENSSL_COMMIT+=$(echo ${{ inputs.version }})
35
35
  git clone -b $OPENSSL_COMMIT --depth 1 https://github.com/openssl/openssl.git .
36
36
  echo "Git commit: $(git rev-parse HEAD)"
37
- if [[ ${{ inputs.version }} == 3.5* ]]; then
38
- ./Configure --prefix=$HOME/openssl --libdir=lib enable-fips no-tests no-legacy
39
- else
40
- ./Configure --prefix=$HOME/openssl --libdir=lib enable-fips no-tests
41
- fi
37
+ ./Configure --prefix=$HOME/openssl --libdir=lib enable-fips no-tests
42
38
  make -j4 && make install_sw && make install_fips
43
39
  ;;
44
40
  *)
@@ -21,18 +21,30 @@ jobs:
21
21
  fail-fast: false
22
22
  matrix:
23
23
  ruby:
24
+ - '4.0'
24
25
  - '3.4'
25
26
  - '3.3'
26
27
  - '3.2'
27
28
  - '3.1'
28
29
  openssl:
29
- - '3.5.3'
30
- - '3.4.2'
31
- - '3.3.4'
32
- - '3.2.5'
30
+ - '4.0.0'
31
+ - '3.6.0'
32
+ - '3.5.4'
33
+ - '3.4.3'
34
+ - '3.3.5'
35
+ - '3.2.6'
33
36
  - '3.1.8'
34
- - '3.0.17'
37
+ - '3.0.18'
35
38
  - '1.1.1w'
39
+ exclude:
40
+ # Ruby 3.1-3.3 bundle an `openssl` gem too old for OpenSSL 4.0.
41
+ # Re-enable once upstream ships patch releases that bump it.
42
+ - ruby: '3.3'
43
+ openssl: '4.0.0'
44
+ - ruby: '3.2'
45
+ openssl: '4.0.0'
46
+ - ruby: '3.1'
47
+ openssl: '4.0.0'
36
48
  include:
37
49
  - ruby: truffleruby
38
50
  - ruby: '3.0'
@@ -45,7 +57,7 @@ jobs:
45
57
  openssl: '1.1.1w'
46
58
 
47
59
  steps:
48
- - uses: actions/checkout@v5
60
+ - uses: actions/checkout@v7
49
61
 
50
62
  - name: Install OpenSSL
51
63
  if: matrix.ruby != 'truffleruby'
@@ -68,13 +80,11 @@ jobs:
68
80
  bundler-cache: true
69
81
 
70
82
  - run: bundle exec rspec
71
- env:
72
- RUBYOPT: ${{ startsWith(matrix.ruby, '3.4') && '--enable=frozen-string-literal' || '' }}
73
83
 
74
84
  lint:
75
85
  runs-on: ubuntu-latest
76
86
  steps:
77
- - uses: actions/checkout@v5
87
+ - uses: actions/checkout@v7
78
88
  - uses: ruby/setup-ruby@v1
79
89
  with:
80
90
  ruby-version: '3.3'
@@ -14,7 +14,7 @@ jobs:
14
14
  runs-on: ubuntu-latest
15
15
 
16
16
  steps:
17
- - uses: actions/checkout@v5
17
+ - uses: actions/checkout@v7
18
18
  - name: Block autosquash commits
19
19
  uses: xt0rted/block-autosquash-commits-action@v2
20
20
  with:
@@ -0,0 +1,29 @@
1
+ name: Release
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ jobs:
8
+ release:
9
+ name: Publish to Rubygems
10
+
11
+ runs-on: ubuntu-latest
12
+
13
+ environment: release
14
+
15
+ permissions:
16
+ contents: write
17
+ id-token: write
18
+
19
+ steps:
20
+ - uses: actions/checkout@v7
21
+
22
+ - name: Setup Ruby
23
+ uses: ruby/setup-ruby@v1
24
+ with:
25
+ bundler-cache: true
26
+ ruby-version: ruby
27
+
28
+ - name: Publish to RubyGems
29
+ uses: rubygems/release-gem@v1
data/CHANGELOG.md CHANGED
@@ -1,47 +1,71 @@
1
1
  # Changelog
2
2
 
3
- ## Unreleased
3
+ ## [Unreleased](https://github.com/cedarcode/webauthn-ruby/compare/v3.4.3...master/)
4
4
 
5
- ## [v3.4.3] - 2025-10-23
5
+ ## [v3.5.0](https://github.com/cedarcode/webauthn-ruby/compare/v3.4.3...v3.5.0/)
6
+
7
+ ### Added
8
+
9
+ - Add support for crossOrigin/topOrigin verification during credential registration and authentication. [#486](https://github.com/cedarcode/webauthn-ruby/pull/486) [@nicolastemciuc]
10
+ - Add support for the `attestation_formats` option in `WebAuthn::Credential.options_for_create`. [#514](https://github.com/cedarcode/webauthn-ruby/pull/514) [@santiagorodriguez96]
11
+ - Add support for the `hints` option in `WebAuthn::Credential.options_for_create` and `WebAuthn::Credential.options_for_get`. [#513](https://github.com/cedarcode/webauthn-ruby/pull/513) [@santiagorodriguez96]
12
+ - Reject authenticator data where the BS (backup state) flag is set but the BE (backup eligibility) flag is not, during credential registration and authentication. Raises `WebAuthn::BackupFlagsVerificationError`. [#516](https://github.com/cedarcode/webauthn-ruby/pull/516) [@santiagorodriguez96]
13
+ - Reject credential IDs longer than 1023 bytes during credential registration. Raises `WebAuthn::CredentialIdLengthVerificationError`. [#517](https://github.com/cedarcode/webauthn-ruby/pull/517) [@santiagorodriguez96]
14
+ - Add `WebAuthn.generate_user_handle` as an alias for `generate_user_id`. [#503](https://github.com/cedarcode/webauthn-ruby/pull/503) [@ttanimichi]
15
+
16
+ ### Changed
17
+
18
+ - Bump the default `credential_options_timeout` from `120_000` to `300_000` milliseconds (5 minutes). [#515](https://github.com/cedarcode/webauthn-ruby/pull/515) [@santiagorodriguez96]
19
+ - `WebAuthn::FakeClient#get` now defaults `backup_state` to `false`. The previous default (`backup_eligibility: false`, `backup_state: true`) produced authenticator data that now fails verification. [#516](https://github.com/cedarcode/webauthn-ruby/pull/516) [@santiagorodriguez96]
20
+ - Avoid mutating caller relying-party options. [#509](https://github.com/cedarcode/webauthn-ruby/pull/509) [@OskarEichler]
21
+
22
+ ### Removed
23
+
24
+ - Remove `TokenBinding` verification during credential registration and authentication. [#450](https://github.com/cedarcode/webauthn-ruby/pull/450) [@nicolastemciuc]
25
+ - BREAKING CHANGE: `WebAuthn::TokenBindingVerificationError` no longer exists. Remove it from any `rescue` clauses.
26
+ - BREAKING CHANGE: `WebAuthn::FakeClient.new` no longer accepts `token_binding:`.
27
+ - BREAKING CHANGE: `WebAuthn::ClientData` no longer exposes `#token_binding` or `#valid_token_binding_format?`.
28
+
29
+ ## [v3.4.3](https://github.com/cedarcode/webauthn-ruby/compare/v3.4.2...v3.4.3/) - 2025-10-23
6
30
 
7
31
  ### Fixed
8
32
 
9
- - Fix `RelyingParty#origin` and `WebAuthn.configuration.origin` always returning `nil`. [#484](https://github.com/cedarcode/webauthn-ruby/pull/484)[@santiagorodriguez96]
33
+ - Fix `RelyingParty#origin` and `WebAuthn.configuration.origin` always returning `nil`. [#484](https://github.com/cedarcode/webauthn-ruby/pull/484) [@santiagorodriguez96]
10
34
  - Now they return the allowed origin if allowed origins has only one element.
11
35
 
12
- ## [v3.4.2] - 2025-09-22
36
+ ## [v3.4.2](https://github.com/cedarcode/webauthn-ruby/compare/v3.4.1...v3.4.2/) - 2025-09-22
13
37
 
14
38
  ### Added
15
39
 
16
40
  - Updated `safety_net_attestation` dependency from `~> 0.4.0` to `~> 0.5.0`.
17
41
 
18
- ## [v3.4.1] - 2025-06-06
42
+ ## [v3.4.1](https://github.com/cedarcode/webauthn-ruby/compare/v3.4.0...v3.4.1/) - 2025-06-06
19
43
 
20
- - Avoid requiring `base64` as it's not a direct dependency. [#459](https://github.com/cedarcode/webauthn-ruby/pull/459)[@santiagorodriguez96]
44
+ - Avoid requiring `base64` as it's not a direct dependency. [#459](https://github.com/cedarcode/webauthn-ruby/pull/459) [@santiagorodriguez96]
21
45
 
22
- ## [v3.4.0] - 2025-02-17
46
+ ## [v3.4.0](https://github.com/cedarcode/webauthn-ruby/compare/v3.3.0...v3.4.0/) - 2025-02-17
23
47
 
24
- - Added support for Webauthn.config and RelayingParty to accept multiple allowed_origins. [#431](https://github.com/cedarcode/webauthn-ruby/pull/431)[@obroshnij]
48
+ - Added support for Webauthn.config and RelayingParty to accept multiple allowed_origins. [#431](https://github.com/cedarcode/webauthn-ruby/pull/431) [@obroshnij]
25
49
 
26
- ## [v3.3.0] - 2025-02-06
50
+ ## [v3.3.0](https://github.com/cedarcode/webauthn-ruby/compare/v3.2.2...v3.3.0/) - 2025-02-06
27
51
 
28
52
  ### Added
29
53
 
30
54
  - Updated `tpm-key_attestation` dependency from `~> 0.12.0` to `~> 0.14.0`. [#449](https://github.com/cedarcode/webauthn-ruby/pull/449) [@brauliomartinezlm], [@nicolastemciuc]
31
55
 
32
- ## [v3.2.2] - 2024-11-14
56
+ ## [v3.2.2](https://github.com/cedarcode/webauthn-ruby/compare/v3.2.1...v3.2.2/) - 2024-11-14
33
57
 
34
58
  ### Fixed
35
59
 
36
60
  - Fix `PublicKeyCredential::Options#.as_json` not camelCase'ing keys of attributes with hash or arrays as values. [#445](https://github.com/cedarcode/webauthn-ruby/pull/445) [@santiagorodriguez96]
37
61
 
38
- ## [v3.2.1] - 2024-11-14
62
+ ## [v3.2.1](https://github.com/cedarcode/webauthn-ruby/compare/v3.2.0...v3.2.1/) - 2024-11-14
39
63
 
40
64
  ### Fixed
41
65
 
42
- - Fix JSON Serializer generating json with attributes with a null value. [#442](https://github.com/cedarcode/webauthn-ruby/pull/442) @santiagorodriguez96
66
+ - Fix JSON Serializer generating json with attributes with a null value. [#442](https://github.com/cedarcode/webauthn-ruby/pull/442) [@santiagorodriguez96]
43
67
 
44
- ## [v3.2.0] - 2024-11-13
68
+ ## [v3.2.0](https://github.com/cedarcode/webauthn-ruby/compare/v3.1.0...v3.2.0/) - 2024-11-13
45
69
 
46
70
  ### Added
47
71
 
@@ -62,31 +86,31 @@
62
86
 
63
87
  - Remove unused class `AttestationTrustworthinessVerificationError`. [#412](https://github.com/cedarcode/webauthn-ruby/pull/412) [@soartec-lab]
64
88
 
65
- ## [v3.1.0] - 2023-12-26
89
+ ## [v3.1.0](https://github.com/cedarcode/webauthn-ruby/compare/v3.0.0...v3.1.0/) - 2023-12-26
66
90
 
67
91
  ### Added
68
92
 
69
- - Add support for optional `authenticator_attachment` in `PublicKeyCredential`. #370 [@8ma10s]
93
+ - Add support for optional `authenticator_attachment` in `PublicKeyCredential`. [#370](https://github.com/cedarcode/webauthn-ruby/pull/370) [@8ma10s]
70
94
 
71
95
  ### Fixed
72
96
 
73
- - Fix circular require warning between `webauthn/relying_party` and `webauthn/credential`. #389 [@bdewater]
74
- - Correctly verify attestation that contains just a batch certificate that is present in the attestation root certificates. #406 [@santiagorodriguez96]
97
+ - Fix circular require warning between `webauthn/relying_party` and `webauthn/credential`. [#389](https://github.com/cedarcode/webauthn-ruby/pull/389) [@bdewater]
98
+ - Correctly verify attestation that contains just a batch certificate that is present in the attestation root certificates. [#406](https://github.com/cedarcode/webauthn-ruby/pull/406) [@santiagorodriguez96]
75
99
 
76
100
  ### Changed
77
101
 
78
- - Inlined `base64` implementation. #402 [@olleolleolle]
79
- - Raise a more descriptive error if input `challenge` is `nil` when verifying the `PublicKeyCredential`. #413 [@soartec-lab]
102
+ - Inlined `base64` implementation. [#402](https://github.com/cedarcode/webauthn-ruby/pull/402) [@olleolleolle]
103
+ - Raise a more descriptive error if input `challenge` is `nil` when verifying the `PublicKeyCredential`. [#413](https://github.com/cedarcode/webauthn-ruby/pull/413) [@soartec-lab]
80
104
 
81
105
  ## [v3.0.0] - 2023-02-15
82
106
 
83
107
  ### Added
84
108
 
85
- - Add the capability of handling appid extension #319 [@santiagorodriguez96]
86
- - Add support for credential backup flags #378 [@santiagorodriguez96]
109
+ - Add the capability of handling appid extension [#319](https://github.com/cedarcode/webauthn-ruby/pull/319) [@santiagorodriguez96]
110
+ - Add support for credential backup flags [#378](https://github.com/cedarcode/webauthn-ruby/pull/378) [@santiagorodriguez96]
87
111
  - Update dependencies to make gem compatible with OpenSSL 3.1 ([@bdewater],[@santiagorodriguez96])
88
112
 
89
- ## [v3.0.0.alpha2] - 2022-09-12
113
+ ## [v3.0.0.alpha2](https://github.com/cedarcode/webauthn-ruby/compare/2-stable...v3.0.0.alpha2/) - 2022-09-12
90
114
 
91
115
  ### Added
92
116
 
@@ -96,19 +120,19 @@
96
120
 
97
121
  - Bumped minimum required Ruby version to 2.5 ([@bdewater])
98
122
 
99
- ## [v3.0.0.alpha1] - 2020-06-27
123
+ ## [v3.0.0.alpha1](https://github.com/cedarcode/webauthn-ruby/compare/v2.3.0...v3.0.0.alpha1) - 2020-06-27
100
124
 
101
125
  ### Added
102
126
 
103
127
  - Ability to define multiple relying parties with the introduction of the `WebAuthn::RelyingParty` class ([@padulafacundo], [@brauliomartinezlm])
104
128
 
105
- ## [v2.5.2] - 2022-07-13
129
+ ## [v2.5.2](https://github.com/cedarcode/webauthn-ruby/compare/v2.5.1...v2.5.2/) - 2022-07-13
106
130
 
107
131
  ### Added
108
132
 
109
133
  - Updated dependencies to make the gem compatible with openssl-3 [@ClearlyClaire]
110
134
 
111
- ## [v2.5.1] - 2022-03-20
135
+ ## [v2.5.1](https://github.com/cedarcode/webauthn-ruby/compare/v2.5.0...v2.5.1/) - 2022-03-20
112
136
 
113
137
  ### Added
114
138
 
@@ -116,9 +140,9 @@
116
140
 
117
141
  ### Removed
118
142
 
119
- - Removed dependency [secure_compare dependency] (https://rubygems.org/gems/secure_compare/versions/0.0.1) and use OpenSSL#secure_compare instead [@bdewater]
143
+ - Removed dependency [secure_compare dependency](https://rubygems.org/gems/secure_compare/versions/0.0.1) and use OpenSSL#secure_compare instead [@bdewater]
120
144
 
121
- ## [v2.5.0] - 2021-03-14
145
+ ## [v2.5.0](https://github.com/cedarcode/webauthn-ruby/compare/v2.4.1...v2.5.0/) - 2021-03-14
122
146
 
123
147
  ### Added
124
148
 
@@ -129,32 +153,32 @@
129
153
 
130
154
  - No longer accept "removed from the WebAuthn spec" options `rp: { icon: }` and `user: { icon: }` for `WebAuthn::Credential.options_for_create` method ([#326](https://github.com/cedarcode/webauthn-ruby/pull/326) / [@santiagorodriguez96])
131
155
 
132
- ## [v2.4.1] - 2021-02-15
156
+ ## [v2.4.1](https://github.com/cedarcode/webauthn-ruby/compare/v2.4.0...v2.4.1/) - 2021-02-15
133
157
 
134
158
  ### Fixed
135
159
 
136
160
  - Fix verification of new credential if no attestation provided and 'None' type is not among configured `acceptable_attestation_types`. I.e. reject it instead of letting it go through.
137
161
 
138
- ## [v2.4.0] - 2020-09-03
162
+ ## [v2.4.0](https://github.com/cedarcode/webauthn-ruby/compare/v2.3.0...v2.4.0/) - 2020-09-03
139
163
 
140
164
  ### Added
141
165
 
142
166
  - Support for ES256K credentials
143
167
  - `FakeClient#get` accepts `user_handle:` keyword argument ([@lgarron])
144
168
 
145
- ## [v2.3.0] - 2020-06-27
169
+ ## [v2.3.0](https://github.com/cedarcode/webauthn-ruby/compare/v2.2.1...v2.3.0/) - 2020-06-27
146
170
 
147
171
  ### Added
148
172
 
149
173
  - Ability to access extension outputs with `PublicKeyCredential#client_extension_outputs` and `PublicKeyCredential#authenticator_extension_outputs` ([@santiagorodriguez96])
150
174
 
151
- ## [v2.2.1] - 2020-06-06
175
+ ## [v2.2.1](https://github.com/cedarcode/webauthn-ruby/compare/v2.2.0...v2.2.1/) - 2020-06-06
152
176
 
153
177
  ### Fixed
154
178
 
155
179
  - Fixed compatibility with OpenSSL-C (libssl) v1.0.2 ([@santiagorodriguez96])
156
180
 
157
- ## [v2.2.0] - 2020-03-14
181
+ ## [v2.2.0](https://github.com/cedarcode/webauthn-ruby/compare/v2.1.0...v2.2.0/) - 2020-03-14
158
182
 
159
183
  ### Added
160
184
 
@@ -163,7 +187,7 @@
163
187
 
164
188
  Note: Expect possible breaking changes for "EXPERIMENTAL" features.
165
189
 
166
- ## [v2.1.0] - 2019-12-30
190
+ ## [v2.1.0](https://github.com/cedarcode/webauthn-ruby/compare/v2.0.0...v2.1.0/) - 2019-12-30
167
191
 
168
192
  ### Added
169
193
 
@@ -175,7 +199,7 @@ Note: Expect possible breaking changes for "EXPERIMENTAL" features.
175
199
 
176
200
  Note: Expect possible breaking changes for "EXPERIMENTAL" features.
177
201
 
178
- ## [v2.0.0] - 2019-10-03
202
+ ## [v2.0.0](https://github.com/cedarcode/webauthn-ruby/compare/v1.18.0...v2.0.0/) - 2019-10-03
179
203
 
180
204
  ### Added
181
205
 
@@ -227,7 +251,7 @@ string keys instead of snake_case symbol keys in the returned hash.
227
251
  - `WebAuthn::FakeClient#create` and `WebAuthn::FakeClient#get` better fakes a real client by not padding the
228
252
  returned base64url-encoded `id` value.
229
253
 
230
- ## [v1.18.0] - 2019-07-27
254
+ ## [v1.18.0](https://github.com/cedarcode/webauthn-ruby/compare/v1.17.0...v1.18.0/) - 2019-07-27
231
255
 
232
256
  ### Added
233
257
 
@@ -242,14 +266,14 @@ returned base64url-encoded `id` value.
242
266
  - Properly verify SafetyNet certificates from input ([#233](https://github.com/cedarcode/webauthn-ruby/pull/233)) ([@bdewater])
243
267
  - FakeClient default origin URL ([#242](https://github.com/cedarcode/webauthn-ruby/pull/242)) ([@kalebtesfay])
244
268
 
245
- ## [v1.17.0] - 2019-06-18
269
+ ## [v1.17.0](https://github.com/cedarcode/webauthn-ruby/compare/v1.16.0...v1.17.0/) - 2019-06-18
246
270
 
247
271
  ### Added
248
272
 
249
273
  - Support ES384, ES512, PS384, PS512, RS384 and RS512 credentials. Off by default. Enable by adding any of them to `WebAuthn.configuration.algorithms` array ([@bdewater])
250
274
  - Support [Signature Counter](https://www.w3.org/TR/webauthn/#signature-counter) verification ([@bdewater])
251
275
 
252
- ## [v1.16.0] - 2019-06-13
276
+ ## [v1.16.0](https://github.com/cedarcode/webauthn-ruby/compare/v1.15.0...v1.16.0/) - 2019-06-13
253
277
 
254
278
  ### Added
255
279
 
@@ -257,20 +281,20 @@ returned base64url-encoded `id` value.
257
281
  - Support RS1 (RSA w/ SHA-1) credentials. Off by default. Enable by adding `"RS1"` to `WebAuthn.configuration.algorithms` array.
258
282
  - Support PS256 (RSA Probabilistic Signature Scheme w/ SHA-256) credentials. On by default ([@bdewater])
259
283
 
260
- ## [v1.15.0] - 2019-05-16
284
+ ## [v1.15.0](https://github.com/cedarcode/webauthn-ruby/compare/v1.14.0...v1.15.0/) - 2019-05-16
261
285
 
262
286
  ### Added
263
287
 
264
288
  - Ability to configure Origin, RP ID and RP Name via `WebAuthn.configure`
265
289
 
266
- ## [v1.14.0] - 2019-04-25
290
+ ## [v1.14.0](https://github.com/cedarcode/webauthn-ruby/compare/v1.13.0...v1.14.0/) - 2019-04-25
267
291
 
268
292
  ### Added
269
293
 
270
294
  - Support 'tpm' attestation statement
271
295
  - Support RS256 credential public key
272
296
 
273
- ## [v1.13.0] - 2019-04-09
297
+ ## [v1.13.0](https://github.com/cedarcode/webauthn-ruby/compare/v1.12.0...v1.13.0/) - 2019-04-09
274
298
 
275
299
  ### Added
276
300
 
@@ -283,7 +307,7 @@ returned base64url-encoded `id` value.
283
307
  - Verify collectedClientData.tokenBinding format.
284
308
  - `WebAuthn.credential_creation_options` now accept `rp_name`, `user_id`, `user_name` and `display_name` as keyword arguments ([@bdewater])
285
309
 
286
- ## [v1.12.0] - 2019-04-03
310
+ ## [v1.12.0](https://github.com/cedarcode/webauthn-ruby/compare/v1.11.0...v1.12.0/) - 2019-04-03
287
311
 
288
312
  ### Added
289
313
 
@@ -299,7 +323,7 @@ Note #1: A `Credential` instance is what is returned in `WebAuthn::Authenticator
299
323
  Note #2: You don't need to do any convesion before passing the public key in `AuthenticatorAssertionResponse#verify`'s
300
324
  `allowed_credentials` argument, `#verify` is backwards-compatible and will handle both public key formats properly.
301
325
 
302
- ## [v1.11.0] - 2019-03-15
326
+ ## [v1.11.0](https://github.com/cedarcode/webauthn-ruby/compare/v1.10.0...v1.11.0/) - 2019-03-15
303
327
 
304
328
  ### Added
305
329
 
@@ -309,19 +333,19 @@ Note #2: You don't need to do any convesion before passing the public key in `Au
309
333
 
310
334
  - Verify matching AAGUID if needed when verifying `packed` attestation statements ([@bdewater])
311
335
 
312
- ## [v1.10.0] - 2019-03-05
336
+ ## [v1.10.0](https://github.com/cedarcode/webauthn-ruby/compare/v1.9.0...v1.10.0/) - 2019-03-05
313
337
 
314
338
  ### Added
315
339
 
316
340
  - Parse and make AuthenticatorData's extensionData available
317
341
 
318
- ## [v1.9.0] - 2019-02-22
342
+ ## [v1.9.0](https://github.com/cedarcode/webauthn-ruby/compare/v1.8.0...v1.9.0/) - 2019-02-22
319
343
 
320
344
  ### Added
321
345
 
322
346
  - Added `#verify`, which can be used for getting a meaningful error raised in case of a verification error, as opposed to `#valid?` which returns `false`
323
347
 
324
- ## [v1.8.0] - 2019-01-17
348
+ ## [v1.8.0](https://github.com/cedarcode/webauthn-ruby/compare/v1.7.0...v1.8.0/) - 2019-01-17
325
349
 
326
350
  ### Added
327
351
 
@@ -332,40 +356,40 @@ Note #2: You don't need to do any convesion before passing the public key in `Au
332
356
 
333
357
  - Make current raised exception errors a bit more meaningful to aid debugging
334
358
 
335
- ## [v1.7.0] - 2018-11-08
359
+ ## [v1.7.0](https://github.com/cedarcode/webauthn-ruby/compare/v1.6.0...v1.7.0/) - 2018-11-08
336
360
 
337
361
  ### Added
338
362
 
339
363
  - _Registration_ ceremony
340
364
  - `WebAuthn::AuthenticatorAttestationResponse` exposes attestation type and trust path via `#attestation_type` and `#attestation_trust_path` methods ([@bdewater])
341
365
 
342
- ## [v1.6.0] - 2018-11-01
366
+ ## [v1.6.0](https://github.com/cedarcode/webauthn-ruby/compare/v1.5.0...v1.6.0/) - 2018-11-01
343
367
 
344
368
  ### Added
345
369
 
346
370
  - `FakeAuthenticator` object is now exposed to help you test your WebAuthn implementation
347
371
 
348
- ## [v1.5.0] - 2018-10-23
372
+ ## [v1.5.0](https://github.com/cedarcode/webauthn-ruby/compare/v1.4.0...v1.5.0/) - 2018-10-23
349
373
 
350
374
  ### Added
351
375
 
352
376
  - Works with ruby 2.3 ([@bdewater])
353
377
 
354
- ## [v1.4.0] - 2018-10-11
378
+ ## [v1.4.0](https://github.com/cedarcode/webauthn-ruby/compare/v1.3.0...v1.4.0/) - 2018-10-11
355
379
 
356
380
  ### Added
357
381
 
358
382
  - _Registration_ ceremony
359
383
  - `WebAuthn::AuthenticatorAttestationResponse.valid?` supports `android-safetynet` attestation statements ([@bdewater])
360
384
 
361
- ## [v1.3.0] - 2018-10-11
385
+ ## [v1.3.0](https://github.com/cedarcode/webauthn-ruby/compare/v1.2.0...v1.3.0/) - 2018-10-11
362
386
 
363
387
  ### Added
364
388
 
365
389
  - _Registration_ ceremony
366
390
  - `WebAuthn::AuthenticatorAttestationResponse.valid?` supports `packed` attestation statements ([@sorah])
367
391
 
368
- ## [v1.2.0] - 2018-10-08
392
+ ## [v1.2.0](https://github.com/cedarcode/webauthn-ruby/compare/v1.1.0...v1.2.0/) - 2018-10-08
369
393
 
370
394
  ### Added
371
395
 
@@ -376,7 +400,7 @@ Note #2: You don't need to do any convesion before passing the public key in `Au
376
400
 
377
401
  Note: Both additions should help making it compatible with Chrome for Android 70+/Android Fingerprint pair.
378
402
 
379
- ## [v1.1.0] - 2018-10-04
403
+ ## [v1.1.0](https://github.com/cedarcode/webauthn-ruby/compare/v1.0.0...v1.1.0/) - 2018-10-04
380
404
 
381
405
  ### Added
382
406
 
@@ -385,7 +409,7 @@ Note: Both additions should help making it compatible with Chrome for Android 70
385
409
  - _Authentication_ ceremony
386
410
  - `WebAuthn::AuthenticatorAssertionResponse.valid?` optionally accepts rp_id.
387
411
 
388
- ## [v1.0.0] - 2018-09-07
412
+ ## [v1.0.0](https://github.com/cedarcode/webauthn-ruby/compare/v0.2.0...v1.0.0/) - 2018-09-07
389
413
 
390
414
  ### Added
391
415
 
@@ -399,7 +423,7 @@ Note: Both additions should help making it compatible with Chrome for Android 70
399
423
  - _Authentication_ ceremony
400
424
  - Use 32-byte challenge instead of 16-byte
401
425
 
402
- ## [v0.2.0] - 2018-06-08
426
+ ## [v0.2.0](https://github.com/cedarcode/webauthn-ruby/compare/v0.1.0...v0.2.0/) - 2018-06-08
403
427
 
404
428
  ### Added
405
429
 
@@ -427,7 +451,7 @@ Note: Both additions should help making it compatible with Chrome for Android 70
427
451
  - _Registration_ ceremony
428
452
  - `WebAuthn::AuthenticatorAttestationResponse.credential_id` (superseded by `WebAuthn::AuthenticatorAttestationResponse.credential`)
429
453
 
430
- ## [v0.1.0] - 2018-05-25
454
+ ## [v0.1.0](https://github.com/cedarcode/webauthn-ruby/compare/v0.0.0...v0.1.0/) - 2018-05-25
431
455
 
432
456
  ### Added
433
457
 
@@ -436,61 +460,25 @@ Note: Both additions should help making it compatible with Chrome for Android 70
436
460
  - `WebAuthn::AuthenticatorAttestationResponse.valid?` can be used to validate fido-u2f attestations returned by the browser
437
461
  - Works with ruby 2.5
438
462
 
439
- [v3.4.2]: https://github.com/cedarcode/webauthn-ruby/compare/v3.4.1...v3.4.2/
440
- [v3.4.1]: https://github.com/cedarcode/webauthn-ruby/compare/v3.4.0...v3.4.1/
441
- [v3.4.0]: https://github.com/cedarcode/webauthn-ruby/compare/v3.3.0...v3.4.0/
442
- [v3.3.0]: https://github.com/cedarcode/webauthn-ruby/compare/v3.2.2...v3.3.0/
443
- [v3.2.2]: https://github.com/cedarcode/webauthn-ruby/compare/v3.2.1...v3.2.2/
444
- [v3.2.1]: https://github.com/cedarcode/webauthn-ruby/compare/v3.2.0...v3.2.1/
445
- [v3.2.0]: https://github.com/cedarcode/webauthn-ruby/compare/v3.1.0...v3.2.0/
446
- [v3.1.0]: https://github.com/cedarcode/webauthn-ruby/compare/v3.0.0...v3.1.0/
447
- [v3.0.0]: https://github.com/cedarcode/webauthn-ruby/compare/2-stable...v3.0.0/
448
- [v3.0.0.alpha2]: https://github.com/cedarcode/webauthn-ruby/compare/2-stable...v3.0.0.alpha2/
449
- [v3.0.0.alpha1]: https://github.com/cedarcode/webauthn-ruby/compare/v2.3.0...v3.0.0.alpha1
450
- [v2.5.2]: https://github.com/cedarcode/webauthn-ruby/compare/v2.5.1...v2.5.2/
451
- [v2.5.1]: https://github.com/cedarcode/webauthn-ruby/compare/v2.5.0...v2.5.1/
452
- [v2.5.0]: https://github.com/cedarcode/webauthn-ruby/compare/v2.4.1...v2.5.0/
453
- [v2.4.1]: https://github.com/cedarcode/webauthn-ruby/compare/v2.4.0...v2.4.1/
454
- [v2.4.0]: https://github.com/cedarcode/webauthn-ruby/compare/v2.3.0...v2.4.0/
455
- [v2.3.0]: https://github.com/cedarcode/webauthn-ruby/compare/v2.2.1...v2.3.0/
456
- [v2.2.1]: https://github.com/cedarcode/webauthn-ruby/compare/v2.2.0...v2.2.1/
457
- [v2.2.0]: https://github.com/cedarcode/webauthn-ruby/compare/v2.1.0...v2.2.0/
458
- [v2.1.0]: https://github.com/cedarcode/webauthn-ruby/compare/v2.0.0...v2.1.0/
459
- [v2.0.0]: https://github.com/cedarcode/webauthn-ruby/compare/v1.18.0...v2.0.0/
460
- [v1.18.0]: https://github.com/cedarcode/webauthn-ruby/compare/v1.17.0...v1.18.0/
461
- [v1.17.0]: https://github.com/cedarcode/webauthn-ruby/compare/v1.16.0...v1.17.0/
462
- [v1.16.0]: https://github.com/cedarcode/webauthn-ruby/compare/v1.15.0...v1.16.0/
463
- [v1.15.0]: https://github.com/cedarcode/webauthn-ruby/compare/v1.14.0...v1.15.0/
464
- [v1.14.0]: https://github.com/cedarcode/webauthn-ruby/compare/v1.13.0...v1.14.0/
465
- [v1.13.0]: https://github.com/cedarcode/webauthn-ruby/compare/v1.12.0...v1.13.0/
466
- [v1.12.0]: https://github.com/cedarcode/webauthn-ruby/compare/v1.11.0...v1.12.0/
467
- [v1.11.0]: https://github.com/cedarcode/webauthn-ruby/compare/v1.10.0...v1.11.0/
468
- [v1.10.0]: https://github.com/cedarcode/webauthn-ruby/compare/v1.9.0...v1.10.0/
469
- [v1.9.0]: https://github.com/cedarcode/webauthn-ruby/compare/v1.8.0...v1.9.0/
470
- [v1.8.0]: https://github.com/cedarcode/webauthn-ruby/compare/v1.7.0...v1.8.0/
471
- [v1.7.0]: https://github.com/cedarcode/webauthn-ruby/compare/v1.6.0...v1.7.0/
472
- [v1.6.0]: https://github.com/cedarcode/webauthn-ruby/compare/v1.5.0...v1.6.0/
473
- [v1.5.0]: https://github.com/cedarcode/webauthn-ruby/compare/v1.4.0...v1.5.0/
474
- [v1.4.0]: https://github.com/cedarcode/webauthn-ruby/compare/v1.3.0...v1.4.0/
475
- [v1.3.0]: https://github.com/cedarcode/webauthn-ruby/compare/v1.2.0...v1.3.0/
476
- [v1.2.0]: https://github.com/cedarcode/webauthn-ruby/compare/v1.1.0...v1.2.0/
477
- [v1.1.0]: https://github.com/cedarcode/webauthn-ruby/compare/v1.0.0...v1.1.0/
478
- [v1.0.0]: https://github.com/cedarcode/webauthn-ruby/compare/v0.2.0...v1.0.0/
479
- [v0.2.0]: https://github.com/cedarcode/webauthn-ruby/compare/v0.1.0...v0.2.0/
480
- [v0.1.0]: https://github.com/cedarcode/webauthn-ruby/compare/v0.0.0...v0.1.0/
481
-
482
- [@brauliomartinezlm]: https://github.com/brauliomartinezlm
483
463
  [@bdewater]: https://github.com/bdewater
464
+ [@brauliomartinezlm]: https://github.com/brauliomartinezlm
465
+ [@ClearlyClaire]: https://github.com/ClearlyClaire
466
+ [@jdongelmans]: https://github.com/jdongelmans
484
467
  [@jdongelmans]: https://github.com/jdongelmans
468
+ [@juanarias93]: https://github.com/juanarias93
485
469
  [@kalebtesfay]: https://github.com/kalebtesfay
470
+ [@kingjan1999]: https://github.com/@kingjan1999
471
+ [@lgarron]: https://github.com/lgarron
486
472
  [@MaximeNdutiye]: https://github.com/MaximeNdutiye
487
- [@sorah]: https://github.com/sorah
488
- [@ssuttner]: https://github.com/ssuttner
473
+ [@nicolastemciuc]: https://github.com/nicolastemciuc
474
+ [@obroshnij]: https://github.com/obroshnij
475
+ [@olleolleolle]: https://github.com/olleolleolle
476
+ [@OskarEichler]: https://github.com/OskarEichler
489
477
  [@padulafacundo]: https://github.com/padulafacundo
490
- [@santiagorodriguez96]: https://github.com/santiagorodriguez96
491
- [@lgarron]: https://github.com/lgarron
492
- [@juanarias93]: https://github.com/juanarias93
493
- [@kingjan1999]: https://github.com/@kingjan1999
494
- [@jdongelmans]: https://github.com/jdongelmans
495
478
  [@petergoldstein]: https://github.com/petergoldstein
496
- [@ClearlyClaire]: https://github.com/ClearlyClaire
479
+ [@santiagorodriguez96]: https://github.com/santiagorodriguez96
480
+ [@soartec-lab]: https://github.com/soartec-lab
481
+ [@sorah]: https://github.com/sorah
482
+ [@ssuttner]: https://github.com/ssuttner
483
+ [@ttanimichi]: https://github.com/ttanimichi
484
+ [@8ma10s]: https://github.com/8ma10s
data/README.md CHANGED
@@ -38,7 +38,7 @@ _More_: [SECURITY](SECURITY.md)
38
38
 
39
39
  ### What is WebAuthn?
40
40
 
41
- WebAuthn (Web Authentication) is a W3C standard for secure public-key authentication on the Web supported by all leading browsers and platforms.
41
+ WebAuthn (Web Authentication) is a W3C standard for secure public-key authentication on the Web supported by all leading browsers and platforms. WebAuthn is the standard that underpins passkeys, the phishing-resistant replacement for passwords.
42
42
 
43
43
  #### Good Intros
44
44
 
@@ -86,7 +86,7 @@ Or install it yourself as:
86
86
 
87
87
  ## Usage
88
88
 
89
- You can find a working example on how to use this gem in a pasword-less login in a __Rails__ app in [webauthn-rails-demo-app](https://github.com/cedarcode/webauthn-rails-demo-app). If you want to see an example on how to use this gem as a second factor authenticator in a __Rails__ application instead, you can check it in [webauthn-2fa-rails-demo](https://github.com/cedarcode/webauthn-2fa-rails-demo).
89
+ You can find a working example on how to use this gem in a passwordless login in a __Rails__ app in [webauthn-rails-demo-app](https://github.com/cedarcode/webauthn-rails-demo-app). If you want to see an example on how to use this gem as a second factor authenticator in a __Rails__ application instead, you can check it in [webauthn-2fa-rails-demo](https://github.com/cedarcode/webauthn-2fa-rails-demo).
90
90
 
91
91
  If you are migrating an existing application from the legacy FIDO U2F JavaScript API to WebAuthn, also refer to
92
92
  [`docs/u2f_migration.md`](docs/u2f_migration.md).
@@ -104,6 +104,31 @@ WebAuthn.configure do |config|
104
104
  # Multiple origins can be used when needed. Using more than one will imply you MUST configure rp_id explicitely. If you need your credentials to be bound to a single origin but you have more than one tenant, please see [our Advanced Configuration section](https://github.com/cedarcode/webauthn-ruby/blob/master/docs/advanced_configuration.md) instead of adding multiple origins.
105
105
  config.allowed_origins = ["https://auth.example.com"]
106
106
 
107
+ # When operating within iframes or embedded contexts, you may need to restrict
108
+ # which top-level origins are permitted to host WebAuthn ceremonies.
109
+ #
110
+ # crossOrigin / topOrigin verification is DISABLED by default:
111
+ # config.verify_cross_origin = false
112
+ #
113
+ # When `verify_cross_origin` is false, any `crossOrigin` / `topOrigin` values reported by the browser
114
+ # are ignored. As a result, credentials created or used within a cross-origin iframe will be treated
115
+ # as valid.
116
+ #
117
+ # When `verify_cross_origin` is true, you can either:
118
+ #
119
+ # (A) Allow only specific top-level origins to embed your ceremony
120
+ # (each entry must match the browser-reported `topOrigin` during registration/authentication):
121
+ #
122
+ # config.allowed_top_origins = ["https://app.example.com"]
123
+ #
124
+ # (B) Forbid ANY cross-origin iframe usage altogether
125
+ # (this rejects creation/authentication whenever `crossOrigin` is true):
126
+ #
127
+ # config.allowed_top_origins = []
128
+ #
129
+ # Note: if `verify_cross_origin` is not enabled, any values set in `allowed_top_origins`
130
+ # will be ignored.
131
+
107
132
  # Relying Party name for display purposes
108
133
  config.rp_name = "Example Inc."
109
134
 
@@ -112,7 +137,7 @@ WebAuthn.configure do |config|
112
137
  # interaction with the user.
113
138
  # This hint may be overridden by the browser.
114
139
  # https://www.w3.org/TR/webauthn/#dom-publickeycredentialcreationoptions-timeout
115
- # config.credential_options_timeout = 120_000
140
+ # config.credential_options_timeout = 300_000
116
141
 
117
142
  # You can optionally specify a different Relying Party ID
118
143
  # (https://www.w3.org/TR/webauthn/#relying-party-identifier)
@@ -144,14 +169,18 @@ end
144
169
  #### Initiation phase
145
170
 
146
171
  ```ruby
147
- # Generate and store the WebAuthn User ID the first time the user registers a credential
148
- if !user.webauthn_id
149
- user.update!(webauthn_id: WebAuthn.generate_user_id)
172
+ # Generate and store the WebAuthn User Handle the first time the user registers a credential
173
+ if !user.webauthn_user_handle
174
+ user.update!(webauthn_user_handle: WebAuthn.generate_user_handle)
150
175
  end
151
176
 
152
177
  options = WebAuthn::Credential.options_for_create(
153
- user: { id: user.webauthn_id, name: user.name },
154
- exclude: user.credentials.map { |c| c.webauthn_id }
178
+ user: { id: user.webauthn_user_handle, name: user.name },
179
+ exclude: user.webauthn_credentials.map { |c| c.webauthn_id },
180
+ authenticator_selection: {
181
+ resident_key: "discouraged", # For a passwordless login or 2FA. Use "required" for a passkey-based (passwordless and usernameless) login.
182
+ user_verification: "required" # For a passwordless or passkey-based (passwordless and usernameless) login. Use "discouraged" for 2FA.
183
+ }
155
184
  )
156
185
 
157
186
  # Store the newly generated challenge somewhere so you can have it
@@ -166,23 +195,24 @@ session[:creation_challenge] = options.challenge
166
195
  # If inside a Rails controller, `render json: options` will just work.
167
196
  # I.e. it will encode and convert the options to JSON automatically.
168
197
 
169
- # For your frontend code, you might find @github/webauthn-json npm package useful.
170
- # Especially for handling the necessary decoding of the options, and sending the
171
- # `PublicKeyCredential` object back to the server.
198
+ # For your frontend code, you might find the [built-in browser methods](https://developer.mozilla.org/en-US/docs/Web/API/PublicKeyCredential) useful.
199
+ # The built-in `PublicKeyCredential.parseCreationOptionsFromJSON(options)` allows you to decode the options,
200
+ # and the built-in `credential.toJSON()` to send the `PublicKeyCredential` object back to the server.
172
201
  ```
173
202
 
174
203
  #### Verification phase
175
204
 
176
205
  ```ruby
177
- # Assuming you're using @github/webauthn-json package to send the `PublicKeyCredential` object back
206
+ # Assuming you're using the built-in `credential.toJSON()` to send the `PublicKeyCredential` object back
178
207
  # in params[:publicKeyCredential]:
179
208
  webauthn_credential = WebAuthn::Credential.from_create(params[:publicKeyCredential])
180
209
 
181
210
  begin
182
- webauthn_credential.verify(session[:creation_challenge])
211
+ # Enforce user verification (pairs with the "required" request above). Omit for 2FA.
212
+ webauthn_credential.verify(session[:creation_challenge], user_verification: true)
183
213
 
184
214
  # Store Credential ID, Credential Public Key and Sign Count for future authentications
185
- user.credentials.create!(
215
+ user.webauthn_credentials.create!(
186
216
  webauthn_id: webauthn_credential.id,
187
217
  public_key: webauthn_credential.public_key,
188
218
  sign_count: webauthn_credential.sign_count
@@ -199,7 +229,12 @@ end
199
229
  #### Initiation phase
200
230
 
201
231
  ```ruby
202
- options = WebAuthn::Credential.options_for_get(allow: user.credentials.map { |c| c.webauthn_id })
232
+ options = WebAuthn::Credential.options_for_get(
233
+ # Pass `allow` when the user is already known (passwordless/2FA/reauth).
234
+ # For a passkey-based (usernameless and passwordless) login, omit it and resolve the user from `user_handle` after `from_get`.
235
+ allow: user.webauthn_credentials.map { |c| c.webauthn_id },
236
+ user_verification: "required" # For a passwordless or passkey-based (passwordless and usernameless) login. Use "discouraged" for 2FA.
237
+ )
203
238
 
204
239
  # Store the newly generated challenge somewhere so you can have it
205
240
  # for the verification phase.
@@ -213,9 +248,9 @@ session[:authentication_challenge] = options.challenge
213
248
  # If inside a Rails controller, `render json: options` will just work.
214
249
  # I.e. it will encode and convert the options to JSON automatically.
215
250
 
216
- # For your frontend code, you might find @github/webauthn-json npm package useful.
217
- # Especially for handling the necessary decoding of the options, and sending the
218
- # `PublicKeyCredential` object back to the server.
251
+ # For your frontend code, you might find the [built-in browser methods](https://developer.mozilla.org/en-US/docs/Web/API/PublicKeyCredential) useful.
252
+ # The built-in `PublicKeyCredential.parseRequestOptionsFromJSON(options)` allows you to decode the options,
253
+ # and the built-in `credential.toJSON()` to send the `PublicKeyCredential` object back to the server.
219
254
  ```
220
255
 
221
256
  #### Verification phase
@@ -225,17 +260,18 @@ interface returned by the browser to the stored `credential_id`. The correspondi
225
260
  attributes must be passed as keyword arguments to the `verify` method call.
226
261
 
227
262
  ```ruby
228
- # Assuming you're using @github/webauthn-json package to send the `PublicKeyCredential` object back
263
+ # Assuming you're using the built-in `credential.toJSON()` to send the `PublicKeyCredential` object back
229
264
  # in params[:publicKeyCredential]:
230
265
  webauthn_credential = WebAuthn::Credential.from_get(params[:publicKeyCredential])
231
266
 
232
- stored_credential = user.credentials.find_by(webauthn_id: webauthn_credential.id)
267
+ stored_credential = user.webauthn_credentials.find_by(webauthn_id: webauthn_credential.id)
233
268
 
234
269
  begin
235
270
  webauthn_credential.verify(
236
271
  session[:authentication_challenge],
237
272
  public_key: stored_credential.public_key,
238
- sign_count: stored_credential.sign_count
273
+ sign_count: stored_credential.sign_count,
274
+ user_verification: true # For a passwordless or passkey-based (passwordless and usernameless) login. Omit for 2FA.
239
275
  )
240
276
 
241
277
  # Update the stored credential sign count with the value from `webauthn_credential.sign_count`
@@ -263,16 +299,20 @@ Extensions can be requested in the initiation phase in both Credential Registrat
263
299
  ```ruby
264
300
  # Credential Registration
265
301
  creation_options = WebAuthn::Credential.options_for_create(
266
- user: { id: user.webauthn_id, name: user.name },
267
- exclude: user.credentials.map { |c| c.webauthn_id },
268
- extensions: { appidExclude: domain.to_s }
302
+ user: { id: user.webauthn_user_handle, name: user.name },
303
+ exclude: user.webauthn_credentials.map { |c| c.webauthn_id },
304
+ extensions: { appidExclude: domain.to_s },
305
+ authenticator_selection: {
306
+ resident_key: "discouraged", # For a passwordless login or 2FA. Use "required" for a passkey-based (passwordless and usernameless) login.
307
+ user_verification: "required" # For a passwordless or passkey-based (passwordless and usernameless) login. Use "discouraged" for 2FA.
308
+ }
269
309
  )
270
310
 
271
311
  # OR
272
312
 
273
313
  # Credential Authentication
274
314
  options = WebAuthn::Credential.options_for_get(
275
- allow: user.credentials.map { |c| c.webauthn_id },
315
+ allow: user.webauthn_credentials.map { |c| c.webauthn_id },
276
316
  extensions: { appid: domain.to_s }
277
317
  )
278
318
  ```
@@ -302,14 +342,16 @@ A list of all currently defined extensions:
302
342
 
303
343
  ## API
304
344
 
305
- #### `WebAuthn.generate_user_id`
345
+ #### `WebAuthn.generate_user_handle`
306
346
 
307
347
  Generates a [WebAuthn User Handle](https://www.w3.org/TR/webauthn-2/#user-handle) that follows the WebAuthn spec recommendations.
308
348
 
309
349
  ```ruby
310
- WebAuthn.generate_user_id # "lWoMZTGf_ml2RoY5qPwbwrkxrvTqWjGOxEoYBgxft3zG-LlrICvE-y8bxFi06zMyIOyNsJoWx4Fa2TOqoRmnxA"
350
+ WebAuthn.generate_user_handle # "lWoMZTGf_ml2RoY5qPwbwrkxrvTqWjGOxEoYBgxft3zG-LlrICvE-y8bxFi06zMyIOyNsJoWx4Fa2TOqoRmnxA"
311
351
  ```
312
352
 
353
+ > `WebAuthn.generate_user_id` is also available as an alias.
354
+
313
355
  #### `WebAuthn::Credential.options_for_create(options)`
314
356
 
315
357
  Helper method to build the necessary [PublicKeyCredentialCreationOptions](https://www.w3.org/TR/webauthn-2/#dictdef-publickeycredentialcreationoptions)
@@ -317,8 +359,8 @@ to be used in the client-side code to call `navigator.credentials.create({ "publ
317
359
 
318
360
  ```ruby
319
361
  creation_options = WebAuthn::Credential.options_for_create(
320
- user: { id: user.webauthn_id, name: user.name }
321
- exclude: user.credentials.map { |c| c.webauthn_id }
362
+ user: { id: user.webauthn_user_handle, name: user.name },
363
+ exclude: user.webauthn_credentials.map { |c| c.webauthn_id }
322
364
  )
323
365
 
324
366
  # Store the newly generated challenge somewhere so you can have it
@@ -340,7 +382,7 @@ Helper method to build the necessary [PublicKeyCredentialRequestOptions](https:/
340
382
  to be used in the client-side code to call `navigator.credentials.get({ "publicKey": publicKeyCredentialRequestOptions })`.
341
383
 
342
384
  ```ruby
343
- request_options = WebAuthn::Credential.options_for_get(allow: user.credentials.map { |c| c.webauthn_id })
385
+ request_options = WebAuthn::Credential.options_for_get(allow: user.webauthn_credentials.map { |c| c.webauthn_id })
344
386
 
345
387
  # Store the newly generated challenge somewhere so you can have it
346
388
  # for the verification phase.
@@ -32,7 +32,7 @@ Instead of the [Global Configuration](../README.md#configuration) you place in `
32
32
  # interaction with the user.
33
33
  # This hint may be overridden by the browser.
34
34
  # https://www.w3.org/TR/webauthn/#dom-publickeycredentialcreationoptions-timeout
35
- # credential_options_timeout: 120_000
35
+ # credential_options_timeout: 300_000
36
36
 
37
37
  # You can optionally specify a different Relying Party ID
38
38
  # (https://www.w3.org/TR/webauthn/#relying-party-identifier)
@@ -58,8 +58,6 @@ Instead of the [Global Configuration](../README.md#configuration) you place in `
58
58
 
59
59
  ## Instance Based API
60
60
 
61
- **DISCLAIMER: This API was released on version 3.0.0.alpha1 and is still under evaluation. Although it has been thoroughly tested and it is fully functional it might be changed until the final release of version 3.0.0.**
62
-
63
61
  The explanation for each ceremony can be found in depth in [Credential Registration](../README.md#credential-registration) and [Credential Authentication](../README.md#credential-authentication) but if you choose this instance based approach to define your WebAuthn configurations and assuming `relying_party` is the result of an instance you get through `WebAuthn::RelyingParty.new(...)` the code in those explanations needs to be updated to:
64
62
 
65
63
  ### Credential Registration
@@ -13,10 +13,13 @@ require "webauthn/encoder"
13
13
  module WebAuthn
14
14
  class AttestationStatementVerificationError < VerificationError; end
15
15
  class AttestedCredentialVerificationError < VerificationError; end
16
+ class CredentialIdLengthVerificationError < VerificationError; end
16
17
 
17
18
  class AuthenticatorAttestationResponse < AuthenticatorResponse
18
19
  extend Forwardable
19
20
 
21
+ MAX_CREDENTIAL_ID_LENGTH = 1023
22
+
20
23
  def self.from_client(response, relying_party: WebAuthn.configuration.relying_party)
21
24
  encoder = relying_party.encoder
22
25
 
@@ -45,6 +48,7 @@ module WebAuthn
45
48
  if relying_party.verify_attestation_statement
46
49
  verify_item(:attestation_statement)
47
50
  end
51
+ verify_item(:credential_id_length)
48
52
 
49
53
  true
50
54
  end
@@ -80,5 +84,9 @@ module WebAuthn
80
84
  def valid_attestation_statement?
81
85
  @attestation_type, @attestation_trust_path = attestation_object.valid_attestation_statement?(client_data.hash)
82
86
  end
87
+
88
+ def valid_credential_id_length?
89
+ authenticator_data.credential.id.bytesize <= MAX_CREDENTIAL_ID_LENGTH
90
+ end
83
91
  end
84
92
  end
@@ -10,10 +10,11 @@ module WebAuthn
10
10
  class VerificationError < Error; end
11
11
 
12
12
  class AuthenticatorDataVerificationError < VerificationError; end
13
+ class BackupFlagsVerificationError < VerificationError; end
13
14
  class ChallengeVerificationError < VerificationError; end
14
15
  class OriginVerificationError < VerificationError; end
15
16
  class RpIdVerificationError < VerificationError; end
16
- class TokenBindingVerificationError < VerificationError; end
17
+ class TopOriginVerificationError < VerificationError; end
17
18
  class TypeVerificationError < VerificationError; end
18
19
  class UserPresenceVerificationError < VerificationError; end
19
20
  class UserVerifiedVerificationError < VerificationError; end
@@ -30,9 +31,9 @@ module WebAuthn
30
31
  rp_id ||= relying_party.id
31
32
 
32
33
  verify_item(:type)
33
- verify_item(:token_binding)
34
34
  verify_item(:challenge, expected_challenge)
35
35
  verify_item(:origin, expected_origin)
36
+ verify_item(:top_origin) if needs_top_origin_verification?
36
37
  verify_item(:authenticator_data)
37
38
 
38
39
  verify_item(
@@ -49,6 +50,8 @@ module WebAuthn
49
50
  verify_item(:user_verified)
50
51
  end
51
52
 
53
+ verify_item(:backup_flags)
54
+
52
55
  true
53
56
  end
54
57
 
@@ -80,8 +83,10 @@ module WebAuthn
80
83
  client_data.type == type
81
84
  end
82
85
 
83
- def valid_token_binding?
84
- client_data.valid_token_binding_format?
86
+ def valid_top_origin?
87
+ return false unless client_data.cross_origin
88
+
89
+ relying_party.allowed_top_origins&.include?(client_data.top_origin)
85
90
  end
86
91
 
87
92
  def valid_challenge?(expected_challenge)
@@ -114,6 +119,10 @@ module WebAuthn
114
119
  authenticator_data.user_verified?
115
120
  end
116
121
 
122
+ def valid_backup_flags?
123
+ authenticator_data.credential_backup_eligible? || !authenticator_data.credential_backed_up?
124
+ end
125
+
117
126
  def rp_id_from_origin(expected_origin)
118
127
  URI.parse(expected_origin.first).host if expected_origin.size == 1
119
128
  end
@@ -121,5 +130,9 @@ module WebAuthn
121
130
  def type
122
131
  raise NotImplementedError, "Please define #type method in subclass"
123
132
  end
133
+
134
+ def needs_top_origin_verification?
135
+ relying_party.verify_cross_origin && (client_data.cross_origin || client_data.top_origin)
136
+ end
124
137
  end
125
138
  end
@@ -9,8 +9,6 @@ module WebAuthn
9
9
  class ClientDataMissingError < Error; end
10
10
 
11
11
  class ClientData
12
- VALID_TOKEN_BINDING_STATUSES = ["present", "supported", "not-supported"].freeze
13
-
14
12
  def initialize(client_data_json)
15
13
  @client_data_json = client_data_json
16
14
  end
@@ -27,16 +25,12 @@ module WebAuthn
27
25
  data["origin"]
28
26
  end
29
27
 
30
- def token_binding
31
- data["tokenBinding"]
28
+ def cross_origin
29
+ data["crossOrigin"]
32
30
  end
33
31
 
34
- def valid_token_binding_format?
35
- if token_binding
36
- token_binding.is_a?(Hash) && VALID_TOKEN_BINDING_STATUSES.include?(token_binding["status"])
37
- else
38
- true
39
- end
32
+ def top_origin
33
+ data["topOrigin"]
40
34
  end
41
35
 
42
36
  def hash
@@ -24,8 +24,12 @@ module WebAuthn
24
24
  :origin=,
25
25
  :allowed_origins,
26
26
  :allowed_origins=,
27
+ :allowed_top_origins,
28
+ :allowed_top_origins=,
27
29
  :verify_attestation_statement,
28
30
  :verify_attestation_statement=,
31
+ :verify_cross_origin,
32
+ :verify_cross_origin=,
29
33
  :credential_options_timeout,
30
34
  :credential_options_timeout=,
31
35
  :silent_authentication,
@@ -10,16 +10,18 @@ module WebAuthn
10
10
  class FakeClient
11
11
  TYPES = { create: "webauthn.create", get: "webauthn.get" }.freeze
12
12
 
13
- attr_reader :origin, :token_binding, :encoding
13
+ attr_reader :origin, :cross_origin, :top_origin, :encoding
14
14
 
15
15
  def initialize(
16
16
  origin = fake_origin,
17
- token_binding: nil,
17
+ cross_origin: nil,
18
+ top_origin: nil,
18
19
  authenticator: WebAuthn::FakeAuthenticator.new,
19
20
  encoding: WebAuthn.configuration.encoding
20
21
  )
21
22
  @origin = origin
22
- @token_binding = token_binding
23
+ @cross_origin = cross_origin
24
+ @top_origin = top_origin
23
25
  @authenticator = authenticator
24
26
  @encoding = encoding
25
27
  end
@@ -81,7 +83,7 @@ module WebAuthn
81
83
  user_present: true,
82
84
  user_verified: false,
83
85
  backup_eligibility: false,
84
- backup_state: true,
86
+ backup_state: false,
85
87
  sign_count: nil,
86
88
  extensions: nil,
87
89
  user_handle: nil,
@@ -133,8 +135,12 @@ module WebAuthn
133
135
  origin: origin
134
136
  }
135
137
 
136
- if token_binding
137
- data[:tokenBinding] = token_binding
138
+ if cross_origin
139
+ data[:crossOrigin] = cross_origin
140
+ end
141
+
142
+ if top_origin
143
+ data[:topOrigin] = top_origin
138
144
  end
139
145
 
140
146
  data.to_json
@@ -10,6 +10,7 @@ module WebAuthn
10
10
  class CreationOptions < Options
11
11
  attr_accessor(
12
12
  :attestation,
13
+ :attestation_formats,
13
14
  :authenticator_selection,
14
15
  :exclude,
15
16
  :algs,
@@ -19,6 +20,7 @@ module WebAuthn
19
20
 
20
21
  def initialize(
21
22
  attestation: nil,
23
+ attestation_formats: nil,
22
24
  authenticator_selection: nil,
23
25
  exclude_credentials: nil,
24
26
  exclude: nil,
@@ -31,6 +33,7 @@ module WebAuthn
31
33
  super(**keyword_arguments)
32
34
 
33
35
  @attestation = attestation
36
+ @attestation_formats = attestation_formats
34
37
  @authenticator_selection = authenticator_selection
35
38
  @exclude_credentials = exclude_credentials
36
39
  @exclude = exclude
@@ -39,6 +42,7 @@ module WebAuthn
39
42
 
40
43
  @rp =
41
44
  if rp.is_a?(Hash)
45
+ rp = rp.dup
42
46
  rp[:name] ||= relying_party.name
43
47
  rp[:id] ||= relying_party.id
44
48
 
@@ -66,7 +70,10 @@ module WebAuthn
66
70
  private
67
71
 
68
72
  def attributes
69
- super.concat([:rp, :user, :pub_key_cred_params, :attestation, :authenticator_selection, :exclude_credentials])
73
+ super.concat(
74
+ [:rp, :user, :pub_key_cred_params, :attestation, :attestation_formats, :authenticator_selection,
75
+ :exclude_credentials]
76
+ )
70
77
  end
71
78
 
72
79
  def exclude_credentials_from_exclude
@@ -9,12 +9,13 @@ module WebAuthn
9
9
 
10
10
  CHALLENGE_LENGTH = 32
11
11
 
12
- attr_reader :timeout, :extensions, :relying_party
12
+ attr_reader :timeout, :extensions, :hints, :relying_party
13
13
 
14
- def initialize(timeout: nil, extensions: nil, relying_party: WebAuthn.configuration.relying_party)
14
+ def initialize(timeout: nil, extensions: nil, hints: nil, relying_party: WebAuthn.configuration.relying_party)
15
15
  @relying_party = relying_party
16
16
  @timeout = timeout || default_timeout
17
17
  @extensions = default_extensions.merge(extensions || {})
18
+ @hints = hints
18
19
  end
19
20
 
20
21
  def challenge
@@ -24,7 +25,7 @@ module WebAuthn
24
25
  private
25
26
 
26
27
  def attributes
27
- [:challenge, :timeout, :extensions]
28
+ [:challenge, :timeout, :extensions, :hints]
28
29
  end
29
30
 
30
31
  def encoder
@@ -19,11 +19,13 @@ module WebAuthn
19
19
  algorithms: DEFAULT_ALGORITHMS.dup,
20
20
  encoding: WebAuthn::Encoder::STANDARD_ENCODING,
21
21
  allowed_origins: nil,
22
+ allowed_top_origins: nil,
22
23
  origin: nil,
23
24
  id: nil,
24
25
  name: nil,
25
26
  verify_attestation_statement: true,
26
- credential_options_timeout: 120000,
27
+ verify_cross_origin: false,
28
+ credential_options_timeout: 300_000,
27
29
  silent_authentication: false,
28
30
  acceptable_attestation_types: ['None', 'Self', 'Basic', 'AttCA', 'Basic_or_AttCA', 'AnonCA'],
29
31
  attestation_root_certificates_finders: [],
@@ -32,9 +34,11 @@ module WebAuthn
32
34
  @algorithms = algorithms
33
35
  @encoding = encoding
34
36
  @allowed_origins = allowed_origins
37
+ @allowed_top_origins = allowed_top_origins
35
38
  @id = id
36
39
  @name = name
37
40
  @verify_attestation_statement = verify_attestation_statement
41
+ @verify_cross_origin = verify_cross_origin
38
42
  @credential_options_timeout = credential_options_timeout
39
43
  @silent_authentication = silent_authentication
40
44
  @acceptable_attestation_types = acceptable_attestation_types
@@ -46,9 +50,11 @@ module WebAuthn
46
50
  attr_accessor :algorithms,
47
51
  :encoding,
48
52
  :allowed_origins,
53
+ :allowed_top_origins,
49
54
  :id,
50
55
  :name,
51
56
  :verify_attestation_statement,
57
+ :verify_cross_origin,
52
58
  :credential_options_timeout,
53
59
  :silent_authentication,
54
60
  :acceptable_attestation_types,
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module WebAuthn
4
- VERSION = "3.4.3"
4
+ VERSION = "3.5.0"
5
5
  end
data/lib/webauthn.rb CHANGED
@@ -10,7 +10,10 @@ require "webauthn/version"
10
10
  module WebAuthn
11
11
  TYPE_PUBLIC_KEY = "public-key"
12
12
 
13
- def self.generate_user_id
14
- configuration.encoder.encode(SecureRandom.random_bytes(64))
13
+ class << self
14
+ def generate_user_id
15
+ configuration.encoder.encode(SecureRandom.random_bytes(64))
16
+ end
17
+ alias_method :generate_user_handle, :generate_user_id
15
18
  end
16
19
  end
data/webauthn.gemspec CHANGED
@@ -12,7 +12,7 @@ Gem::Specification.new do |spec|
12
12
 
13
13
  spec.summary = "WebAuthn ruby server library"
14
14
  spec.description = 'WebAuthn ruby server library ― Make your application a W3C Web Authentication conformant
15
- Relying Party and allow your users to authenticate with U2F and FIDO2 authenticators.'
15
+ Relying Party and allow your users to authenticate with FIDO2/U2F authenticators as passkeys or security keys.'
16
16
  spec.homepage = "https://github.com/cedarcode/webauthn-ruby"
17
17
  spec.license = "MIT"
18
18
 
@@ -41,7 +41,7 @@ Gem::Specification.new do |spec|
41
41
  spec.add_dependency "safety_net_attestation", "~> 0.5.0"
42
42
  spec.add_dependency "tpm-key_attestation", "~> 0.14.0"
43
43
 
44
- spec.add_development_dependency "bundler", ">= 1.17", "< 3.0"
44
+ spec.add_development_dependency "bundler", ">= 1.17", "< 5.0"
45
45
  spec.add_development_dependency "byebug", "~> 11.0"
46
46
  spec.add_development_dependency "rake", "~> 13.0"
47
47
  spec.add_development_dependency "rspec", "~> 3.8"
metadata CHANGED
@@ -1,15 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: webauthn
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.4.3
4
+ version: 3.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gonzalo Rodriguez
8
8
  - Braulio Martinez
9
- autorequire:
10
9
  bindir: exe
11
10
  cert_chain: []
12
- date: 2025-10-23 00:00:00.000000000 Z
11
+ date: 1980-01-02 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: android_key_attestation
@@ -118,7 +117,7 @@ dependencies:
118
117
  version: '1.17'
119
118
  - - "<"
120
119
  - !ruby/object:Gem::Version
121
- version: '3.0'
120
+ version: '5.0'
122
121
  type: :development
123
122
  prerelease: false
124
123
  version_requirements: !ruby/object:Gem::Requirement
@@ -128,7 +127,7 @@ dependencies:
128
127
  version: '1.17'
129
128
  - - "<"
130
129
  - !ruby/object:Gem::Version
131
- version: '3.0'
130
+ version: '5.0'
132
131
  - !ruby/object:Gem::Dependency
133
132
  name: byebug
134
133
  requirement: !ruby/object:Gem::Requirement
@@ -221,7 +220,7 @@ dependencies:
221
220
  version: '4.0'
222
221
  description: |-
223
222
  WebAuthn ruby server library ― Make your application a W3C Web Authentication conformant
224
- Relying Party and allow your users to authenticate with U2F and FIDO2 authenticators.
223
+ Relying Party and allow your users to authenticate with FIDO2/U2F authenticators as passkeys or security keys.
225
224
  email:
226
225
  - gonzalo@cedarcode.com
227
226
  - braulio@cedarcode.com
@@ -229,11 +228,13 @@ executables: []
229
228
  extensions: []
230
229
  extra_rdoc_files: []
231
230
  files:
231
+ - ".github/FUNDING.yml"
232
232
  - ".github/actions/install-openssl/action.yml"
233
233
  - ".github/actions/install-ruby/action.yml"
234
234
  - ".github/dependabot.yml"
235
235
  - ".github/workflows/build.yml"
236
236
  - ".github/workflows/git.yml"
237
+ - ".github/workflows/release.yml"
237
238
  - ".gitignore"
238
239
  - ".rspec"
239
240
  - ".rubocop.yml"
@@ -304,7 +305,6 @@ metadata:
304
305
  bug_tracker_uri: https://github.com/cedarcode/webauthn-ruby/issues
305
306
  changelog_uri: https://github.com/cedarcode/webauthn-ruby/blob/master/CHANGELOG.md
306
307
  source_code_uri: https://github.com/cedarcode/webauthn-ruby
307
- post_install_message:
308
308
  rdoc_options: []
309
309
  require_paths:
310
310
  - lib
@@ -319,8 +319,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
319
319
  - !ruby/object:Gem::Version
320
320
  version: '0'
321
321
  requirements: []
322
- rubygems_version: 3.2.1
323
- signing_key:
322
+ rubygems_version: 4.0.20
324
323
  specification_version: 4
325
324
  summary: WebAuthn ruby server library
326
325
  test_files: []