Building cross-platform apps with Kotlin Multiplatform (KMP) saves time, but writing a custom authentication wrapper for each platform should not be part of the job. Auth0 now ships an official Kotlin Multiplatform SDK for Android and iOS. You manage Universal Login, direct Authentication API calls, and secure credential storage in common Kotlin code, and it runs natively on both platforms.
Simplifying Cross-Platform Authentication
Here is how the SDK simplifies authentication across both the platforms:
- Write authentication once: The API lives in
commonMain, so your login, logout, and token logic is shared Kotlin code with no per-platform wrapper to build or keep in sync. - Native where it counts: Secure token storage and the login browser both run on each platform's native APIs: a
Keystore-backed DataStoreandCustom Tabson Android, theKeychainandASWebAuthenticationSessionon iOS. - Idiomatic in both languages: Kotlin gets
suspendfunctions and a sealedResulttype. Through Swift Kotlin Interface Enhancer (SKIE), those same calls surface in Swift asasync/awaitwith an exhaustiveswitch. - One consistent model: A single
Resulttype and typed error hierarchy span every feature, eliminating thrown exceptions and keeping success and error handling uniform. - Flexible architecture: Start with the umbrella
auth0module, or depend only on the features you need.
Installing the SDK
Add the auth0 module to your shared module's commonMain dependencies. It bundles authentication, Web Auth, and credential management into one artifact:
// shared/build.gradle.kts kotlin { sourceSets { commonMain.dependencies { implementation("com.auth0.kmp:auth0:1.0.0-beta.1") } } }
Before getting started, make sure your project meets a few baseline requirements. You will need at least Kotlin 2.3.21, Android minSdk 24 or higher, and iOS 14.0 or higher.
If you prefer a smaller footprint, depend on individual feature modules such as auth0-webauth or auth0-credentials instead of the auth0 module.
Configuring the Native Platforms
Universal Login relies on native browser redirects, so each platform needs a short one-time setup. In both cases, register the resulting callback URL under your application's Allowed Callback URLs in the Auth0 Dashboard.
Android
Declare your Auth0 domain and redirect scheme through manifest placeholders in your app module's build.gradle.kts:
// androidApp/build.gradle.kts android { defaultConfig { manifestPlaceholders["auth0Scheme"] = "https" // or a custom scheme manifestPlaceholders["auth0Domain"] = "YOUR_DOMAIN" } }
The SDK captures the application Context automatically through AndroidX Startup, without requiring an extra dependency. The callback URL uses the following format:
{scheme}://YOUR_DOMAIN/android/YOUR_APP_PACKAGE_NAME/callback
iOS
The callback URL uses a custom scheme, derived by default from your bundle identifier, or https:
{scheme}://YOUR_DOMAIN/ios/YOUR_BUNDLE_IDENTIFIER/callback
Initializing the Client
Everything begins with an Auth0Account, which holds your Auth0 domain and client ID. Pass it to Auth0, which manages a single network transport shared across every client it creates:
import com.auth0.kmp.Auth0 import com.auth0.kmp.core.Auth0Account val account = Auth0Account( clientId = "<YOUR_CLIENT_ID>", domain = "<YOUR_DOMAIN>", ) val auth0 = Auth0(account)
The auth0 instance provides browser authentication (webAuth), direct API calls (authentication), and secure credential management (credentials()).
Authenticating Users with Web Auth
Calling auth0.webAuth.login(...) opens the system browser for Universal Login. Every client method is a suspend function that returns a Result, so you can handle success and failure exhaustively with when without catching exceptions:
import com.auth0.kmp.core.result.Result import com.auth0.kmp.webauth.LoginOptions when (val result = auth0.webAuth.login( LoginOptions(scope = "openid profile email offline_access") )) { is Result.Success -> { val credentials = result.data // credentials.accessToken, credentials.idToken, credentials.refreshToken } is Result.Failure -> { // result.error is a WebAuthError } }
To end the session in the browser, call logout:
import com.auth0.kmp.webauth.LogoutOptions auth0.webAuth.logout()
Managing Credentials Securely
The built-in Credentials Manager stores tokens securely and renews the access token with the refresh token when it has expired. On Android, it uses a Keystore-backed, encrypted DataStore; on iOS, it uses the Keychain for storage:
import com.auth0.kmp.core.result.Result val manager = auth0.credentials() manager.saveCredentials(credentials) // Get valid credentials, renewing them automatically if needed: when (val result = manager.getCredentials()) { is Result.Success -> { val accessToken = result.data.accessToken // Use accessToken to call your API } is Result.Failure -> { // result.error is a CredentialsManagerError } } // Check validity without triggering a renewal: val loggedIn = manager.hasValidCredentials() // On logout: manager.clearCredentials()
When you finish with the SDK instance, call auth0.close() to release the shared network transport.
Exploring Advanced Features
Beyond the standard authentication and authorization features, the SDK supports several advanced capabilities out of the box:
- Direct Authentication API: Sign users in with a username and password, create users, and fetch profiles directly through
auth0.authentication. - WebAuthn passkeys: Enroll and sign in with a passkey instead of a password.
- Call multiple APIs from one login: Exchange the refresh token for audience-scoped tokens with
getApiCredentials(...). - Native-to-web SSO: Continue a native session in the browser using a session-transfer token.
- Sender-constrained tokens: Bind tokens to your app with
DPoP (RFC 9449)so a stolen token is useless elsewhere; setuseDPoP = trueonAuth0Account. - Custom credential stores: Supply your own
Storageimplementation. - Configurable retries: Opt into retries with fixed or exponential backoff on API requests by setting a
RetryPolicyinRequestOptions.
See EXAMPLES.md for in-depth examples of each.
Try it Yourself
The SDK is live on Maven Central. Point it to your Kotlin Multiplatform application, and you have authentication running on both platforms.
- Source, README, and sample apps: github.com/auth0/auth0-kmp
- Quickstart : KMP Quickstart
- Examples: KMP EXAMPLES.md
- Feedback and issues: the Auth0 KMP issue tracker
If you do not already have an Auth0 account yet, create one for free.
About the author

Prince Mathew
Senior Software Engineer
