webauthn 3.4.2 → 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: 50b5c2c43f3e5719dd1ed0f63e9a7bb9705f2f1e97861ab0a0ee0a7d61c4ee41
4
- data.tar.gz: d8849b387d30e54f7a45fd66bcb2b164983100b0b3369ca8fbf52840261e7fe4
3
+ metadata.gz: a20be10512baef48a31bf98b85727c8819a9b7c995400bad6282648e2120695e
4
+ data.tar.gz: b84352d26add2af3477070c91ef5707134882f99810216d89f09f9c81e1ef909
5
5
  SHA512:
6
- metadata.gz: 4189cd8d89340585a464e6d9368b6ea532c7c59189cbd47022a04d767ec230979076652e333e70878dcead127688d7fe01e57706f63afe325eb1ec5673cf851a
7
- data.tar.gz: 1cba3b28cd9388256f6d47493fb151f7732ad8680da5863476d4b5e237db7389e362f7a2543bc1447cd0e205e44134957cfa2e4ceb43e9fb32a6b5f851ff349a
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,38 +1,71 @@
1
1
  # Changelog
2
2
 
3
- ## [v3.4.2] - 2025-09-22
3
+ ## [Unreleased](https://github.com/cedarcode/webauthn-ruby/compare/v3.4.3...master/)
4
+
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
30
+
31
+ ### Fixed
32
+
33
+ - Fix `RelyingParty#origin` and `WebAuthn.configuration.origin` always returning `nil`. [#484](https://github.com/cedarcode/webauthn-ruby/pull/484) [@santiagorodriguez96]
34
+ - Now they return the allowed origin if allowed origins has only one element.
35
+
36
+ ## [v3.4.2](https://github.com/cedarcode/webauthn-ruby/compare/v3.4.1...v3.4.2/) - 2025-09-22
4
37
 
5
38
  ### Added
6
39
 
7
40
  - Updated `safety_net_attestation` dependency from `~> 0.4.0` to `~> 0.5.0`.
8
41
 
9
- ## [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
10
43
 
11
- - 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]
12
45
 
13
- ## [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
14
47
 
15
- - 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]
16
49
 
17
- ## [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
18
51
 
19
52
  ### Added
20
53
 
21
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]
22
55
 
23
- ## [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
24
57
 
25
58
  ### Fixed
26
59
 
27
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]
28
61
 
29
- ## [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
30
63
 
31
64
  ### Fixed
32
65
 
33
- - 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]
34
67
 
35
- ## [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
36
69
 
37
70
  ### Added
38
71
 
@@ -53,31 +86,31 @@
53
86
 
54
87
  - Remove unused class `AttestationTrustworthinessVerificationError`. [#412](https://github.com/cedarcode/webauthn-ruby/pull/412) [@soartec-lab]
55
88
 
56
- ## [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
57
90
 
58
91
  ### Added
59
92
 
60
- - 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]
61
94
 
62
95
  ### Fixed
63
96
 
64
- - Fix circular require warning between `webauthn/relying_party` and `webauthn/credential`. #389 [@bdewater]
65
- - 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]
66
99
 
67
100
  ### Changed
68
101
 
69
- - Inlined `base64` implementation. #402 [@olleolleolle]
70
- - 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]
71
104
 
72
105
  ## [v3.0.0] - 2023-02-15
73
106
 
74
107
  ### Added
75
108
 
76
- - Add the capability of handling appid extension #319 [@santiagorodriguez96]
77
- - 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]
78
111
  - Update dependencies to make gem compatible with OpenSSL 3.1 ([@bdewater],[@santiagorodriguez96])
79
112
 
80
- ## [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
81
114
 
82
115
  ### Added
83
116
 
@@ -87,19 +120,19 @@
87
120
 
88
121
  - Bumped minimum required Ruby version to 2.5 ([@bdewater])
89
122
 
90
- ## [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
91
124
 
92
125
  ### Added
93
126
 
94
127
  - Ability to define multiple relying parties with the introduction of the `WebAuthn::RelyingParty` class ([@padulafacundo], [@brauliomartinezlm])
95
128
 
96
- ## [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
97
130
 
98
131
  ### Added
