Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [5.5.0]

- `/appid-<appId>/<tenantId>/recipe/webauthn/signin` POST: sign in options are now single-use. They are consumed atomically with a successful sign in, so verifying the same assertion again returns `OPTIONS_NOT_FOUND_ERROR`. SDKs must verify each assertion exactly once (requests on CDI <= 5.4 keep the previous behaviour).
- `/appid-<appId>/<tenantId>/recipe/webauthn/signin` POST: sign in options are now single-use. A successful sign in consumes them, so a later sign in with the same `webauthnGeneratedOptionsId` returns `OPTIONS_NOT_FOUND_ERROR`. SDKs must verify each assertion exactly once. Requests that send a `cdi-version` of 5.4 or lower keep the previous behaviour; requests without the header are treated as the latest CDI version and consume the options too.

## [5.4.0]

Expand Down
13 changes: 9 additions & 4 deletions api_spec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9333,9 +9333,10 @@ paths:
Sign in the user using the WebAuthn credential.

The sign in options (`webauthnGeneratedOptionsId`, created with `/recipe/webauthn/options/signin`) are single-use:
they are consumed atomically with a successful verification, so the same assertion cannot be replayed.
Verifying the same assertion a second time returns `OPTIONS_NOT_FOUND_ERROR`.
a successful sign in consumes them, so a later sign in with the same `webauthnGeneratedOptionsId` returns `OPTIONS_NOT_FOUND_ERROR`.
Failed attempts do not consume the options; they stay usable until they expire or are removed.

Note that requests without a `cdi-version` header are treated as the core's latest CDI version, so their options are consumed too.
operationId: signInWebAuthNUser
parameters:
- $ref: '#/components/parameters/webauthnRid'
Expand Down Expand Up @@ -9376,6 +9377,10 @@ paths:
properties:
status:
type: string
description: |
- `INVALID_OPTIONS_ERROR`: the options have expired (`reason`: "Options expired")
- `INVALID_AUTHENTICATOR_ERROR`: the assertion failed verification (`reason` has the details)
- `INVALID_CREDENTIALS_ERROR`: the `credential` object could not be parsed (`reason` has the details)
enum: [ 'INVALID_OPTIONS_ERROR', 'INVALID_AUTHENTICATOR_ERROR', 'INVALID_CREDENTIALS_ERROR' ]
reason:
type: string
Expand All @@ -9384,8 +9389,8 @@ paths:
status:
type: string
description: |
- `OPTIONS_NOT_FOUND_ERROR`: unknown or expired options id, or options already consumed by an earlier successful sign in
- `CREDENTIAL_NOT_FOUND_ERROR`: no credential with this id is registered for the options' relying party
- `OPTIONS_NOT_FOUND_ERROR`: unknown options id, or options already consumed by an earlier successful sign in (expired options are reported as `INVALID_OPTIONS_ERROR` until they are cleaned up)
- `CREDENTIAL_NOT_FOUND_ERROR`: no credential with this id is registered for the options' relying party, or the credential's user is not in this tenant
- `UNKNOWN_USER_ID_ERROR`: the credential's user no longer exists
enum: [ 'OPTIONS_NOT_FOUND_ERROR', 'CREDENTIAL_NOT_FOUND_ERROR', 'UNKNOWN_USER_ID_ERROR' ]
'400':
Expand Down
Loading