
Standards-first WebAuthn and passkey building blocks: typed protocol models, strict validation, backend ceremony services, client orchestration, and modular transport, storage, crypto and attestation adapters.
Standards-first Kotlin Multiplatform building blocks for WebAuthn and passkey integrations.
This project helps teams implement passwordless login without rebuilding the hardest parts from scratch. It gives you typed protocol models, strict validation, backend ceremony services, platform passkey clients, and optional transport/adaptation modules that stay close to the WebAuthn specification.
This repo focuses on those needs:
| Android | iOS |
|---|---|
WebAuthn has two ceremony pairs:
create)get)Each pair has a server start step and a server finish step, with the platform authenticator in the middle.
sequenceDiagram
autonumber
actor User
participant App as Client App
participant Auth as Platform Authenticator
participant RP as Relying Party Server
note over RP,App: Registration ceremony
App->>RP: registration/start request
RP-->>App: registration/start response (challenge + options)
App->>Auth: navigator.credentials.create / platform create
Auth-->>App: RegistrationResponse
App->>RP: registration/finish (response + echoed challenge)
RP-->>App: verified registration
note over RP,App: Authentication ceremony
App->>RP: authentication/start request
RP-->>App: authentication/start response (challenge + options)
App->>Auth: navigator.credentials.get / platform get
Auth-->>App: AuthenticationResponse
App->>RP: authentication/finish (response + echoed challenge)
RP-->>App: verified sign-inValidation and trust decisions are server responsibilities: challenge/origin/type checks, authenticator data rules, signature/attestation verification, counter handling, and policy decisions.
The repository follows a layered model that keeps protocol and validation concerns separate from transport and platform adapters.
flowchart TB
subgraph Layer1[Layer 1: Protocol Model]
M[webauthn-model]
end
subgraph Layer2[Layer 2: Validation and Serialization]
CBOR[webauthn-cbor-core]
C[webauthn-core]
S[webauthn-serialization-kotlinx]
RUNTIME[webauthn-runtime-core]
end
subgraph Layer3[Layer 3: Crypto Abstractions and Backends]
API[webauthn-crypto-api]
JCRYPTO[webauthn-server-jvm-crypto]
end
subgraph Layer4[Layer 4: Server Services and Adapters]
SVC[webauthn-server-core-jvm]
KTOR[webauthn-server-ktor]
STORE[webauthn-server-store-exposed]
MDS[webauthn-attestation-mds]
end
subgraph Layer5[Layer 5: Client Orchestration and Platform]
CCORE[webauthn-client-core]
CJSON[webauthn-client-json-core]
CANDROID[webauthn-client-android]
CIOS[webauthn-client-ios]
CCOMPOSE[webauthn-client-compose]
CPRF[webauthn-client-prf-crypto]
NET[webauthn-network-ktor-client]
end
M --> C
M --> S
CBOR --> S
C --> API
S --> SVC
CBOR --> JCRYPTO
JCRYPTO --> API
C --> SVC
SVC --> KTOR
SVC --> STORE
MDS --> API
M --> CCORE
RUNTIME --> CCORE
RUNTIME --> CPRF
RUNTIME --> NET
CCORE --> CJSON
CCORE --> CANDROID
CCORE --> CIOS
CCORE --> CCOMPOSE
CCORE --> CPRF
C --> NET
S --> NET
CCORE --> NETFocus modules for this documentation round:
core/ contains reusable protocol, validation, runtime, serialization, and crypto contracts.
client/ contains shared client orchestration, platform bridges, Compose helpers, and client transport.
server/ contains JVM server services, Ktor/store adapters, JVM crypto, and optional trust metadata.
sample/ contains runnable samples and demo entry points; these modules are not published.
webauthn-runtime-core: shared coroutine/failure boundary helpers for adapters.
webauthn-model: typed protocol/value contracts.
webauthn-core: standards-first ceremony validation.
webauthn-client-core: shared passkey orchestration and controller flows.
webauthn-client-compose: Compose integration helpers over client core.
webauthn-client-prf-crypto: PRF-enabled key derivation/session crypto helpers.
Most module READMEs follow this baseline structure (adapted per module when needed):
What it provides: the module's owned responsibilities.When to use: where it belongs in an integration.How to use: practical API snippets plus required caller responsibilities.How it fits in the system: dependency and data-flow context.Pitfalls/limits: common misuse patterns and intentional boundaries.Status: maturity and readiness signal.Recommended adoption paths:
model -> core -> crypto-api -> server-core-jvm (+ server-ktor if you want HTTP adapters).client-core -> platform bridge (+ client-compose for Compose UI).client-prf-crypto only when you need PRF-derived application crypto.The coordinated release train uses one version for the full published surface plus a BOM.
repositories {
google()
mavenCentral()
}Use only the modules your app actually wires in. In Kotlin Multiplatform projects, shared modules belong in commonMain, while concrete platform bridges belong in the matching platform source set.
Client-side KMP example:
kotlin {
sourceSets {
commonMain.dependencies {
implementation(platform("io.github.szijpeter:webauthn-bom:<version>"))
implementation("io.github.szijpeter:webauthn-client-core")
implementation("io.github.szijpeter:webauthn-network-ktor-client") // optional default backend transport
}
androidMain.dependencies {
implementation("io.github.szijpeter:webauthn-client-android") // only if you use AndroidPasskeyClient
}
iosMain.dependencies {
implementation("io.github.szijpeter:webauthn-client-ios") // only if you use IosPasskeyClient
}
}
}JVM/Ktor server example:
dependencies {
implementation(platform("io.github.szijpeter:webauthn-bom:<version>"))
implementation("io.github.szijpeter:webauthn-server-core-jvm")
implementation("io.github.szijpeter:webauthn-server-jvm-crypto")
implementation("io.github.szijpeter:webauthn-server-ktor") // optional route adapter
}Notes:
webauthn-server-* dependencies.webauthn-client-android / webauthn-client-ios when that target instantiates the concrete platform client.commonMain only needs the common modules.sample/compose-passkey, sample/compose-passkey-android, and sample/compose-passkey-ios.Published to Maven Central (latest version is shown in the Maven Central badge above). Maintainers can still validate publication locally with:
./gradlew publishToMavenLocal --stacktraceUse:
webauthn-modelwebauthn-corewebauthn-crypto-apiwebauthn-server-jvm-cryptowebauthn-server-core-jvmwebauthn-server-ktor if you want route adapterswebauthn-server-store-exposed if you want an Exposed-backed store implementationUse:
webauthn-client-corewebauthn-client-json-core if you exchange raw JSON with a host/backendwebauthn-client-androidwebauthn-client-ioswebauthn-client-compose for Compose helperswebauthn-client-prf-crypto for PRF-based key derivation and encryption helperswebauthn-network-ktor-client for the default backend contract (HttpClient-based API; add your preferred Ktor engine at app runtime)Start with:
sample/backend-ktorsample/compose-passkeysample/compose-passkey-iossample/passkey-cli for a macOS-first experimental native-authenticator CLI POCDesktop and CLI strategy notes for this repo live in docs/DESKTOP_CLI_STRATEGY.md.
| Module | Who it is for |
|---|---|
platform:bom |
Consumers who want aligned versions across published artifacts |
webauthn-cbor-core |
Parser/crypto modules needing strict low-level CBOR byte scanning primitives |
webauthn-model |
Teams that want typed WebAuthn models and value wrappers |
webauthn-runtime-core |
Shared coroutine-safe error/cancellation boundary helpers for adapter modules |
webauthn-serialization-kotlinx |
Teams mapping JSON/CBOR DTOs to typed models |
webauthn-core |
Teams validating ceremonies and authenticator data |
webauthn-crypto-api |
Teams plugging crypto/attestation implementations into validation and server flows |
webauthn-server-jvm-crypto |
JVM backends that want Signum-first hashing, signature, and attestation verification |
webauthn-server-core-jvm |
JVM backends that need registration/authentication ceremony services |
webauthn-server-ktor |
Ktor backends that want ready-made WebAuthn routes |
webauthn-server-store-exposed |
JVM backends storing WebAuthn state through Exposed |
webauthn-client-core |
Shared passkey orchestration and controller-driven flows |
webauthn-client-json-core |
Apps or SDKs that need raw JSON interoperability on top of typed clients |
webauthn-client-compose |
Compose apps that want remembered client/controller helpers |
webauthn-client-android |
Android apps using Credential Manager |
webauthn-client-ios |
iOS apps using AuthenticationServices |
webauthn-client-prf-crypto |
Client apps deriving crypto sessions from WebAuthn PRF extension outputs |
webauthn-network-ktor-client |
Clients talking to a /webauthn/* backend contract over Ktor (HttpClient contract + caller-selected engine) |
webauthn-attestation-mds |
Backends that want optional FIDO Metadata Service trust anchors |
This repository is publicly released and still pre-1.0.
Current state:
kotlinx-serialization is now on 1.10.0 together with Signum 0.12.0 and indispensable 3.20.0; captured Android assertion-vector regressions are green on this combined dependency set.SECURITY.md.docs/PUBLIC_LAUNCH_CHECKLIST.md.docs/MAVEN_CENTRAL.md.Renovate.tools/agent/setup-hooks.sh
tools/agent/quality-gate.sh --mode fast --scope changed --block false
tools/agent/quality-gate.sh --mode strict --scope changed --block false
./gradlew apiCheck --stacktrace
./gradlew publishToMavenLocal --stacktracedocs/wiki/README.mddocs/CLIENT_FIRST_EXECUTION.mddocs/CLIENT_API_BENCHMARKS.mddocs/IMPLEMENTATION_STATUS.mddocs/ROADMAP.mddocs/ai/STEERING.mdLicense: Apache-2.0. See LICENSE.
Standards-first Kotlin Multiplatform building blocks for WebAuthn and passkey integrations.
This project helps teams implement passwordless login without rebuilding the hardest parts from scratch. It gives you typed protocol models, strict validation, backend ceremony services, platform passkey clients, and optional transport/adaptation modules that stay close to the WebAuthn specification.
This repo focuses on those needs:
| Android | iOS |
|---|---|
WebAuthn has two ceremony pairs:
create)get)Each pair has a server start step and a server finish step, with the platform authenticator in the middle.
sequenceDiagram
autonumber
actor User
participant App as Client App
participant Auth as Platform Authenticator
participant RP as Relying Party Server
note over RP,App: Registration ceremony
App->>RP: registration/start request
RP-->>App: registration/start response (challenge + options)
App->>Auth: navigator.credentials.create / platform create
Auth-->>App: RegistrationResponse
App->>RP: registration/finish (response + echoed challenge)
RP-->>App: verified registration
note over RP,App: Authentication ceremony
App->>RP: authentication/start request
RP-->>App: authentication/start response (challenge + options)
App->>Auth: navigator.credentials.get / platform get
Auth-->>App: AuthenticationResponse
App->>RP: authentication/finish (response + echoed challenge)
RP-->>App: verified sign-inValidation and trust decisions are server responsibilities: challenge/origin/type checks, authenticator data rules, signature/attestation verification, counter handling, and policy decisions.
The repository follows a layered model that keeps protocol and validation concerns separate from transport and platform adapters.
flowchart TB
subgraph Layer1[Layer 1: Protocol Model]
M[webauthn-model]
end
subgraph Layer2[Layer 2: Validation and Serialization]
CBOR[webauthn-cbor-core]
C[webauthn-core]
S[webauthn-serialization-kotlinx]
RUNTIME[webauthn-runtime-core]
end
subgraph Layer3[Layer 3: Crypto Abstractions and Backends]
API[webauthn-crypto-api]
JCRYPTO[webauthn-server-jvm-crypto]
end
subgraph Layer4[Layer 4: Server Services and Adapters]
SVC[webauthn-server-core-jvm]
KTOR[webauthn-server-ktor]
STORE[webauthn-server-store-exposed]
MDS[webauthn-attestation-mds]
end
subgraph Layer5[Layer 5: Client Orchestration and Platform]
CCORE[webauthn-client-core]
CJSON[webauthn-client-json-core]
CANDROID[webauthn-client-android]
CIOS[webauthn-client-ios]
CCOMPOSE[webauthn-client-compose]
CPRF[webauthn-client-prf-crypto]
NET[webauthn-network-ktor-client]
end
M --> C
M --> S
CBOR --> S
C --> API
S --> SVC
CBOR --> JCRYPTO
JCRYPTO --> API
C --> SVC
SVC --> KTOR
SVC --> STORE
MDS --> API
M --> CCORE
RUNTIME --> CCORE
RUNTIME --> CPRF
RUNTIME --> NET
CCORE --> CJSON
CCORE --> CANDROID
CCORE --> CIOS
CCORE --> CCOMPOSE
CCORE --> CPRF
C --> NET
S --> NET
CCORE --> NETFocus modules for this documentation round:
core/ contains reusable protocol, validation, runtime, serialization, and crypto contracts.
client/ contains shared client orchestration, platform bridges, Compose helpers, and client transport.
server/ contains JVM server services, Ktor/store adapters, JVM crypto, and optional trust metadata.
sample/ contains runnable samples and demo entry points; these modules are not published.
webauthn-runtime-core: shared coroutine/failure boundary helpers for adapters.
webauthn-model: typed protocol/value contracts.
webauthn-core: standards-first ceremony validation.
webauthn-client-core: shared passkey orchestration and controller flows.
webauthn-client-compose: Compose integration helpers over client core.
webauthn-client-prf-crypto: PRF-enabled key derivation/session crypto helpers.
Most module READMEs follow this baseline structure (adapted per module when needed):
What it provides: the module's owned responsibilities.When to use: where it belongs in an integration.How to use: practical API snippets plus required caller responsibilities.How it fits in the system: dependency and data-flow context.Pitfalls/limits: common misuse patterns and intentional boundaries.Status: maturity and readiness signal.Recommended adoption paths:
model -> core -> crypto-api -> server-core-jvm (+ server-ktor if you want HTTP adapters).client-core -> platform bridge (+ client-compose for Compose UI).client-prf-crypto only when you need PRF-derived application crypto.The coordinated release train uses one version for the full published surface plus a BOM.
repositories {
google()
mavenCentral()
}Use only the modules your app actually wires in. In Kotlin Multiplatform projects, shared modules belong in commonMain, while concrete platform bridges belong in the matching platform source set.
Client-side KMP example:
kotlin {
sourceSets {
commonMain.dependencies {
implementation(platform("io.github.szijpeter:webauthn-bom:<version>"))
implementation("io.github.szijpeter:webauthn-client-core")
implementation("io.github.szijpeter:webauthn-network-ktor-client") // optional default backend transport
}
androidMain.dependencies {
implementation("io.github.szijpeter:webauthn-client-android") // only if you use AndroidPasskeyClient
}
iosMain.dependencies {
implementation("io.github.szijpeter:webauthn-client-ios") // only if you use IosPasskeyClient
}
}
}JVM/Ktor server example:
dependencies {
implementation(platform("io.github.szijpeter:webauthn-bom:<version>"))
implementation("io.github.szijpeter:webauthn-server-core-jvm")
implementation("io.github.szijpeter:webauthn-server-jvm-crypto")
implementation("io.github.szijpeter:webauthn-server-ktor") // optional route adapter
}Notes:
webauthn-server-* dependencies.webauthn-client-android / webauthn-client-ios when that target instantiates the concrete platform client.commonMain only needs the common modules.sample/compose-passkey, sample/compose-passkey-android, and sample/compose-passkey-ios.Published to Maven Central (latest version is shown in the Maven Central badge above). Maintainers can still validate publication locally with:
./gradlew publishToMavenLocal --stacktraceUse:
webauthn-modelwebauthn-corewebauthn-crypto-apiwebauthn-server-jvm-cryptowebauthn-server-core-jvmwebauthn-server-ktor if you want route adapterswebauthn-server-store-exposed if you want an Exposed-backed store implementationUse:
webauthn-client-corewebauthn-client-json-core if you exchange raw JSON with a host/backendwebauthn-client-androidwebauthn-client-ioswebauthn-client-compose for Compose helperswebauthn-client-prf-crypto for PRF-based key derivation and encryption helperswebauthn-network-ktor-client for the default backend contract (HttpClient-based API; add your preferred Ktor engine at app runtime)Start with:
sample/backend-ktorsample/compose-passkeysample/compose-passkey-iossample/passkey-cli for a macOS-first experimental native-authenticator CLI POCDesktop and CLI strategy notes for this repo live in docs/DESKTOP_CLI_STRATEGY.md.
| Module | Who it is for |
|---|---|
platform:bom |
Consumers who want aligned versions across published artifacts |
webauthn-cbor-core |
Parser/crypto modules needing strict low-level CBOR byte scanning primitives |
webauthn-model |
Teams that want typed WebAuthn models and value wrappers |
webauthn-runtime-core |
Shared coroutine-safe error/cancellation boundary helpers for adapter modules |
webauthn-serialization-kotlinx |
Teams mapping JSON/CBOR DTOs to typed models |
webauthn-core |
Teams validating ceremonies and authenticator data |
webauthn-crypto-api |
Teams plugging crypto/attestation implementations into validation and server flows |
webauthn-server-jvm-crypto |
JVM backends that want Signum-first hashing, signature, and attestation verification |
webauthn-server-core-jvm |
JVM backends that need registration/authentication ceremony services |
webauthn-server-ktor |
Ktor backends that want ready-made WebAuthn routes |
webauthn-server-store-exposed |
JVM backends storing WebAuthn state through Exposed |
webauthn-client-core |
Shared passkey orchestration and controller-driven flows |
webauthn-client-json-core |
Apps or SDKs that need raw JSON interoperability on top of typed clients |
webauthn-client-compose |
Compose apps that want remembered client/controller helpers |
webauthn-client-android |
Android apps using Credential Manager |
webauthn-client-ios |
iOS apps using AuthenticationServices |
webauthn-client-prf-crypto |
Client apps deriving crypto sessions from WebAuthn PRF extension outputs |
webauthn-network-ktor-client |
Clients talking to a /webauthn/* backend contract over Ktor (HttpClient contract + caller-selected engine) |
webauthn-attestation-mds |
Backends that want optional FIDO Metadata Service trust anchors |
This repository is publicly released and still pre-1.0.
Current state:
kotlinx-serialization is now on 1.10.0 together with Signum 0.12.0 and indispensable 3.20.0; captured Android assertion-vector regressions are green on this combined dependency set.SECURITY.md.docs/PUBLIC_LAUNCH_CHECKLIST.md.docs/MAVEN_CENTRAL.md.Renovate.tools/agent/setup-hooks.sh
tools/agent/quality-gate.sh --mode fast --scope changed --block false
tools/agent/quality-gate.sh --mode strict --scope changed --block false
./gradlew apiCheck --stacktrace
./gradlew publishToMavenLocal --stacktracedocs/wiki/README.mddocs/CLIENT_FIRST_EXECUTION.mddocs/CLIENT_API_BENCHMARKS.mddocs/IMPLEMENTATION_STATUS.mddocs/ROADMAP.mddocs/ai/STEERING.mdLicense: Apache-2.0. See LICENSE.