99
132
 
100
133
  - Updated dependencies to make the gem compatible with openssl-3 [@ClearlyClaire]
101
134
 
102
- ## [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
103
136
 
104
137
  ### Added
105
138
 
@@ -107,9 +140,9 @@
107
140
 
108
141
  ### Removed
109
142
 
110
- - 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]
111
144
 
112
- ## [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
113
146
 
114
147
  ### Added
115
148
 
@@ -120,32 +153,32 @@
120
153
 
121
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])
122
155
 
123
- ## [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
124
157
 
125
158
  ### Fixed
126
159
 
127
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.
128
161
 
129
- ## [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
130
163
 
131
164
  ### Added
132
165
 
133
166
  - Support for ES256K credentials
134
167
  - `FakeClient#get` accepts `user_handle:` keyword argument ([@lgarron])
135
168
 
136
- ## [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
137
170
 
138
171
  ### Added
139
172
 
140
173
  - Ability to access extension outputs with `PublicKeyCredential#client_extension_outputs` and `PublicKeyCredential#authenticator_extension_outputs` ([@santiagorodriguez96])
141
174
 
142
- ## [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
143
176
 
144
177
  ### Fixed
145
178
 
146
179
  - Fixed compatibility with OpenSSL-C (libssl) v1.0.2 ([@santiagorodriguez96])
147
180
 
148
- ## [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
149
182
 
150
183
  ### Added
151
184
 
@@ -154,7 +187,7 @@
154
187
 
155
188
  Note: Expect possible breaking changes for "EXPERIMENTAL" features.
156
189
 
157
- ## [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
158
191
 
159
192
  ### Added
160
193
 
@@ -166,7 +199,7 @@ Note: Expect possible breaking changes for "EXPERIMENTAL" features.
166
199
 
167
200
  Note: Expect possible breaking changes for "EXPERIMENTAL" features.
168
201
 
169
- ## [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
170
203
 
171
204
  ### Added
172
205
 
@@ -218,7 +251,7 @@ string keys instead of snake_case symbol keys in the returned hash.
218
251
  - `WebAuthn::FakeClient#create` and `WebAuthn::FakeClient#get` better fakes a real client by not padding the
219
252
  returned base64url-encoded `id` value.
220
253
 
221
- ## [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
222
255
 
223
256
  ### Added
224
257
 
