Hanko webauthn API
Represents all objects which are related to WebAuthn in common
Represents all objects which are related to WebAuthn in common
openapi: 3.0.3
info:
version: 1.2.0
title: Hanko Admin Audit Logs webauthn API
description: '## Introduction
This is the OpenAPI specification for the [Hanko Admin API](https://github.com/teamhanko/hanko/blob/main/backend/README.md#start-private-api).
## Authentication
The Admin API must be protected by an access management system.
---
'
contact:
email: developers@hanko.io
license:
name: AGPL-3.0-or-later
url: https://www.gnu.org/licenses/agpl-3.0.txt
servers:
- url: https://{tenant_id}.hanko.io/admin
variables:
tenant_id:
default: ''
description: The (UU)ID of a tenant. Replace the default value with your tenant ID.
tags:
- name: webauthn
description: Represents all objects which are related to WebAuthn in common
paths:
/{tenant_id}/.well-known/jwks.json:
get:
tags:
- webauthn
summary: Well-known JWKS
description: Endpoint for fetching JWKS
operationId: get-.well-known-jwks.json
parameters:
- $ref: '#/components/parameters/tenant_id'
responses:
'200':
$ref: '#/components/responses/jwks'
servers:
- url: https://passkeys.hanko.io
/webauthn/login/initialize:
post:
summary: Initialize WebAuthn login
description: 'Initialize a login with Webauthn. Returns a JSON representation of CredentialRequestOptions for use
with the Webauthn API''s `navigator.credentials.get()`.
Omitting the optional request body or using an empty JSON object results in generation of request options for a
login using a [discoverable credential](https://www.w3.org/TR/webauthn-2/#client-side-discoverable-public-key-credential-source)
(i.e. they will not contain
[allowCredentials](https://www.w3.org/TR/webauthn-2/#dom-publickeycredentialrequestoptions-allowcredentials)).
*Note*: The Webauthn API uses binary data represented by ArrayBuffers for certain input/output values.
The Hanko API returns these values as base64url-encoded, so they must be converted to ArrayBuffers
when passed to the Webauthn API. Similarly, Webauthn API output must be converted to base64url-encoded values
when passed to the Hanko API (e.g. using the [webauthn-json](https://github.com/github/webauthn-json) library).
'
operationId: webauthnLoginInit
tags:
- webauthn
deprecated: true
requestBody:
content:
application/json:
schema:
type: object
properties:
user_id:
description: The ID of the user on whose behalf WebAuthn login should be performed
allOf:
- $ref: '#/components/schemas/UUID4'
responses:
'200':
description: Successful initialization
content:
application/json:
schema:
$ref: '#/components/schemas/CredentialRequestOptions'
examples:
non-disco:
summary: Non-Discoverable credentials
value:
publicKey:
challenge: qgOI+0KpGnl9NOqaT6dfsYvi96R87LgpErnvePeOgSU=
timeout: 60000
rpId: localhost
allowCredentials:
- type: public-key
id: Mepptysj5ZZrTlg0qiLbsZ068OtQMeGVAikVy2n1hvvG...
userVerification: required
disco:
summary: Discoverable credentials
value:
challenge: qgOI+0KpGnl9NOqaT6dfsYvi96R87LgpErnvePeOgSU=
timeout: 60000
rpId: localhost
userVerification: required
'400':
$ref: '#/components/responses/BadRequest'
'500':
$ref: '#/components/responses/InternalServerError'
/webauthn/login/finalize:
post:
summary: Finalize WebAuthn login
description: 'Finalize a login with Webauthn using the WebAuthn API response to a `navigator.credentials.get()` call.
*Note*: The Webauthn API uses binary data represented by ArrayBuffers for certain input/output values.
The Hanko API returns these values as base64url-encoded, so they must be converted to ArrayBuffers
when passed to the Webauthn API. Similarly, Webauthn API output must be converted to base64url-encoded values
when passed to the Hanko API (e.g. using the [webauthn-json](https://github.com/github/webauthn-json) library).
'
operationId: webauthnLoginFinal
tags:
- webauthn
deprecated: true
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/PublicKeyCredentialAssertionResponse'
responses:
'200':
description: Successful login
headers:
X-Auth-Token:
description: 'Present only when enabled via [configuration](https://github.com/teamhanko/hanko/blob/main/backend/docs/Config.md#hanko-backend-config) option `session.enable_auth_token_header`
for purposes of cross-domain communication between client and Hanko API.
'
schema:
$ref: '#/components/schemas/X-Auth-Token'
X-Session-Lifetime:
description: 'Contains the seconds until the session expires.
'
schema:
$ref: '#/components/schemas/X-Session-Lifetime'
Set-Cookie:
description: 'Contains the JSON Web Token (JWT) that must be provided to protected endpoints.
Cookie attributes (e.g. domain) can be set via [configuration](https://github.com/teamhanko/hanko/blob/main/backend/docs/Config.md#hanko-backend-config) option `session.cookie`.
'
schema:
$ref: '#/components/schemas/CookieSession'
content:
application/json:
schema:
$ref: '#/components/schemas/WebauthnLoginResponse'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'500':
$ref: '#/components/responses/InternalServerError'
/webauthn/registration/initialize:
post:
summary: Initialize WebAuthn registration
description: 'Initialize a registration with Webauthn. Returns a JSON representation of CredentialCreationOptions for use
with the Webauthn API''s `navigator.credentials.create()`.
*Note*: The Webauthn API uses binary data represented by ArrayBuffers for certain input/output values.
The Hanko API returns these values as base64url-encoded, so they must be converted to ArrayBuffers
when passed to the Webauthn API. Similarly, Webauthn API output must be converted to base64url-encoded values
when passed to the Hanko API (e.g. using the [webauthn-json](https://github.com/github/webauthn-json) library).
'
operationId: webauthnRegInit
tags:
- webauthn
deprecated: true
security:
- CookieAuth: []
- BearerTokenAuth: []
responses:
'200':
description: Challenge
content:
application/json:
schema:
$ref: '#/components/schemas/CredentialCreationOptions'
'400':
$ref: '#/components/responses/BadRequest'
'422':
$ref: '#/components/responses/unprocessableEntity'
'500':
$ref: '#/components/responses/InternalServerError'
/webauthn/registration/finalize:
post:
summary: Finalize WebAuthn registration
description: 'Finalize a registration with Webauthn using the WebAuthn API response to a `navigator.credentials.create()` call.
*Note*: The Webauthn API uses binary data represented by ArrayBuffers for certain input/output values.
The Hanko API returns these values as base64url-encoded, so they must be converted to ArrayBuffers
when passed to the Webauthn API. Similarly, Webauthn API output must be converted to base64url-encoded values
when passed to the Hanko API (e.g. using the [webauthn-json](https://github.com/github/webauthn-json) library).
'
operationId: webauthnRegFinal
tags:
- webauthn
deprecated: true
security:
- CookieAuth: []
- BearerTokenAuth: []
requestBody:
description: Challenge response
content:
application/json:
schema:
$ref: '#/components/schemas/PublicKeyCredentialAttestationResponse'
responses:
'200':
description: Successful registration
content:
application/json:
schema:
type: object
properties:
credential_id:
description: The ID of the created credential
type: string
format: base64
user_id:
description: The ID of the user on whose behalf a credential was created
allOf:
- $ref: '#/components/schemas/UUID4'
'400':
$ref: '#/components/responses/BadRequest'
'500':
$ref: '#/components/responses/InternalServerError'
/webauthn/credentials:
get:
summary: Get a list of WebAuthn credentials
description: 'Returns a list of WebAuthn credentials assigned to the current user.
'
operationId: listCredentials
tags:
- webauthn
deprecated: true
security:
- CookieAuth: []
- BearerTokenAuth: []
responses:
'200':
description: A list of WebAuthn credentials assigned to the current user
content:
application/json:
schema:
$ref: '#/components/schemas/WebauthnCredentials'
'401':
$ref: '#/components/responses/Unauthorized'
'500':
$ref: '#/components/responses/InternalServerError'
/webauthn/credentials/{id}:
patch:
summary: Updates a WebAuthn credential
description: 'Updates the specified WebAuthn credential. Only credentials assigned to the current user can be updated.
'
operationId: updateCredential
tags:
- webauthn
deprecated: true
security:
- CookieAuth: []
- BearerTokenAuth: []
parameters:
- name: id
in: path
description: ID of the WebAuthn credential
required: true
schema:
$ref: '#/components/schemas/UUID4'
requestBody:
content:
application/json:
schema:
type: object
properties:
name:
description: A new credential name. Has no technical meaning, only serves as an identification aid for the user.
type: string
responses:
'200':
description: Credential updated successfully
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
'500':
$ref: '#/components/responses/InternalServerError'
delete:
summary: Deletes a WebAuthn credential
description: 'Deletes the specified WebAuthn credential.
'
operationId: deleteCredential
tags:
- webauthn
deprecated: true
security:
- CookieAuth: []
- BearerTokenAuth: []
parameters:
- name: id
in: path
description: ID of the WebAuthn credential
required: true
schema:
$ref: '#/components/schemas/UUID4'
responses:
'201':
description: Credential updated successfully
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
'500':
$ref: '#/components/responses/InternalServerError'
components:
schemas:
CookieSession:
type: string
description: Value `<JWT>` is a [JSON Web Token](https://www.rfc-editor.org/rfc/rfc7519.html)
example: hanko=<JWT>; Path=/; HttpOnly
PublicKeyCredentialAssertionResponse:
description: WebAuthn API response to a navigator.credentials.get() call
type: object
properties:
id:
type: string
example: _18q6IjW09tiM4NSbsZjocUtGx00Muv5mN6LZCelCMDD...
rawId:
type: string
example: _18q6IjW09tiM4NSbsZjocUtGx00Muv5mN6LZCelCMDD...
type:
type: string
enum:
- public-key
example: public-key
response:
type: object
properties:
clientDataJson:
type: string
format: base64url
example: eyJ0eXBlIjoid2ViYXV0aG4uZ2V0IiwiY2hhbGxlbmdl...
authenticatorData:
type: string
format: base64url
example: SZYN5YgOjGh0NBcPZHZgW4_krrmihjLHmVzzuoMdl2MF...
signature:
type: string
format: base64url
example: MEQCIHe2RXqh6dyZw1LNXgeTTxljCV_qK2ydQjp02CiF...
userHandle:
type: string
format: base64url
example: rpe_EkgaSEeZG0TwzZyZJw
CredentialCreationOptions:
description: Options for credential creation with the WebAuthn API
externalDocs:
url: https://www.w3.org/TR/webauthn-2/#dictionary-makecredentialoptions
type: object
properties:
publicKey:
type: object
properties:
rp:
type: object
properties:
name:
type: string
example: Hanko Authentication Service
id:
type: string
example: localhost
user:
type: object
properties:
id:
type: string
example: pPQT9rwJRD7gVncsnCDNyN
name:
type: string
example: user@example.com
displayName:
type: string
example: user@example.com
challenge:
type: string
format: base64url
example: 7qmkJUXR0dOFnsW48evX3qKdCzlGjvvqAAvMDN+KTN0=
pubKeyCredParams:
type: array
items:
type: object
properties:
type:
type: string
enum:
- public-key
alg:
type: number
example:
- type: public-key
alg: -7
timeout:
type: integer
format: int64
example: 60000
authenticatorSelection:
type: object
properties:
authenticatorAttachment:
type: string
enum:
- platform
- cross-platform
example: platform
requireResidentKey:
type: boolean
example: true
residentKey:
type: string
enum:
- discouraged
- preferred
- required
example: preferred
userVerification:
type: string
enum:
- discouraged
- preferred
- required
example: required
attestation:
type: string
enum:
- none
- indirect
- direct
- enterprise
example: none
PublicKeyCredentialAttestationResponse:
description: WebAuthn API response to a navigator.credentials.create() call
type: object
properties:
id:
type: string
example: _18q6IjW09tiM4NSbsZjocUtGx00Muv5mN6LZCelCMDD...
rawId:
type: string
example: _18q6IjW09tiM4NSbsZjocUtGx00Muv5mN6LZCelCMDD...
type:
type: string
enum:
- public-key
example: public-key
response:
type: object
properties:
clientDataJson:
type: string
format: base64url
example: eyJ0eXBlIjoid2ViYXV0aG4uZ2V0IiwiY2hhbGxlbmdl...
attestationObject:
type: string
format: base64url
example: o2NmbXRkbm9uZWdhdHRTdG10oGhhdXRoRGF0YVjfSZYN...
transports:
type: array
items:
type: string
enum:
- usb
- nfc
- ble
- internal
example: internal
X-Auth-Token:
description: 'Enable via [configuration](https://github.com/teamhanko/hanko/blob/main/backend/docs/Config.md#hanko-backend-config) option `session.enable_auth_token_header`
for purposes of cross-domain communication between client and Hanko API.
'
type: string
format: JWT
externalDocs:
url: https://github.com/teamhanko/hanko/blob/main/backend/docs/Config.md#hanko-backend-config
X-Session-Lifetime:
description: 'Contains the seconds until the session expires.
'
type: number
CredentialRequestOptions:
description: Options for assertion generation with the WebAuthn API
externalDocs:
url: https://www.w3.org/TR/webauthn-2/#dictionary-assertion-options
type: object
properties:
publicKey:
type: object
properties:
challenge:
type: string
format: base64url
example: qgOI+0KpGnl9NOqaT6dfsYvi96R87LgpErnvePeOgSU=
timeout:
type: integer
format: int64
example: 60000
rpId:
type: string
example: localhost
allowCredentials:
type: array
items:
type: object
properties:
type:
type: string
enum:
- public-key
example: public-key
id:
type: string
format: base64url
example: Mepptysj5ZZrTlg0qiLbsZ068OtQMeGVAikVy2n1hvvG...
userVerification:
type: string
enum:
- required
- preferred
- discouraged
example: required
Error:
type: object
required:
- code
- message
properties:
code:
type: integer
format: int32
message:
type: string
WebauthnLoginResponse:
description: Response after a successful login with webauthn
type: object
properties:
credential_id:
type: string
format: base64url
user_id:
type: string
format: uuid4
WebauthnCredential:
type: object
properties:
aaguid:
type: string
format: uuid
attestation_type:
type: string
enum:
- none
- packed
- tpm
- android-key
- android-safetynet
- fido-u2f
- apple
backup_eligible:
type: boolean
backup_state:
type: boolean
created_at:
type: string
format: date-time
id:
type: string
format: uuid
last_used_at:
type: string
format: date-time
mfa_only:
type: boolean
name:
type: string
public-key:
type: string
transports:
type: array
items:
type: string
enum:
- ble
- internal
- nfc
- usb
UUID4:
type: string
format: uuid4
example: c339547d-e17d-4ba7-8a1d-b3d5a4d17c1c
WebauthnCredentials:
description: A list of WebAuthn credentials
type: array
items:
$ref: '#/components/schemas/WebauthnCredential'
example:
- id: 5333cc5b-c7c4-48cf-8248-9c184ac72b65
name: iCloud
public_key: pQECYyagASFYIBblARCP_at3cmprjzQN1lJ...
attestation_type: packed
aaguid: 01020304-0506-0708-0102-030405060708
last_used_at: '2026-02-24T21:40:36.26936Z'
created_at: '2026-02-24T21:40:36.26936Z'
transports:
- internal
backup_eligible: true
backup_state: true
mfa_only: false
- id: f826013e-e7e3-4366-a6d8-9359effc8cdd
name: Yubikey Bio
public_key: aNMEEyadASFYIBblARCP_at3cmp4gg3zQN1lJ...
attestation_type: packed
aaguid: 90636e1f-ef82-43bf-bdcf-5255f139d12f
last_used_at: '2026-02-24T21:40:36.26936Z'
created_at: '2026-02-24T21:40:36.26936Z'
transports:
- usb
backup_eligible: true
backup_state: false
mfa_only: true
responses:
BadRequest:
description: Bad Request
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
code: 400
message: Bad Request
NotFound:
description: Not Found
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
code: 404
message: Not found
unprocessableEntity:
description: Unprocessable Entity
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
code: 422
message: Unprocessable Entity
jwks:
description: Example response
content:
application/json:
schema:
type: object
properties:
keys:
type: array
minItems: 1
uniqueItems: true
items:
type: object
additionalProperties: false
properties:
alg:
type: string
readOnly: true
example:
- RS256
e:
type: string
readOnly: true
example:
- AAAA
kid:
type: string
format: uuid
readOnly: true
example:
- 483b2499-1ed7-4325-94e3-97e8118ceee9
kty:
type: string
readOnly: true
example:
- RSA
n:
type: string
readOnly: true
use:
type: string
readOnly: true
example:
- sig
minProperties: 6
minProperties: 1
Unauthorized:
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
code: 401
message: Unauthorized
InternalServerError:
description: Internal server error
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
code: 500
message: Internal Server Error
parameters:
tenant_id:
name: tenant_id
in: path
description: UUID of the tenant
required: true
schema:
type: string
format: uuid
minLength: 36
maxLength: 36
example:
- 1f496bcd-49da-4839-a02f-7ce681ccb488
securitySchemes:
BearerApiKeyAuth:
description: Bearer authentication header of the form `Bearer <token>`, where `<token>` is your API key. Must only be used when using Hanko Cloud.
type: http
scheme: bearer
bearerFormat: API Key
externalDocs:
description: More about Hanko
url: https://github.com/teamhanko/hanko