Hot on the heels of the last major release, v13 introduces support for registration hints! Refined types and improved attestation trust anchor verification are also included. Last but not least, we say goodbye to one of the project's packages for better docs and fewer dependencies to install. Read on for more information, including refactor advice for dealing with the retirement of @simplewebauthn/types.
Changes:
- [server] A new
preferredAuthenticatorType
argument can be set when callinggenerateRegistrationOptions()
to generate options that encourage the browser to direct the user to register one of three types of authenticators:'securityKey'
,'localDevice'
, or'remoteDevice'
(a.k.a. opinionated WebAuthn hints support) (#653) - [browser]
startRegistration()
will recognizehints
if specified inoptionsJSON
(#652) - [server] Attestation verification now recognizes intermediate certificates as trust anchors (#650)
- [browser] [server] The types previously maintained in the types package are now included within the browser and server packages. See Breaking Changes below for more info (#655)
Its types will now be included directly in @simplewebauthn/browser and @simplewebauthn/server.
To refactor existing imports from /types, simply import them from /browser or /server instead:
Before:
import type {
AuthenticationResponseJSON,
RegistrationResponseJSON,
WebAuthnCredential,
} from '@simplewebauthn/types'; // <--
After:
import type {
AuthenticationResponseJSON,
RegistrationResponseJSON,
WebAuthnCredential,
} from '@simplewebauthn/server'; // <--
The benefits of indirect attestation are too minimal to be useful for Relying Parties. In practice
it is almost never used over ignoring the concept completely with 'none'
or needing to be
intentional and setting 'direct'
.
RP's that have been specifying attestationType: 'indirect'
when calling
generateRegistrationOptions()
will need to refactor their code to either omit
attestationType
(generateRegistrationOptions()
will default to attestationType: 'none'
) or set
attestationType: 'direct'
instead:
Before:
const options = await generateRegistrationOptions({
// ...
attestationType: 'indirect',
});
After:
const options = await generateRegistrationOptions({
// ...
});
-or-
const options = await generateRegistrationOptions({
// ...
attestationType: 'direct',
});
All SimpleWebAuthn packages are now available for installation from the JavaScript Registry (JSR)! JSR is an "open-source package registry for modern JavaScript and TypeScript" - you can read more about this new package registry and its ESM-centric capabilities here.
All packages in v12.0.0 are functionally identical to v11.0.0! And JSR package hosting is in
addition to existing package hosting on NPM. Nothing changes about package installation via
npm install
. Read on for more information.
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
- [browser] [server] [types] All packages can now be installed from JSR wherever JSR imports are supported (#634)
- [browser] Deno projects using frameworks like Fresh can now import and use @simplewebauthn/browser (#634)
To install from JSR, use npx jsr add @simplewebauthn/...
or deno add jsr:@simplewebauthn/...
depending on which package manager is available.
npx jsr add @simplewebauthn/browser
npx jsr add @simplewebauthn/server
npx jsr add @simplewebauthn/types
deno add jsr:@simplewebauthn/browser
deno add jsr:@simplewebauthn/server
deno add jsr:@simplewebauthn/types
v12.0.0 officially deprecates importing SimpleWebAuthn from deno.land/x. See Breaking Changes below for refactor guidance.
Importing SimpleWebAuthn packages from "https://deno.land/x/simplewebauthn/..."
URLs is no longer
supported. Please use Deno's native support for JSR imports instead, available in projects running
Deno v1.42 and higher.
Before:
import { generateAuthenticationOptions } from 'https://deno.land/x/simplewebauthn/deno/server.ts';
After:
import { generateAuthenticationOptions } from 'jsr:@simplewebauthn/server';
Alternatively, use deno add
to install these packages from
JSR:
# Deno v1.42 and higher
deno add jsr:@simplewebauthn/server
import { generateAuthenticationOptions } from '@simplewebauthn/server';
Say hello to support for automatic passkey registration, support for valid conditional UI <input>
elements stashed away in web components, and to the new WebAuthnCredential
type that modernizes
some logic within.
There are some breaking changes in this release! Please see Breaking Changes below for refactor guidance.
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
- [browser] [server] A new
useAutoRegister
argument has been added tostartRegistration()
to support attempts to automatically register passkeys for users who just completed non-passkey auth.verifyRegistrationResponse()
has gained a newrequireUserPresence
option that can be set tofalse
when verifying responses fromstartRegistration({ useAutoRegister: true, ... })
(#623) - [browser] A new
verifyBrowserAutofillInput
argument has been added tostartAuthentication()
to disable throwing an error when a correctly configured<input>
element cannot be found (but perhaps a valid one is present in a web component shadow's DOM) (#621) - [server] [types] The
AuthenticatorDevice
type has been renamed toWebAuthnCredential
and has had its properties renamed. The return value out ofverifyRegistrationResponse()
and corresponding inputs intoverifyAuthenticationResponse()
have been updated accordingly. See Breaking Changes below for refactor guidance (#625) - [server]
verifyRegistrationResponse()
now verifies that the authenticator data AAGUID matches the leaf cert'sid-fido-gen-ce-aaguid
extension AAGUID when it is present (#609) - [server] TPM attestation verification recognizes the corrected TPM manufacturer identifier for IBM (#610)
- [server] Types for the defunct authenticator extensions
uvm
anddpk
have been removed (#611)
[browser] Positional arguments in startRegistration()
and startAuthentication()
have been replaced by a single object
Property names in the object match the names of the previously-positional arguments. To update existing implementations, wrap existing options in an object with corresponding properties:
Before:
startRegistration(options);
startAuthentication(options, true);
After:
startRegistration({ optionsJSON: options });
startAuthentication({ optionsJSON: options, useBrowserAutofill: true });
AuthenticatorDevice.credentialID
and AuthenticatorDevice.credentialPublicKey
have been shortened
to WebAuthnCredential.id
and WebAuthnCredential.publicKey
respectively.
verifyRegistrationResponse()
has been updated accordingly to return a new credential
value of
type WebAuthnCredential
. Update code that stores credentialID
, credentialPublicKey
, and
counter
out of verifyRegistrationResponse()
to store credential.id
, credential.publicKey
,
and credential.counter
instead:
Before:
const { registrationInfo } = await verifyRegistrationResponse({...});
storeInDatabase(
registrationInfo.credentialID,
registrationInfo.credentialPublicKey,
registrationInfo.counter,
body.response.transports,
);
After:
const { registrationInfo } = await verifyRegistrationResponse({...});
storeInDatabase(
registrationInfo.credential.id,
registrationInfo.credential.publicKey,
registrationInfo.credential.counter,
registrationInfo.credential.transports,
);
Update calls to verifyAuthenticationResponse()
to match the new credential
argument that
replaces the authenticator
argument:
Before:
import { AuthenticatorDevice } from '@simplewebauthn/types';
const authenticator: AuthenticatorDevice = {
credentialID: ...,
credentialPublicKey: ...,
counter: 0,
transports: [...],
};
const verification = await verifyAuthenticationResponse({
// ...
authenticator,
});
After:
import { WebAuthnCredential } from '@simplewebauthn/types';
const credential: WebAuthnCredential = {
id: ...,
publicKey: ...,
counter: 0,
transports: [...],
};
const verification = await verifyAuthenticationResponse({
// ...
credential,
});
- @simplewebauthn/[email protected]
- [server]
isoCrypto.verify()
now has better support for signature verification with ECC public keys using P-256, P-385, and P-521 curves (#594, with thanks to @nlordell)
Thanks for everything, Node 16 and Node 18, but it's time to move on! The headlining change of this release is the targeting of Node LTS v20+ as the minimum Node runtime. Additional developer-centric quality-of-life changes have also been made in the name of streamlining use of SimpleWebAuthn on both the back end and front end.
This release is packed with updates, so buckle up! Refactor advice for breaking changes is, as always, offered below.
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
- [server] The minimum supported Node version has been raised to Node v20 (#531)
- [server]
user.displayName
now defaults to an empty string if a value is not specified foruserDisplayName
when callinggenerateRegistrationOptions()
(#538) - [browser] The
browserSupportsWebAuthnAutofill()
helper will no longer break in environments in whichPublicKeyCredential
is not present (#557, with thanks to @clarafitzgerald)
- [server] The following breaking changes were made in PR
#529:
generateRegistrationOptions()
now expectsBase64URLString
for excluded credential IDsgenerateAuthenticationOptions()
now expectsBase64URLString
for allowed credential IDscredentialID
returned from response verification methods is now aBase64URLString
AuthenticatorDevice.credentialID
is now aBase64URLString
isoBase64URL.isBase64url()
is now calledisoBase64URL.isBase64URL()
- [browser, server] The following breaking changes were made in PR
#552:
generateRegistrationOptions()
now accepts an optionalUint8Array
instead of astring
foruserID
isoBase64URL.toString()
andisoBase64URL.fromString()
have been renamedgenerateRegistrationOptions()
will now generate random user IDsuser.id
is now treated like a base64url string instartRegistration()
userHandle
is now treated like a base64url string instartAuthentication()
- [server]
rpID
is now a required argument when callinggenerateAuthenticationOptions()
(#555)
The isoBase64URL
helper can be used to massage Uint8Array
credential IDs into base64url strings:
Before
const opts = await generateRegistrationOptions({
// ...
excludeCredentials: devices.map((dev) => ({
id: dev.credentialID, // type: Uint8Array
type: 'public-key',
transports: dev.transports,
})),
});
After
import { isoBase64URL } from '@simplewebauthn/server/helpers';
const opts = await generateRegistrationOptions({
// ...
excludeCredentials: devices.map((dev) => ({
id: isoBase64URL.fromBuffer(dev.credentialID), // type: string
transports: dev.transports,
})),
});
The type
argument is no longer needed either.
Similarly, the isoBase64URL
helper can also be used during auth to massage Uint8Array
credential
IDs into base64url strings:
Before
const opts = await generateAuthenticationOptions({
// ...
allowCredentials: devices.map((dev) => ({
id: dev.credentialID, // type: Uint8Array
type: 'public-key',
transports: dev.transports,
})),
});
After
import { isoBase64URL } from '@simplewebauthn/server/helpers';
const opts = await generateAuthenticationOptions({
// ...
allowCredentials: devices.map((dev) => ({
id: isoBase64URL.fromBuffer(dev.credentialID), // type: Base64URLString (a.k.a string)
transports: dev.transports,
})),
});
The type
argument is no longer needed either.
It is no longer necessary to manually stringify credentialID
out of response verification methods:
Before
import { isoBase64URL } from '@simplewebauthn/server/helpers';
// Registration
const { verified, registrationInfo } = await verifyRegistrationResponse({ ... });
if (verified && registrationInfo) {
const { credentialID } = registrationInfo;
await storeInDatabase({ credIDString: isoBase64URL.fromBuffer(credentialID), ... });
}
// Authentication
const { verified, authenticationInfo } = await verifyAuthenticationResponse({ ... });
if (verified && authenticationInfo) {
const { newCounter, credentialID } = authenticationInfo;
dbAuthenticator.counter = authenticationInfo.newCounter;
await updateCounterInDatabase({
credIDString: isoBase64URL.fromBuffer(credentialID),
newCounter,
});
}
After
// Registration
const { verified, registrationInfo } = await verifyRegistrationResponse({ ... });
if (verified && registrationInfo) {
const { credentialID } = registrationInfo;
await storeInDatabase({ credIDString: credentialID, ... });
}
// Authentication
const { verified, authenticationInfo } = await verifyAuthenticationResponse({ ... });
if (verified && authenticationInfo) {
const { newCounter, credentialID } = authenticationInfo;
dbAuthenticator.counter = authenticationInfo.newCounter;
await updateCounterInDatabase({ credIDString: credentialID, newCounter });
}
Calls to verifyAuthenticationResponse()
will need to be updated to encode the credential ID to a
base64url string:
Before
const verification = await verifyAuthenticationResponse({
// ...
authenticator: {
// ...
credentialID: credIDBytes,
},
});
After
import { isoBase64URL } from '@simplewebauthn/server/helpers';
const verification = await verifyAuthenticationResponse({
// ...
authenticator: {
// ...
credentialID: isoBase64URL.fromBuffer(credIDBytes),
},
});
Note the capitalization change from "url" to "URL" in the method name. Update calls to this method accordingly.
A random identifier will now be generated when a value is not provided for the now-optional userID
argument when calling generateRegistrationOptions()
. This identifier will be base64url-encoded
string of 32 random bytes. RPs that wish to take advantage of this can simply omit this
argument.
Additionally, startRegistration()
will base64url-decode user.id
before calling WebAuthn. During
auth startAuthentication()
will base64url-encode userHandle
in the returned credential. This
should be a transparent change for RP's that simply feed @simplewebauthn/server options output
into the corresponding @simplewebauthn/browser methods.
However, RP's that wish to continue generating their own user identifiers will need to take additional steps to ensure they get back user IDs in the expected format after authentication.
Before (SimpleWebAuthn v9)
// @simplewebauthn/server v9.x
const opts = generateRegistrationOptions({
// ...
userID: 'randomUserID',
});
// @simplewebauthn/browser v9.x
const credential = await startAuthentication(...);
sendToServer(credential);
// @simplewebauthn/server v9.x
const credential = await receiveFromBrowser();
console.log(
credential.response.userhandle, // 'randomUserID'
);
After (SimpleWebAuthn v10)
// @simplewebauthn/server v10.x
import { isoUint8Array } from '@simplewebauthn/server/helpers';
const opts = generateRegistrationOptions({
// ...
userID: isoUint8Array.fromUTF8String('randomUserID'),
});
// @simplewebauthn/browser v10.x
const credential = await startAuthentication(...);
sendToServer(credential);
// @simplewebauthn/server v10.x
import { isoBase64URL } from '@simplewebauthn/server/helpers';
const credential = await receiveFromBrowser();
console.log(
isoBase64URL.toUTF8String(credential.response.userhandle), // 'randomUserID'
);
The method names have been updated to reflect the use of UTF-8 string encoding:
Before:
const foo = isoBase64URL.toString('...');
const bar = isoBase64URL.fromString('...');
After:
const foo = isoBase64URL.toUTF8String('...');
const bar = isoBase64URL.fromUTF8String('...');
Update calls to this method to specify the same rpID
as passed into
generateRegistrationOptions()
:
Before
generateRegistrationOptions({ rpID: 'example.com', ... });
generateAuthenticationOptions();
After
generateRegistrationOptions({ rpID: 'example.com', ... });
generateAuthenticationOptions({ rpID: 'example.com' });
- @simplewebauthn/[email protected]
- [server] Fixed
"Cannot find module 'cbor-x/index-no-eval' or its corresponding type declarations"
build errors when transpiling TypeScript projects using @simplewebauthn/server (#521)
- @simplewebauthn/[email protected]
- [server] Improved support for Next.js Edge runtime (#518, with thanks to @balazsorban44)
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
- [server] Fixed an issue with use with CBOR handling in runtime environments that restrict use
of
eval()
(#511, with thanks to @Maronato) - [browser, types] Monorepo version sync
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
- [types] The
@simplewebauthn/typescript-types
package has been renamed to@simplewebauthn/types
(#508)
- Any reference to
@simplwebauthn/typescript-types
will need to be replaced with the new package name@simplewebauthn/types
:
Before:
import { ... } from '@simplwebauthn/typescript-types';
After:
$> npm uninstall @simplewebauthn/typescript-types
$> npm install -D @simplewebauthn/types
import { ... } from '@simplwebauthn/types';
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
- [browser] The
WebAuthnError
class can now be imported from@simplewebauthn/browser
for simpler error detection and handling when callingstartRegistration()
andstartAuthentication()
(#505, with thanks to @zoontek) - [server] The
COSEPublicKeyEC2
,COSEPublicKeyOKP
, andCOSEPublicKeyRSA
types can now be imported from@simplwebauthn/server/helpers
to help type possible return values fromdecodeCredentialPublicKey()
(#504, with thanks to @mmv08) - [server] Custom challenge strings passed to
generateRegistrationOptions()
will now be treated as UTF-8 strings to align with the existing behavior ofgenerateAuthenticationOptions()
(#507)
- @simplewebauthn/[email protected]
- [server] Updated dependencies to fix an issue with ASN.1 parsing when calling
verifyAuthenticationResponse()
(#499)
- @simplewebauthn/[email protected]
- [server] Use of the Web Crypto API in edge runtimes has been improved (#472)
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
- [server] The library will now try to use
globalThis.crypto
first before trying to import Node'snode:crypto
as a fallback (#468) - [browser, types] Version sync
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
- [server, types]
deno vendor
will no longer error out because typescript-types/src/dom.ts is missing (#466) - [server] Authenticator data will now be preserved after bad CBOR encoding is detected and temporarily fixed when handling security key responses from Firefox (#465)
- [browser] Version sync due to changes in typescript-types
- @simplewebauthn/[email protected]
- [server] The cbor-x dependency is now used without pulling in the Node-specific
stream
API for better Web API environment compatibility (#455, with thanks to @Maronato)
- @simplewebauthn/[email protected]
- [browser] Calling
startAuthentication(..., true)
to set up conditional UI will now require the"webauthn"
value in an input'sautocomplete="..."
be either the only value or the last value (#451)
- @simplewebauthn/[email protected]
- [browser] The
WebAuthnAbortService
singleton can now be imported, with acancelCeremony()
method that can be called to manually cancel any active WebAuthn ceremonies. This can be used by developers building projects that use client-side routing to better control the behavior of their UX in response to router navigation events. (#449)
- @simplewebauthn/[email protected]
- [browser]
startRegistration()
will visibly warn in the browser console when a WebAuthn API method call errors out in a way that is likely due to a browser extension intercepting the API (#447)
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
- [browser]
startRegistration()
will no longer error out on registration responses generated by the 1Password browser extension (#443, with thanks to @unix) - [browser] Helper methods
base64URLStringToBuffer()
andbufferToBase64URLString()
are now exported from@simplewebauthn/browser
(#444) - [server]
verifyRegistrationResponse()
andverifyAuthenticationResponse()
now accept a newexpectedType
argument that can be used to, for example, verify Secure Payment Confirmation responses (#436, with thanks to @fabiancook) - [server] Responses containing malformed authenticator data returned from Firefox 117 will no longer raise an error (#441)
- @simplewebauthn/[email protected]
- [server] Debug logger output from
MetadataService
has been disabled (#434)
- @simplewebauthn/[email protected]
- [server] The
expectedChallenge
argument forverifyRegistrationResponse()
andverifyAuthenticationResponse()
methods now also accept asynchronous methods (#432, with thanks to @jordanbtucker)
- @simplewebauthn/[email protected]
- [browser] The NPM package now targets ES2021 for support in older browsers like Safari 13.1 (#429)
- @simplewebauthn/[email protected]
- [server] Node projects with
"type": "module"
in their package.json will no longer error out when trying to use methods that leverage the Crypto APIs (#428)
This major release marks the completion of a long journey that started with the release of v7.0.0: SimpleWebAuthn is now available for use in non-Node projects! 🎉
SimpleWebAuthn debuted in mid-2020 as a combination of libraries aiming to make WebAuthn simpler to use across browsers and "NodeJS + CommonJS" applications. Since then NodeJS has evolved to gain ESM support, and additional JavaScript and TypeScript runtimes have debuted that offer ESM-centric, TypeScript-first alternatives while also implementing Web APIs to offer a more consistent and capable execution environment for developers.
I've wanted to make this project available to developers using these Node alternatives to help them get past some of WebAuthn's rough spots. Today I'm happy to announce that this goal has been achieved! 😌
See the Changes below for more information, as well as additional information on breaking changes made in this release.
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
- [server] [typescript-types] SimpleWebAuthn can now also be used in runtimes other than Node.
Deno is now a first-class runtime for this project alongside Node
(#425)
- The following list of runtimes are officially supported:
- (Existing) NodeJS using CommonJS
- (Existing) NodeJS using ECMAScript Modules (ESM)
- (New) Deno @ https://deno.land/x/simplewebauthn
- The following list of runtimes are periodically tested but unofficially supported:
- (New) CloudFlare Workers
- (New) Bun
- The following list of runtimes are officially supported:
- [browser] Version sync
- [server]
generateRegistrationOptions()
andgenerateAuthenticationOptions()
are now asynchronous methods. Refactor calls to these methods to handle thePromise
that's now returned in whatever way is appropriate for your project. - [server]
generateChallenge()
(in@simplewebauthn/server/helpers
) is now an asynchronous method. Refactor calls to this method to handle thePromise
that's now returned in whatever way is appropriate for your project.
Packages:
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
Changes:
- [browser] [typescript-types]
AuthenticatorAttestationResponseJSON
now includes additional, optionalpublicKeyAlgorithm
,publicKey
, andauthenticatorData
convenience values that track JSON interface changes in WebAuthn L3 draft (#400) - [iso-crypto] Version sync
- [server]
verifyRegistrationResponse()
andverifyAuthenticationResponse()
now return the matched origin and RP ID in their to output to help RP's that use the same verification logic with multiple origins and RP ID's understand where a response was generated and for which RP (#415) - [typescript-types]
"smart-card"
is now a recognized value forAuthenticatorTransportFuture
(#399)
Packages:
- @simplewebauthn/[email protected]
Changes:
- [server] The
AttestationStatement.size
property declaration is now more tolerant of older versions of TypeScript - [server] Declared minimum supported TypeScript version of 4.4+
Packages:
- @simplewebauthn/[email protected]
Changes:
- [server] Improved signature verification of the latest FIDO MDS JWTs (#390)
Packages:
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
Changes:
- [server]
generateRegistrationOptions()
defaults to-8
,-7
, and-257
for supported public key algorithms (#361) - [browser] [iso-webcrypto] [server] Users will no longer need to also
npm install @simplewebauthn/typescript-types
to pull in type definitions when using these libraries (#370) - [browser] Errors raised by
startRegistration()
andstartAuthentication()
now include acode
property to help programmatically detect identified errors. A newcause
property is also populated that will always include the original error raised by the WebAuthn API call (#367) - [browser] Aborting conditional UI (i.e. calling
startAuthentication(..., true)
and then subsequently callingstartAuthentication()
for modal UI) will now throw anAbortError
instead of astring
(#371)
Packages:
- @simplewebauthn/[email protected]
Changes:
- [browser]
startRegistration()
andstartAuthentication()
now pass through allNotAllowedError
's without trying to interpret what caused them (#353)
Packages:
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
Changes:
- [server] Update dependencies for better deduping in projects using @simplewebauthn/server (#341)
- [browser] Version sync
- [iso-webcrypto] Version sync
The highlight of this release is the rearchitecture of @simplewebauthn/server to start allowing
it to be used in more environments than Node. This was accomplished by refactoring the library
completely away from Node's Buffer
type and crypto
package, and instead leveraging Uint8Array
and the WebCrypto Web API for all
cryptographic operations. This means that, hypothetically, this library can now also work in any
non-Node environment that provides access to the WebCrypto API on the global crypto
object.
Existing Node support is still first-class! In fact because @simplewebauth/server still builds to CommonJS it will continue to be tricky to incorporate the library in non-Node, ESM-only environments that do not support CommonJS modules (whether natively, via a bundler, etc...) A future update will attempt to fix this to offer better support for use in ESM-only projects with support for WebCrypto (e.g. Deno).
Please read all of the changes below! There are significant breaking changes in this update and additional information has been included to help adapt existing projects to the newest version of these libraries.
Packages:
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
Changes:
- [server] A new "isomorphic" library architecture allows for use of this library in non-Node environments. In addition, the library now targets Node 16 and above (#299)
- [server]
@simplewebauthn/server/helpers
now includes several new helpers for working with WebAuthn-related data types that should work in all run times:isoCBOR
for working with CBOR-encoded valuesisoCrypto
for leveraging the WebCrypto API when working with various WebAuthn/FIDO2 data structuresisoBase64URL
for encoding and decoding values into base64url (with optional base64 support)isoUint8Array
for working withUint8Array
scose
for working with COSE-related methods and types
- [server] Certificate chains using self-signed X.509 root certificates now validate more reliably (#310)
- [server] Code execution times for some common use cases are approximately 60-90% faster (#311, #315)
- [iso-webcrypto] This new library helps @simplewebauthn/server reference the WebCrypto API in more environments than Node. This package is available on NPM, but it is not officially supported for use outside of @simplewebauthn/server!
- [server] The following values returned from
verifyRegistrationResponse()
are now aUint8Array
instead of aBuffer
. They will need to be passed intoBuffer.from(...)
to convert them toBuffer
if needed:aaguid
authData
clientDataHash
credentialID
credentialPublicKey
rpIdHash
- [server] The following values returned from
verifyAuthenticationResponse()
are now aUint8Array
instead of aBuffer
. They will need to be passed intoBuffer.from(...)
to convert them toBuffer
if needed:credentialID
- [server] The
isBase64URLString()
helper is nowisoBase64URL.isBase64url()
- [server] The
decodeCborFirst()
helper is nowisoCBOR.decodeFirst()
- [server] The
convertPublicKeyToPEM()
helper has been removed - [typescript-types] [server] [browser] New JSON-serialization-friendly data structures added to
the WebAuthn L3 spec have been preemptively mapped into this project. Some types, values, and
methods have been refactored or replaced accordingly
(#320):
- The
RegistrationCredentialJSON
type has been replaced by theRegistrationResponseJSON
type - The
AuthenticationCredentialJSON
type has been replaced by theAuthenticationResponseJSON
type RegistrationCredentialJSON.transports
has been relocated intoRegistrationResponseJSON.response.transports
to mirror response structure in the WebAuthn spec- The
verifyRegistrationResponse()
method has had itscredential
argument renamed toresponse
- The
verifyAuthenticationResponse()
method has had itscredential
argument renamed toresponse
- The
- [server]
generateRegistrationOptions()
now marks user verification as"preferred"
during registration and authentication (to reduce some user friction at the browser+authenticator level), and requires user verification during response verification. See below for refactor tips (#307)
Refactor Tips
RP's implementing a second-factor flow with WebAuthn, where UV is not important (because username+password are provided before WebAuthn is leveraged for the second factor), should not require user verification when verifying responses:Before
const verification = await verifyRegistrationResponse({
credential: attestationFIDOU2F,
// ...
});
After
const verification = await verifyRegistrationResponse({
credential: attestationFIDOU2F,
// ...
requireUserVerification: false,
});
Before
const verification = await verifyAuthenticationResponse({
credential: assertionResponse,
// ...
});
After
const verification = await verifyAuthenticationResponse({
credential: assertionResponse,
// ...
requireUserVerification: false,
});
- [server]
generateRegistrationOptions()
now defaults to preferring the creation of discoverable credentials. See below for refactor tips (#324)
Refactor Tips
RP's that do not require support for discoverable credentials from authenticators will need to update their calls to `generateRegistrationOptions()` accordingly:Before
const options = generateRegistrationOptions({
rpName: 'SimpleWebAuthn',
rpID: 'simplewebauthn.dev',
userID: '1234',
userName: 'usernameHere',
});
After
const options = generateRegistrationOptions({
rpName: 'SimpleWebAuthn',
rpID: 'simplewebauthn.dev',
userID: '1234',
userName: 'usernameHere',
authenticatorSelection: {
// See https://www.w3.org/TR/webauthn-2/#enumdef-residentkeyrequirement
residentKey: 'discouraged',
},
});
Packages:
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
Changes:
- [browser]
browserSupportsWebAuthnAutofill()
no longer supports the old Chrome Canary way of testing for conditional UI support (#298) - [server] Version sync
Packages:
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
Changes:
- [browser] Multiple calls to
startRegistration()
andstartAuthentication()
will now more reliably cancel the preceding call (#275) - [server] Version sync
- [testing] Version sync
- [typescript-types] Version sync
Packages:
- @simplewebauthn/[email protected]
Changes:
- [server] The value of the user verification flag is now returned from
verifyAuthenticationResponse()
asauthenticationInfo.userVerified
, similar to howverifyRegistrationResponse()
currently returns this value (#263)
Packages:
- @simplewebauthn/[email protected]
Changes:
- [server] Improve support for requiring resident keys when targeting WebAuthn L1 (#259)
- [server] Encourage authenticators to produce Ed25519 credential keypairs when supported (#261)
This release also marks the return of the library's ability to pass FIDO Conformance! Adding Ed25519 signature verification (see below) finally allowed the library to pass all required tests, and nearly all optional tests.
Packages:
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
Changes:
- [server] Signatures can now be verified with OKP public keys that use the Ed25519 curve and EDDSA algorithm (#256)
- [testing] Version sync
- [typescript-types] Version sync
- [server]
verifyAuthenticationResponse()
now returnsPromise<VerifiedAuthenticationResponse>
instead ofVerifiedAuthenticationResponse
(#256)
Update your existing calls to verifyAuthenticationResponse()
to handle the values resolved by the
promises, whether with .then()
or await
depending on your code structure:
Before:
const verification = verifyAuthenticationResponse({
// ...
});
After:
const verification = await verifyAuthenticationResponse({
// ...
});
- [browser]
browserSupportsWebauthn()
has been renamed tobrowserSupportsWebAuthn()
(#257)
Update calls to browserSupportsWebauthn()
to capitalize the "A" in "WebAuthn":
Before:
if (browserSupportsWebauthn()) {
// ...
}
After:
if (browserSupportsWebAuthn()) {
// ...
}
Packages:
- @simplewebauthn/[email protected]
Changes:
- [server] Support FIDO Conformance user verification requirements (#254)
To leverage these requirements (as might be the case for RP's seeking FIDO certification), update
your calls to verifyAuthenticationResponse()
to replace requireUserVerification
with the new
advancedFIDOConfig.userVerification
option:
Before:
const verification = verifyAuthenticationResponse({
// ...
requireUserVerification: true,
});
After
const verification = verifyAuthenticationResponse({
// ...
advancedFIDOConfig: {
// UserVerificationRequirement: 'required' | 'preferred' | 'discouraged'
userVerification: 'required',
},
});
Setting advancedFIDOConfig.userVerification
to 'required'
will only require the uv
flag to be
true; up
flag may be false
. Setting it to 'preferred'
or 'discouraged'
will allow both up
and uv
to be false
during verification.
- [server] Rename the
devicePublicKey
property on theAuthenticationExtensionsAuthenticatorOutputs
type todevicePubKey
(#243; no one supports this yet so it's not a breaking change)
Packages:
- @simplewebauthn/[email protected]
Changes:
- [server] Enhance compliance with current FIDO conformance requirements (#249, #251)
- [server] Minor performance improvements (#150)
Packages:
- @simplewebauthn/[email protected]
Changes:
- [server] Remove support for the following defunct FIDO metadata authentication algorithms:
"rsa_emsa_pkcs1_sha256_raw"
,"rsa_emsa_pkcs1_sha256_der"
,"sm2_sm3_raw"
(#245) - [server] Update remaining FIDO metadata constants to match v2.2 of the FIDO Registry of Predefined Values (#244)
Packages:
- @simplewebauthn/[email protected]
Changes:
- [server] Add support for
"rsa_emsa_pkcs1_sha256_raw"
and"rsa_emsa_pkcs1_sha256_der"
authentication algorithms in FIDO MDS metadata statements (#241)
Packages:
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
Changes:
- [browser]
"type": "module"
has been added to package.json to appease modern front end tooling that expects this value to be present when using the ESM build (#237) - [server] TPM attestation statement verification now properly verifies statements with ECC public area type (#239)
Packages:
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
Changes:
- [server]
verifyRegistrationResponse()
andverifyAuthenticationResponse()
now return authenticator extension data upon successful verification as the newauthenticatorExtensionResults
property (#230) - [browser] Code quality improvements
- [typescript-types] Code quality improvements
Packages:
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
Changes:
- [browser]
startAuthentication()
now accepts a seconduseBrowserAutofill
boolean argument that sets up support for credential selection via a browser's autofill prompt (a.k.a. Conditional UI). The newbrowserSupportsWebAuthnAutofill()
helper method can be used independently to determine when this feature is supported by the browser (#214) - [browser]
startRegistration()
andstartAuthentication()
will return a newauthenticatorAttachment
value when present that captures whether a cross-platform or platform authenticator was just used (#221) - [typescript-types] A new
PublicKeyCredentialFuture
interface has been added to define new properties currently defined in the WebAuthn L3 spec draft. These new values support the above new functionality until official TypeScript types are updated accordingly (#214, #221) - [typescript-types] A new
"hybrid"
transport has been added toAuthenticatorTransportFuture
while browsers migrate away from the existing"cable"
transport for cross-device auth (#222)
Packages:
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
Changes:
- [server]
generateRegistrationOptions()
andgenerateAuthenticationOptions()
will stop reporting typing errors for definitions ofexcludeCredentials
andallowCredentials
that were otherwise fine before v5.2.0 (#203) - [typescript-types] The new
AuthenticatorTransportFuture
andPublicKeyCredentialDescriptorFuture
have been added to track changes to WebAuthn that outpace TypeScript's DOM lib typings - [browser] Version sync
Packages:
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
Changes:
- [browser, typescript-types] The new
"cable"
transport is now recognized as a potential value of theAuthenticatorTransport
type (#198) - [server]
verifyRegistrationResponse()
andverifyAuthenticationResponse()
now returncredentialDeviceType
andcredentialBackedUp
withinauthenticatorInfo
as parsed values of two new flags being added to authenticator data. These response verification methods will also now throw an error when the invalid combination of these two flags (credentialDeviceType: "singleDevice", credentialBackedUp: true
) is detected (#195)- This feature supports detection of "multi-device credentials" gradually coming to all major platform authenticator vendors later this year.
Packages:
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
Changes:
- [browser] Custom errors raised when calling
startRegistration()
andstartAuthentication()
will now have the samename
property as the original error (#191) - [server] Cleaned up code and added tests (#192, #193)
Packages:
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
Changes:
- [browser] Most common WebAuthn errors that can occur when calling
startRegistration()
andstartAuthentication()
will now return descriptions with more specific insights into what went wrong (#184) - [testing] Version sync
- [typescript-types] Version sync
- [server] The
fidoUserVerification
argument toverifyAuthenticationResponse()
has been replaced with the simplerrequireUserVerification
boolean (#181)
Previous values of "required"
should specify true
for this new argument; previous values of
"preferred"
or "discouraged"
should specify false
:
Before:
const verification = verifyAuthenticationResponse({
// ...snip...
fidoUserVerification: 'required',
});
After:
const verification = verifyAuthenticationResponse({
// ...snip...
requireUserVerification: true,
});
Packages:
- @simplewebauthn/[email protected]
Changes:
- [server] Attestation statement verification involving FIDO metadata now correctly validates the credential public keypair algorithm against possible algorithms defined in the metadata statement.
- [server] The expired GlobalSign R2 root certificate for
"android-safetynet"
responses has been removed - [server] Certificate path validation errors will now identify which part of the chain and which certificate has an issue
- [server]
verifyAuthenticationResponse()
'sexpectedChallenge
argument also accepts a function that accepts a Base64URLstring
and returns aboolean
to run custom logic against theclientDataJSON.challenge
returned by the authenticator (see v4.3.0 release notes for more info).
Packages:
- @simplewebauthn/[email protected]
Changes:
- [server] The
expectedChallenge
argument passed toverifyRegistrationResponse()
can now be a function that accepts a Base64URLstring
and returns aboolean
to run custom logic against theclientDataJSON.challenge
returned by the authenticator. This allows for arbitrary data to be included in the challenge so it can be signed by the authenticator.
After generating registration options, the challenge can be augmented with additional data:
const options = generateRegistrationOptions(opts);
// Remember the plain challenge
inMemoryUserDeviceDB[loggedInUserId].currentChallenge = options.challenge;
// Add data to be signed
options.challenge = base64url(JSON.stringify({
actualChallenge: options.challenge,
arbitraryData: 'arbitraryDataForSigning',
}));
Then, when invoking verifyRegistrationResponse()
, pass in a method for expectedChallenge
to
parse the challenge and return a boolean
:
const expectedChallenge = inMemoryUserDeviceDB[loggedInUserId].currentChallenge;
const verification = await verifyRegistrationResponse({
expectedChallenge: (challenge: string) => {
const parsedChallenge = JSON.parse(base64url.decode(challenge));
return parsedChallenge.actualChallenge === expectedChallenge;
},
// ...
});
To retrieve the arbitrary data afterwards, use decodeClientDataJSON()
afterwards to get it out:
import { decodeClientDataJSON } from '@simplewebauthn/server/helpers';
const { challenge } = decodeClientDataJSON(response.clientDataJSON);
const parsedChallenge = JSON.parse(base64url.decode(challenge));
console.log(parsedChallenge.arbitraryData); // 'arbitraryDataForSigning'
Packages:
- @simplewebauthn/[email protected]
Changes:
- [server] The debug library has been incorporated to support logging output from the library's internal operations. Add the following environment variable to your application to view this output when using this library:
DEBUG=SimpleWebAuthn:*
The following logging scopes are defined in this release:
SimpleWebAuthn:MetadataService
See PR #159 for a preview of logging output.
Packages:
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
Changes:
- [browser]
platformAuthenticatorIsAvailable()
now checks that WebAuthn is supported at all before attempting to query for the status of an available platform authenticator. - [server]
MetadataService.initialize()
gained a newverificationMode
option that can be set to"permissive"
to allow registration response verification to continue when an unregistered AAGUID is encountered. Default behavior, that fails registration response verification, is represented by the alternative value"strict"
; MetadataService continues to default to this more restrictive behavior.
A lot has happened to me since I first launched SimpleWebAuthn back in May 2020. My understanding of WebAuthn has grown by leaps and bounds thanks in part to my representing Duo/Cisco in the W3C's WebAuth Adoption Working Group. I'm now in a point in my life in which it's no longer sufficient to think, "what's in SimpleWebAuthn's best interests?" Now, I have an opportunity to think bigger - "what's in the WebAuthn API's best interests?"
While early on I thought "attestation" and "assertion" were important names to WebAuthn, I've since come to better appreciate the spec's efforts to encourage the use of "registration" and "authentication" instead. To that end I decided it was time to rename all of the project's various public methods and types to get as much as possible to use "registration" and "authentication" instead.
This release is one of the more disruptive because it affects everyone who's used SimpleWebAuthn to date. The good news is that, while method and type names have changed, their capabilities remain the same. Updating your code to this version of SimpleWebAuthn should only involve renaming existing method calls and type annotations.
Please take the time to read the entire changelog for this release! There are a handful of new features also included that users with advanced use cases will find helpful. The simple use cases of the library remain unchanged - most new features are for power users who require extra scrutiny of authenticators that interact with their website and are otherwise opt-in as needed.
Packages:
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
Changes:
- [browser] A new (asynchronous) helper method
platformAuthenticatorIsAvailable()
has been added for detecting when hardware-bound authenticators like Touch ID, Windows Hello, etc... are available for use. More info is available here. - [server] The new
SettingsService
can be used to configure aspects of SimpleWebAuthn like root certs for enhanced registration response verification or for validating FIDO MDS BLOBs with MetadataService. More info is available here. - [server] Known root certificates for the following attestation formats have been updated:
'android-key'
,'android-safetynet'
,'apple'
- [server] A wide range of internal helper methods are now exported from
'@simplewebauthn/server/helpers'
(not a new package, but a subpath.) These methods can be used, for example, to process non-standard responses that are not officially part of the WebAuthn spec and thus unlikely to ever be supported by SimpleWebAuthn. - [server]
MetadataService
now supports FIDO Alliance Metadata Service version 3.0.
- [browser, server, typescript-types] All methods and types that included "attestation" in the name have been renamed to use "registration" instead
- [browser, server, typescript-types] All methods and types that included "assertion" in the name have been renamed to use "authentication" instead.
The quickest way to update your code is to try changing "attestation" to "registration" and "assertion" to "authentication" in the name of whatever method or type is no longer working and see if that fixes it (exceptions to this rule are called out with asterisks below.) If it doesn't, check out PR #147 to see all of the renamed methods and types and try to cross-reference the original to see what it was renamed to.
Examples:
generateAttestationOptions()
->generateRegistrationOptions()
GenerateAttestationOptionsOpts
->GenerateRegistrationOptionsOpts
verifyAssertionResponse()
->verifyAuthenticationResponse()
VerifiedAttestation
->VerifiedRegistrationResponse
(*)VerifiedAssertion
->VerifiedAuthenticationResponse
(*)startAttestation()
->startRegistration()
startAssertion()
->startAuthentication()
These examples are not a comprehensive list of all the renamed methods! Rather these are examples of how method names were changed to try and eliminate "attestation" and "assertion" from the public API of both @simplewebauthn/browser and @simplewebauthn/server.
- [server] The
opts
argument forMetadataService.initialize()
is now optional. - [server] The
opts.mdsServers
argument forMetadataService.initialize(opts)
is now a simple array of URL strings to FIDO Alliance MDSv3-compatible servers. If no value is specified then MetadataService will query the official FIDO Alliance Metadata Service version 3.0.
See here for more information about the updated
MetadataService
.
- [browser]
supportsWebAuthn()
has been renamed tobrowserSupportsWebAuthn()
in an effort to make the method convey a clearer idea of what supports WebAuthn.
Packages:
- @simplewebauthn/[email protected]
Changes:
- [browser] The ES2018 bundle is now "main" in package.json. The
tslib
dependency for production is no longer necessary as transpilation to ES5 is now fully the responsibility of the framework implementing @simplewebauthn/browser.- The ES5 UMD build remains available for websites not leveraging a build pipeline.
- [browser] Linking to this package via unpkg now defaults to the ES2018 build. See browser's README.md for information on how to link to the ES5 build instead.
This release is focused on updating @simplewebauthn/browser for better browser support out of the box. Most projects will now pull in its (slightly larger) ES5 bundle to ensure maximum browser compatibility, including older browsers in which WebAuthn will never be available. The ES2018 build is still available for projects that only need to target newer browsers, but bundler configuration changes must now be made to include it instead of the ES5 build.
Packages:
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
Changes:
- [browser] Set default bundle to ES5 to support IE10+ and Edge Legacy
- [browser]
startAssertion()
no longer Base64URL-encodesuserHandle
string - [server] Fix issue with Chrome (< v90) WebAuthn virtual authenticators
- [server] Update
jsrsasign
to10.2.0
(see GHSA-27fj-mc8w-j9wg) - [typescript-types] Update assertion JSON declarations as per
startAssertion()
fix
- [browser] Projects targeting modern browsers may not wish to bundle the ES5 version due to its inclusion of various polyfills. See the updated "Building for Production" section of the README.md for more info on how to pull in the ES2018 version instead.
- [browser] RPs with usernameless flows will no longer need to Base64URL-decode
response.userHandle
as returned fromstartAssertion()
.
Packages:
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
Changes:
- [browser] Adds support for older browsers (IE10/IE11, Edge Legacy, etc...) with additional
build artifacts targeting ES5
- See updated "Installation" and "Building for Production" sections of the README.md
- [server] Internal code cleanup
Packages:
- @simplewebauthn/[email protected]
Changes:
- [server] Export more TypeScript types for options and verification method inputs and outputs:
// Newly exported types
import type {
GenerateAssertionOptionsOpts,
GenerateAttestationOptionsOpts,
VerifiedAssertion,
VerifiedAttestation,
VerifyAssertionResponseOpts,
VerifyAttestationResponseOpts,
} from '@simplewebauthn/server';
Packages:
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
Changes:
- [browser]
startAttestation()
andstartAssertion()
now include extension results asclientExtensionResults
in their return value - [typescript-types] Updated
PublicKeyCredentialCreationOptionsJSON
andPublicKeyCredentialRequestOptionsJSON
types with new optionalextensions
property to support specifying WebAuthn extensions when callinggenerateAttestationOptions()
andgenerateAssertionOptions()
- [typescript-types] Updated
AttestationCredentialJSON
andAssertionCredentialJSON
types with newclientExtensionResults
properties to contain output from WebAuthn'scredential.getClientExtensionResults()
- [server] Version sync
This major release includes improvements intended to make it easier to support passwordless and usernameless WebAuthn flows. Additional information returned from attestation verification can be used by RP's to further scrutinize the attestation now or in the future.
I also made the decision to reduce the amount of encoding from Buffer to Base64URL and decoding from Base64URL to Buffer throughout the library. Verification methods now return raw Buffers so that RP's are free to store and retrieve these values as they see fit without the library imposing any kind of encoding overhead that may complicate storage in a database, etc...
Packages:
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
Changes:
- [server] See Breaking Changes below.
- [typescript-types] See Breaking Changes below
- [browser] Version sync
- [testing] Version sync
- [server] The method
verifyAttestationResponse()
now returns a different data structure with additional information that RP's can use to more easily support passwordless and usernameless WebAuthn flows.- Additionally,
Buffer
values are now returned in place of previously-base64url-encoded values. This is intended to offer more flexibility in how these values are persisted without imposing an encoding scheme that may introduce undesirable overhead.
- Additionally,
Before:
type VerifiedAttestation = {
verified: boolean;
userVerified: boolean;
authenticatorInfo?: {
fmt: ATTESTATION_FORMAT;
counter: number;
base64PublicKey: string;
base64CredentialID: string;
};
};
After:
type VerifiedAttestation = {
verified: boolean;
attestationInfo?: {
fmt: ATTESTATION_FORMAT;
counter: number;
aaguid: string;
credentialPublicKey: Buffer;
credentialID: Buffer;
credentialType: string;
userVerified: boolean;
attestationObject: Buffer;
};
};
- [server] The method
verifyAssertionResponse()
now returns a different data structure to align with changes made toverifyAttestationResponse()
.
Before:
type VerifiedAssertion = {
verified: boolean;
authenticatorInfo: {
counter: number;
base64CredentialID: string;
};
};
After:
type VerifiedAssertion = {
verified: boolean;
assertionInfo: {
credentialID: Buffer;
newCounter: number;
};
};
- [server] The
excludeCredentials
argument ingenerateAttestationOptions()
now expects aBuffer
type for a credential'sid
property. Previouslyid
needed to be astring
. Existing credential IDs stored in base64url encoding can be easily converted to Buffer with a library likebase64url
:
Before:
const options = generateAttestationOptions({
// ...
excludeCredentials: [{
id: 'PPa1spYTB680cQq5q6qBtFuPLLdG1FQ73EastkT8n0o',
// ...
}],
// ...
});
After:
const options = generateAttestationOptions({
// ...
excludeCredentials: [{
id: base64url.toBuffer('PPa1spYTB680cQq5q6qBtFuPLLdG1FQ73EastkT8n0o'),
// ...
}],
// ...
});
- [server] The
allowCredentials
argument ingenerateAssertionOptions()
now expects aBuffer
type for a credential'sid
property. Previouslyid
needed to be astring
. Existing credential IDs stored in base64url encoding can be easily converted to Buffer with a library likebase64url
:
Before:
const options = generateAssertionOptions({
// ...
allowCredentials: [{
id: 'PPa1spYTB680cQq5q6qBtFuPLLdG1FQ73EastkT8n0o',
// ...
}],
// ...
});
After:
const options = generateAssertionOptions({
// ...
allowCredentials: [{
id: base64url.toBuffer('PPa1spYTB680cQq5q6qBtFuPLLdG1FQ73EastkT8n0o'),
// ...
}],
// ...
});
- [typescript-types] The
AuthenticatorDevice
type has been updated to expectBuffer
's for credential data. Naming of its properties have also been updated to help maintain consistency with naming in the WebAuthn spec:
Before:
type AuthenticatorDevice = {
publicKey: Base64URLString;
credentialID: Base64URLString;
counter: number;
transports?: AuthenticatorTransport[];
};
After:
type AuthenticatorDevice = {
credentialPublicKey: Buffer;
credentialID: Buffer;
counter: number;
transports?: AuthenticatorTransport[];
};
Packages:
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
Changes:
- [server] Add support for multiple expected origins and RP IDs in
verifyAttestationResponse()
andverifyAssertionResponse()
- [server] Update
generateAttestationOptions()
to force legacyauthenticatorSelection.requireResidentKey
totrue
whenauthenticatorSelection.residentKey
is"required"
(as per L2 of the WebAuthn spec) - [typescript-types] Update
AuthenticatorDevice
type with optionaltransports
property - [browser] Version sync
- [testing] Version sync
There are no breaking changes in this release. Several recent minor changes presented an opportunity to release a "v1.0". I'd received enough positive feedback about SimpleWebAuthn and noticed growing usage which granted me the confidence to take advantage of this opportunity.
And perhaps this will give the project more legitimacy in the eyes of larger organizations wishing to use it but waiting for the libraries to "get out of beta"...
Packages:
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
Changes:
- [browser] Refactor
toUint8Array()
for easier testing when integrated - [server] Fix an unexpected build issue
- [testing] Publish package (stub)
Packages:
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
Changes:
- [server] Make
allowCredentials
ingenerateAssertionOptions()
optional - [server] Support calling
generateAssertionOptions()
without any options - [browser] Ignore "empty" values for
allowCredentials
before starting assertion - [typescript-types] Unpin dependency versions
Packages:
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
Changes:
- [server] Unpin dependency versions
- [server] Upgrade dependencies and devDependencies
- [typescript-types] Pull in TypeScript DOM lib types on build
- [docs] Upgrade TypeDoc for better API docs
Packages:
- @simplewebauthn/[email protected]
Changes:
- [server] Add optional
rpID
argument togenerateAssertionOptions()
Packages:
- @simplewebauthn/[email protected]
Changes:
- [server] Update ASN.1 parsing libraries to latest releases
Packages:
- @simplewebauthn/[email protected]
Changes:
- [server] Pin third-party package versions
Packages:
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
Changes:
- [server] Add support for "apple" attestations to support iOS Face ID and Touch ID
- [server] [browser] Enable specifying transports per credential for
allowCredentials
andexcludeCredentials
- [browser] Return authenticator's transports (when available) as
transports
in response fromstartAttestation()
- [typescript-types] Add new
AuthenticatorAttestationResponseFuture
type for better typing of credential response methods (getTransports()
,getAuthenticatorData()
, etc...)
- [server] Existing implementations of
generateAttestationOptions()
andgenerateAssertionOptions()
must be updated to specify credentials with their own transports:
generateAttestationOptions()
// OLD
const options = generateAttestationOptions({
excludedCredentialIDs: devices.map((dev) => dev.credentialID),
suggestedTransports: ['usb', 'ble', 'nfc', 'internal'],
});
// NEW
const options = generateAttestationOptions({
excludeCredentials: devices.map((dev) => ({
id: dev.credentialID,
type: 'public-key',
transports: dev.transports,
})),
});
generateAssertionOptions()
// OLD
const options = generateAssertionOptions({
allowedCredentialIDs: user.devices.map((dev) => dev.credentialID),
suggestedTransports: ['usb', 'ble', 'nfc', 'internal'],
});
// NEW
const options = generateAssertionOptions({
allowCredentials: devices.map((dev) => ({
id: dev.credentialID,
type: 'public-key',
transports: dev.transports,
})),
});
Packages:
- @simplewebauthn/[email protected]
Changes:
- [server] Third-party package security update
Packages:
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
Changes:
- [server] Add support for attestations and assertions containing RSA public keys.
- [browser] Version sync.
- [typescript-types] Version sync.
- [server]
authenticatorInfo.base64PublicKey
returned byverifyAttestationResponse()
is now the entire public key buffer instead of a pared down form of it (it's still returned base64url-encoded). This helps ensure support for existing public keys, as well as future public key formats that may be introduced in the future. Public keys previously returned by this method must be upgraded via this "upgrader" script to work with future assertions. - [server] The
serviceName
argument forgenerateAttestationOptions()
has been renamed torpName
. This brings it in line with the existingrpID
argument and maps more obviously to its respective property within the returned options.
Packages:
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
Changes:
- [server] Return explicit defaults for
authenticatorSelection
in return value fromgenerateAttestationOptions()
for enhanced device compatibility. - [browser] Version sync.
- [typescript-types] Version sync.
Packages:
- @simplewebauthn/[email protected]
Changes:
- [server] Stop filtering out algorithm ID's from
supportedAlgorithmIDs
when callinggenerateAttestationOptions()
- [server] Fix a bug when verifying TPM attestation extensions
Packages:
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
Changes:
- [server] The
challenge
parameter ofgenerateAttestationOptions()
andgenerateAssertionOptions()
is now optional.- When undefined the library will generate a random challenge. This value will be base64url-encoded in preparation for transit to the front end.
- When defined the value will be directly encoded to base64url in preparation for transit to the front end.
- [browser]
startAttestation()
andstartAssertion()
now convert the base64url-encodedoptions.challenge
to a buffer before passing it to the authenticator.
- [server]
verifyAttestationResponse()
andverifyAssertionResponse()
now require the base64url-encoded challenge to be passed in asexpectedChallenge
:
Before:
const challenge = 'someChallenge';
const opts = generateAttestationOptions({
...atteOpts,
challenge,
});
const verification = verifyAttestationResponse({
...atteResp,
// Raw original value
expectedChallenge: challenge,
});
After:
const challenge = 'someChallenge';
const opts = generateAttestationOptions({
...atteOpts,
// This is now optional
challenge,
});
const verification = verifyAttestationResponse({
...atteResp,
// Now expected to be the base64url-encoded `challenge` returned
// by `generateAttestationOptions()`
expectedChallenge: opts.challenge,
});
Packages:
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
Changes:
- [browser] Update dependencies
- [server] Update dependencies
Packages:
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
Changes:
- [browser] Add support for UTF-8 values in server challenges
- [server] Minor performance improvement
Packages:
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
Changes:
- [server] Added support for specifying a custom array of COSE algorithm identifiers when
calling
generateAttestationOptions()
andverifyAttestationResponse()
- [browser] Updated README.md with new doc URLs
Packages:
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
Changes:
- Fixed broken README and Homepage links in package listings on NPMJS.com
Packages:
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
Changes:
- [server] Add support for TPM attestations
- [server] Add support for Android Key attestations
- [server] Add support for authenticator metadata statements and the FIDO Metadata Service (MDS)
- [server] The return type of
verifyAttestationResponse()
changed fromboolean
toPromise<boolean>
. This was necessary to support querying FIDO MDS for an authenticator metadata statement during attestation verification. - [server] The optional
requireUserVerification
parameter ofverifyAssertionResponse()
has been replaced with the new optionalfidoUserVerification
parameter. This enables greater control over user verification when verifying assertions.
Packages:
- @simplewebauthn/[email protected]
Changes:
- [typescript-types] Update
verifyAttestationResponse()
options param description.
Packages:
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
Changes:
- [server] (BREAKING) Server's
verifyAttestationResponse()
andverifyAssertionResponse()
methods now take a single arguments object. - [server] These methods now include the ability to require user verification during attestation
and assertion verification via the new
requireUserVerification
argument.
Packages:
- @simplewebauthn/[email protected]
Changes:
- [typescript-types] Re-export
AuthenticatorAttestationResponseJSON
andAuthenticatorAssertionResponseJSON
Packages:
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
- @simplewebauthn/[email protected]
Changes:
- [browser] (BREAKING) Refactor
startAttestation()
andstartAssertion()
to return more of the output from thenavigator.credentials
calls - [browser] Replace
base64-js
dependency with internal functionality - [browser, server] Standardize on use of Base64URL encoding when converting to and from JSON
- [server] (BREAKING) Remove references to "base64" from
generateAttestationOptions()
andgenerateAssertionOptions()
by renaming theexcludedBase64CredentialIDs
andallowedBase64CredentialIDs
toexcludedCredentialIDs
andallowedCredentialIDs
respectively - [typescript-types] (BREAKING) Migrate some non-shared typings into server