@@ -233,14 +266,14 @@ returned base64url-encoded `id` value.
233
266
  - Properly verify SafetyNet certificates from input ([#233](https://github.com/cedarcode/webauthn-ruby/pull/233)) ([@bdewater])
234
267
  - FakeClient default origin URL ([#242](https://github.com/cedarcode/webauthn-ruby/pull/242)) ([@kalebtesfay])
235
268
 
236
- ## [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
237
270
 
238
271
  ### Added
239
272
 
240
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])
241
274
  - Support [Signature Counter](https://www.w3.org/TR/webauthn/#signature-counter) verification ([@bdewater])
242
275
 
243
- ## [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
244
277
 
245
278
  ### Added
246
279
 
@@ -248,20 +281,20 @@ returned base64url-encoded `id` value.
248
281
  - Support RS1 (RSA w/ SHA-1) credentials. Off by default. Enable by adding `"RS1"` to `WebAuthn.configuration.algorithms` array.
249
282
  - Support PS256 (RSA Probabilistic Signature Scheme w/ SHA-256) credentials. On by default ([@bdewater])
250
283
 
251
- ## [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
252
285
 
253
286
  ### Added
254
287
 
255
288
  - Ability to configure Origin, RP ID and RP Name via `WebAuthn.configure`
256
289
 
257
- ## [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
258
291
 
259
292
  ### Added
260
293
 
261
294
  - Support 'tpm' attestation statement
262
295
  - Support RS256 credential public key
263
296
 
264
- ## [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
265
298
 
266
299
  ### Added
267
300
 
@@ -274,7 +307,7 @@ returned base64url-encoded `id` value.
274
307
  - Verify collectedClientData.tokenBinding format.
275
308
  - `WebAuthn.credential_creation_options` now accept `rp_name`, `user_id`, `user_name` and `display_name` as keyword arguments ([@bdewater])
276
309
 
277
- ## [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
278
311
 
279
312
  ### Added
280
313
 
@@ -290,7 +323,7 @@ Note #1: A `Credential` instance is what is returned in `WebAuthn::Authenticator
290
323
  Note #2: You don't need to do any convesion before passing the public key in `AuthenticatorAssertionResponse#verify`'s
291
324
  `allowed_credentials` argument, `#verify` is backwards-compatible and will handle both public key formats properly.
292
325
 
293
- ## [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
294
327
 
295
328
  ### Added
296
329
 
@@ -300,19 +333,19 @@ Note #2: You don't need to do any convesion before passing the public key in `Au
300
333
 
301
334
  - Verify matching AAGUID if needed when verifying `packed` attestation statements ([@bdewater])
302
335
 
303
- ## [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
304
337
 
305
338
  ### Added
306
339
 
307
340
  - Parse and make AuthenticatorData's extensionData available
308
341
 
309
- ## [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
310
343
 
311
344
  ### Added
312
345
 
313
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`
314
347
 
315
- ## [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
316
349
 
317
350
  ### Added
318
351
 
@@ -323,40 +356,40 @@ Note #2: You don't need to do any convesion before passing the public key in `Au
323
356
 
324
357
  - Make current raised exception errors a bit more meaningful to aid debugging
325
358
 
326
- ## [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
327
360
 
328
361
  ### Added
329
362
 
330
363
  - _Registration_ ceremony
331
364
  - `WebAuthn::AuthenticatorAttestationResponse` exposes attestation type and trust path via `#attestation_type` and `#attestation_trust_path` methods ([@bdewater])
332
365
 
333
- ## [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
334
367
 
335
368
  ### Added
336
369
 
337
370
  - `FakeAuthenticator` object is now exposed to help you test your WebAuthn implementation
338
371
 
339
- ## [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
340
373
 
341
374
  ### Added
342
375
 
343
376
  - Works with ruby 2.3 ([@bdewater])
344
377
 
345
- ## [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
346
379
 
347
380
  ### Added
348
381
 
349
382
  - _Registration_ ceremony
350
383
  - `WebAuthn::AuthenticatorAttestationResponse.valid?` supports `android-safetynet` attestation statements ([@bdewater])
351
384
 
352
- ## [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
353
386
 
354
387
  ### Added
355
388
 
356
389
  - _Registration_ ceremony
357
390
  - `WebAuthn::AuthenticatorAttestationResponse.valid?` supports `packed` attestation statements ([@sorah])
358
391
 
359
- ## [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
360
393
 
361
394
  ### Added
362
395
 
@@ -367,7 +400,7 @@ Note #2: You don't need to do any convesion before passing the public key in `Au
367
400
 
368
401
  Note: Both additions should help making it compatible with Chrome for Android 70+/Android Fingerprint pair.
369
402
 
370
- ## [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
371
404
 
372
405
  ### Added
373
406
 
@@ -376,7 +409,7 @@ Note: Both additions should help making it compatible with Chrome for Android 70
376
409
  - _Authentication_ ceremony
377
410
  - `WebAuthn::AuthenticatorAssertionResponse.valid?` optionally accepts rp_id.
378
411
 
379
- ## [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
380
413
 
381
414
  ### Added
382
415
 
@@ -390,7 +423,7 @@ Note: Both additions should help making it compatible with Chrome for Android 70
390
423
  - _Authentication_ ceremony
391
424
  - Use 32-byte challenge instead of 16-byte
392
425
 
393
- ## [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
394
427
 
395
428
  ### Added
396
429
 
@@ -418,7 +451,7 @@ Note: Both additions should help making it compatible with Chrome for Android 70
418
451
  - _Registration_ ceremony
419
452
  - `WebAuthn::AuthenticatorAttestationResponse.credential_id` (superseded by `WebAuthn::AuthenticatorAttestationResponse.credential`)
420
453
 
421
- ## [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
422
455
 
423
456
  ### Added
424
457
 
@@ -427,61 +460,25 @@ Note: Both additions should help making it compatible with Chrome for Android 70
427
460
  - `WebAuthn::AuthenticatorAttestationResponse.valid?` can be used to validate fido-u2f attestations returned by the browser
428
461
  - Works with ruby 2.5
429
462
 
430
- [v3.4.2]: https://github.com/cedarcode/webauthn-ruby/compare/v3.4.1...v3.4.2/
431
- [v3.4.1]: https://github.com/cedarcode/webauthn-ruby/compare/v3.4.0...v3.4.1/
432
- [v3.4.0]: https://github.com/cedarcode/webauthn-ruby/compare/v3.3.0...v3.4.0/
433
- [v3.3.0]: https://github.com/cedarcode/webauthn-ruby/compare/v3.2.2...v3.3.0/
434
- [v3.2.2]: https://github.com/cedarcode/webauthn-ruby/compare/v3.2.1...v3.2.2/
435
- [v3.2.1]: https://github.com/cedarcode/webauthn-ruby/compare/v3.2.0...v3.2.1/
436
- [v3.2.0]: https://github.com/cedarcode/webauthn-ruby/compare/v3.1.0...v3.2.0/
437
- [v3.1.0]: https://github.com/cedarcode/webauthn-ruby/compare/v3.0.0...v3.1.0/
438
- [v3.0.0]: https://github.com/cedarcode/webauthn-ruby/compare/2-stable...v3.0.0/
439
- [v3.0.0.alpha2]: https://github.com/cedarcode/webauthn-ruby/compare/2-stable...v3.0.0.alpha2/
440
- [v3.0.0.alpha1]: https://github.com/cedarcode/webauthn-ruby/compare/v2.3.0...v3.0.0.alpha1
441
- [v2.5.2]: https://github.com/cedarcode/webauthn-ruby/compare/v2.5.1...v2.5.2/
442
- [v2.5.1]: https://github.com/cedarcode/webauthn-ruby/compare/v2.5.0...v2.5.1/
443
- [v2.5.0]: https://github.com/cedarcode/webauthn-ruby/compare/v2.4.1...v2.5.0/
444
- [v2.4.1]: https://github.com/cedarcode/webauthn-ruby/compare/v2.4.0...v2.4.1/
445
- [v2.4.0]: https://github.com/cedarcode/webauthn-ruby/compare/v2.3.0...v2.4.0/
446
- [v2.3.0]: https://github.com/cedarcode/webauthn-ruby/compare/v2.2.1...v2.3.0/
447
- [v2.2.1]: https://github.com/cedarcode/webauthn-ruby/compare/v2.2.0...v2.2.1/
448
- [v2.2.0]: https://github.com/cedarcode/webauthn-ruby/compare/v2.1.0...v2.2.0/
449
- [v2.1.0]: https://github.com/cedarcode/webauthn-ruby/compare/v2.0.0...v2.1.0/
450
- [v2.0.0]: https://github.com/cedarcode/webauthn-ruby/compare/v1.18.0...v2.0.0/
451
- [v1.18.0]: https://github.com/cedarcode/webauthn-ruby/compare/v1.17.0...v1.18.0/
452
- [v1.17.0]: https://github.com/cedarcode/webauthn-ruby/compare/v1.16.0...v1.17.0/
453
- [v1.16.0]: https://github.com/cedarcode/webauthn-ruby/compare/v1.15.0...v1.16.0/
454
- [v1.15.0]: https://github.com/cedarcode/webauthn-ruby/compare/v1.14.0...v1.15.0/
455
- [v1.14.0]: https://github.com/cedarcode/webauthn-ruby/compare/v1.13.0...v1.14.0/
456
- [v1.13.0]: https://github.com/cedarcode/webauthn-ruby/compare/v1.12.0...v1.13.0/
457
- [v1.12.0]: https://github.com/cedarcode/webauthn-ruby/compare/v1.11.0...v1.12.0/
458
- [v1.11.0]: https://github.com/cedarcode/webauthn-ruby/compare/v1.10.0...v1.11.0/
459
- [v1.10.0]: https://github.com/cedarcode/webauthn-ruby/compare/v1.9.0...v1.10.0/
460
- [v1.9.0]: https://github.com/cedarcode/webauthn-ruby/compare/v1.8.0...v1.9.0/
461
- [v1.8.0]: https://github.com/cedarcode/webauthn-ruby/compare/v1.7.0...v1.8.0/
462
- [v1.7.0]: https://github.com/cedarcode/webauthn-ruby/compare/v1.6.0...v1.7.0/
463
- [v1.6.0]: https://github.com/cedarcode/webauthn-ruby/compare/v1.5.0...v1.6.0/
464
- [v1.5.0]: https://github.com/cedarcode/webauthn-ruby/compare/v1.4.0...v1.5.0/
465
- [v1.4.0]: https://github.com/cedarcode/webauthn-ruby/compare/v1.3.0...v1.4.0/
466
- [v1.3.0]: https://github.com/cedarcode/webauthn-ruby/compare/v1.2.0...v1.3.0/
467
- [v1.2.0]: https://github.com/cedarcode/webauthn-ruby/compare/v1.1.0...v1.2.0/
468
- [v1.1.0]: https://github.com/cedarcode/webauthn-ruby/compare/v1.0.0...v1.1.0/
469
- [v1.0.0]: https://github.com/cedarcode/webauthn-ruby/compare/v0.2.0...v1.0.0/
470
- [v0.2.0]: https://github.com/cedarcode/webauthn-ruby/compare/v0.1.0...v0.2.0/
471
- [v0.1.0]: https://github.com/cedarcode/webauthn-ruby/compare/v0.0.0...v0.1.0/
472
-
473
- [@brauliomartinezlm]: https://github.com/brauliomartinezlm
474
463
  [@bdewater]: https://github.com/bdewater
464
+ [@brauliomartinezlm]: https://github.com/brauliomartinezlm
465
+ [@ClearlyClaire]: https://github.com/ClearlyClaire
466
+ [@jdongelmans]: https://github.com/jdongelmans
475
467
  [@jdongelmans]: https://github.com/jdongelmans
468
+ [@juanarias93]: https://github.com/juanarias93
476
469
  [@kalebtesfay]: https://github.com/kalebtesfay
470
+ [@kingjan1999]: https://github.com/@kingjan1999
471
+ [@lgarron]: https://github.com/lgarron
477
472
  [@MaximeNdutiye]: https://github.com/MaximeNdutiye
478
- [@sorah]: https://github.com/sorah
479
- [@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
480
477
  [@padulafacundo]: https://github.com/padulafacundo
481
- [@santiagorodriguez96]: https://github.com/santiagorodriguez96
482
- [@lgarron]: https://github.com/lgarron
483
- [@juanarias93]: https://github.com/juanarias93
484
- [@kingjan1999]: https://github.com/@kingjan1999
485
- [@jdongelmans]: https://github.com/jdongelmans
486
478
  [@petergoldstein]: https://github.com/petergoldstein
487
- [@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
@@ -1,6 +1,3 @@
1
- > [!warning]
2
- > You are viewing the README for the development version of webauthn-ruby. For the current release version see https://github.com/cedarcode/webauthn-ruby/blob/3-stable/README.md.
3
-
4
1
  # webauthn-ruby
5
2
 
6
3
  ![banner](assets/webauthn-ruby.png)
@@ -41,7 +38,7 @@ _More_: [SECURITY](SECURITY.md)
41
38
 
42
39
  ### What is WebAuthn?
43
40
 
44
- 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.
45
42
 
46
43
  #### Good Intros
47
44
 
@@ -89,7 +86,7 @@ Or install it yourself as:
89
86
 
90
87
  ## Usage
91
88
 
92
- 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).
93
90
 
94
91
  If you are migrating an existing application from the legacy FIDO U2F JavaScript API to WebAuthn, also refer to
95
92
  [`docs/u2f_migration.md`](docs/u2f_migration.md).
@@ -107,6 +104,31 @@ WebAuthn.configure do |config|
107
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.
108
105
  config.allowed_origins = ["https://auth.example.com"]
109
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
+
110
132
  # Relying Party name for display purposes
111
133
  config.rp_name = "Example Inc."
112
134
 
@@ -115,7 +137,7 @@ WebAuthn.configure do |config|
115
137
  # interaction with the user.
116
138
  # This hint may be overridden by the browser.
117
139
  # https://www.w3.org/TR/webauthn/#dom-publickeycredentialcreationoptions-timeout
118
- # config.credential_options_timeout = 120_000
140
+ # config.credential_options_timeout = 300_000
119
141
 
120
142
  # You can optionally specify a different Relying Party ID
121
143
  # (https://www.w3.org/TR/webauthn/#relying-party-identifier)
@@ -147,14 +169,18 @@ end
147
169
  #### Initiation phase
148
170
 
149
171
  ```ruby
150
- # Generate and store the WebAuthn User ID the first time the user registers a credential
151
- if !user.webauthn_id
152
- 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)
153
175
  end
154
176
 
155
177
  options = WebAuthn::Credential.options_for_create(
156
- user: { id: user.webauthn_id, name: user.name },
157
- 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
+ }
158
184
  )
159
185
 
160
186
  # Store the newly generated challenge somewhere so you can have it
@@ -169,23 +195,24 @@ session[:creation_challenge] = options.challenge
169
195
  # If inside a Rails controller, `render json: options` will just work.
170
196
  # I.e. it will encode and convert the options to JSON automatically.
171
197
 
172
- # For your frontend code, you might find @github/webauthn-json npm package useful.
173
- # Especially for handling the necessary decoding of the options, and sending the
174
- # `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.
175
201
  ```
176
202
 
177
203
  #### Verification phase
178
204
 
179
205
  ```ruby
180
- # 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
181
207
  # in params[:publicKeyCredential]:
182
208
  webauthn_credential = WebAuthn::Credential.from_create(params[:publicKeyCredential])
183
209
 
184
210
  begin
185
- 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)
186
213
 
187
214
  # Store Credential ID, Credential Public Key and Sign Count for future authentications
188
- user.credentials.create!(
215
+ user.webauthn_credentials.create!(
189
216
  webauthn_id: webauthn_credential.id,
190
217
  public_key: webauthn_credential.public_key,
191
218
  sign_count: webauthn_credential.sign_count
@@ -202,7 +229,12 @@ end
202
229
  #### Initiation phase
203
230
 
204
231
  ```ruby
205
- 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
+ )
206
238
 
207
239
  # Store the newly generated challenge somewhere so you can have it
208
240
  # for the verification phase.
@@ -216,9 +248,9 @@ session[:authentication_challenge] = options.challenge
216
248
  # If inside a Rails controller, `render json: options` will just work.
217
249
  # I.e. it will encode and convert the options to JSON automatically.
218
250
 
219
- # For your frontend code, you might find @github/webauthn-json npm package useful.
220
- # Especially for handling the necessary decoding of the options, and sending the
221
- # `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.
222
254
  ```
223
255
 
224
256
  #### Verification phase
@@ -228,17 +260,18 @@ interface returned by the browser to the stored `credential_id`. The correspondi
228
260
  attributes must be passed as keyword arguments to the `verify` method call.
229
261
 
230
262
  ```ruby
231
- # 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
232
264
  # in params[:publicKeyCredential]:
233
265
  webauthn_credential = WebAuthn::Credential.from_get(params[:publicKeyCredential])
234
266
 
235
- stored_credential = user.credentials.find_by(webauthn_id: webauthn_credential.id)
267
+ stored_credential = user.webauthn_credentials.find_by(webauthn_id: webauthn_credential.id)
236
268
 
237
269
  begin
238
270
  webauthn_credential.verify(
239
271
  session[:authentication_challenge],
240
272
  public_key: stored_credential.public_key,
241
- 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.
242
275
  )
243
276
 
244
277
  # Update the stored credential sign count with the value from `webauthn_credential.sign_count`
@@ -266,16 +299,20 @@ Extensions can be requested in the initiation phase in both Credential Registrat
266
299
  ```ruby
267
300
  # Credential Registration
268
301
  creation_options = WebAuthn::Credential.options_for_create(
269
- user: { id: user.webauthn_id, name: user.name },
270
- exclude: user.credentials.map { |c| c.webauthn_id },
271
- 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
+ }
272
309
  )
273
310
 
274
311
  # OR
275
312
 
276
313
  # Credential Authentication
277
314
  options = WebAuthn::Credential.options_for_get(
278
- allow: user.credentials.map { |c| c.webauthn_id },
315
+ allow: user.webauthn_credentials.map { |c| c.webauthn_id },
279
316
  extensions: { appid: domain.to_s }
280
317
  )
281
318
  ```
@@ -305,14 +342,16 @@ A list of all currently defined extensions:
305
342
 
306
343
  ## API
307
344
 
308
- #### `WebAuthn.generate_user_id`
345
+ #### `WebAuthn.generate_user_handle`
309
346
 
310
347
  Generates a [WebAuthn User Handle](https://www.w3.org/TR/webauthn-2/#user-handle) that follows the WebAuthn spec recommendations.
311
348
 
312
349
  ```ruby
313
- WebAuthn.generate_user_id # "lWoMZTGf_ml2RoY5qPwbwrkxrvTqWjGOxEoYBgxft3zG-LlrICvE-y8bxFi06zMyIOyNsJoWx4Fa2TOqoRmnxA"
350
+ WebAuthn.generate_user_handle # "lWoMZTGf_ml2RoY5qPwbwrkxrvTqWjGOxEoYBgxft3zG-LlrICvE-y8bxFi06zMyIOyNsJoWx4Fa2TOqoRmnxA"
314
351
  ```
315
352
 
353
+ > `WebAuthn.generate_user_id` is also available as an alias.
354
+
316
355
  #### `WebAuthn::Credential.options_for_create(options)`
317
356
 
318
357
  Helper method to build the necessary [PublicKeyCredentialCreationOptions](https://www.w3.org/TR/webauthn-2/#dictdef-publickeycredentialcreationoptions)
@@ -320,8 +359,8 @@ to be used in the client-side code to call `navigator.credentials.create({ "publ
320
359
 
321
360
  ```ruby
322
361
  creation_options = WebAuthn::Credential.options_for_create(
323
- user: { id: user.webauthn_id, name: user.name }
324
- 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 }
325
364
  )
326
365
 
327
366
  # Store the newly generated challenge somewhere so you can have it
@@ -343,7 +382,7 @@ Helper method to build the necessary [PublicKeyCredentialRequestOptions](https:/
343
382
  to be used in the client-side code to call `navigator.credentials.get({ "publicKey": publicKeyCredentialRequestOptions })`.
344
383
 
345
384
  ```ruby
346
- 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 })
347
386
 
348
387
  # Store the newly generated challenge somewhere so you can have it
349
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,15 +50,17 @@ 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,
55
61
  :legacy_u2f_appid
56
62
 
57
- attr_reader :attestation_root_certificates_finders, :origin
63
+ attr_reader :attestation_root_certificates_finders
58
64
 
59
65
  # This is the user-data encoder.
60
66
  # Used to decode user input and to encode data provided to the user.
@@ -121,13 +127,24 @@ module WebAuthn
121
127
  end
122
128
  end
123
129
 
130
+ # DEPRECATED: This method will be removed in future.
131
+ def origin
132
+ warn(
133
+ "DEPRECATION WARNING: `WebAuthn.origin` is deprecated and returns `nil` " \
134
+ "when `WebAuthn.allowed_origins` contains more than one origin. " \
135
+ "It will be removed in future. Please use `WebAuthn.allowed_origins` instead."
136
+ )
137
+
138
+ allowed_origins.first if allowed_origins&.size == 1
139
+ end
140
+
124
141
  # DEPRECATED: This method will be removed in future.
125
142
  def origin=(new_origin)
126
143
  return if new_origin.nil?
127
144
 
128
145
  warn(
129
- "DEPRECATION WARNING: `WebAuthn.origin` is deprecated and will be removed in future. "\
130
- "Please use `WebAuthn.allowed_origins` instead "\
146
+ "DEPRECATION WARNING: `WebAuthn.origin=` is deprecated and will be removed in future. "\
147
+ "Please use `WebAuthn.allowed_origins=` instead "\
131
148
  "that also allows configuring multiple origins per Relying Party"
132
149
  )
133
150
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module WebAuthn
4
- VERSION = "3.4.2"
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.2
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-09-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: []