Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Passkeys (protocol side)

pro.aduki.net.http.Passkeys is the HTTP side of WebAuthn at Aduki ID: the begin and verify calls of the three ceremonies, plus list and remove. It runs on a plain JVM. The authenticator step is handled by the platform (Android Credential Manager): on Android, use PasskeyFlow and CredentialManagerAuthenticator from the android module (pro.aduki:android).

Each ceremony is two calls. begin* returns a Challenge (ceremony, expires, options); give challenge.optionsJson to the platform API; pass the JSON the platform returns to the matching finish* call. A challenge is spent by the first answer, right or wrong, and lasts five minutes.

CeremonyBeginFinishResult
Register (step-up or code)beginRegistration(client, identity, bearer, label?, code?)finishRegistration(..., challenge, registrationResponseJson)Registered
Step-upbeginStepUp(client, identity, bearer)finishStepUp(..., challenge, authenticationResponseJson)Unix seconds; renew the access token to get the new stp
Sign in (no account named)beginSignIn(client, identity)finishSignIn(client, identity, challenge, authenticationResponseJson, audience, device)Tokens

list(client, identity, bearer) returns your passkeys (Item, never key material); remove(client, identity, bearer, passkey, code?) removes one.

Passkeys.credential(json, registration) is what the finish calls use: it checks that the platform JSON is a public-key credential with clientDataJSON and either attestationObject (registration) or authenticatorData and signature (assertion), and keeps only the fields Aduki ID reads. A malformed credential throws IllegalArgumentException before any request is made.

Errors: every failed verification is AdukiException.Unauthorized (401 auth.invalid, uniform). Registering and removing need a recent step-up or a fresh authenticator code; otherwise the server answers 403 auth.stepup, which Passkeys.needsStepUp(e) recognises (step up, then retry). A malformed server answer is AdukiException.Protocol. For a session bound to a device key, use an HTTP client with the DPoP interceptor.

Android: Credential Manager

pro.aduki.android.passkey.PasskeyFlow runs begin, the platform step and finish for register, stepUp and signIn; CredentialManagerAuthenticator hands challenge.optionsJson to CreatePublicKeyCredentialRequest / GetPublicKeyCredentialOption and returns the platform’s response JSON. See Android module. Request shaping and error mapping are unit tested; a real passkey ceremony needs a device with a credential provider and is not verified.