developers

One SDK, Multiple Platforms: Introducing the Auth0 SDK for Kotlin Multiplatform

Add login, logout, and secure token storage to iOS and Android apps using the Auth0 Kotlin Multiplatform SDK. Simplify cross-platform auth.

Oct 14, 2026 • 5 min read

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 DataStore and Custom Tabs on Android, the Keychain and ASWebAuthenticationSession on iOS.
  • Idiomatic in both languages: Kotlin gets suspend functions and a sealed Result type. Through Swift Kotlin Interface Enhancer (SKIE), those same calls surface in Swift as async/await with an exhaustive switch.
  • One consistent model: A single Result type and typed error hierarchy span every feature, eliminating thrown exceptions and keeping success and error handling uniform.
  • Flexible architecture: Start with the umbrella auth0 module, 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; set useDPoP = true on Auth0Account.
  • Custom credential stores: Supply your own Storage implementation.
  • Configurable retries: Opt into retries with fixed or exponential backoff on API requests by setting a RetryPolicy in RequestOptions.

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.

If you do not already have an Auth0 account yet, create one for free.

About the author

Prince Mathew

Prince Mathew

Senior Software Engineer

Prince Mathew is a Senior Engineer passionate about Identity, Security and Developer Experience. He enjoys exploring and building new things and solving pain points for other engineers.View profile