Authentication
Every call mero-kotlin makes carries a JWT access token. There are two ways to obtain one — direct credentials and hosted SSO — and the SDK keeps it fresh for you.
Direct credentials
Section titled “Direct credentials”For first-party apps, exchange a username and password for a token bundle.
bootstrapSecret is only needed for the very first login on a fresh node.
mero.authenticate( Credentials( username = "alice", password = "s3cr3t", bootstrapSecret = "…", // only on a fresh node's first login ))val authed = mero.isAuthenticated // trueYou can also put credentials in the config and call authenticate() with no
argument:
val mero = Mero( MeroConfig( baseUrl = "https://your-node.example", credentials = Credentials(username = "alice", password = "s3cr3t"), ))mero.authenticate() // uses config.credentials, else throws MeroStateExceptionThe token lifecycle
Section titled “The token lifecycle”Refresh is reactive: the SDK never refreshes proactively (the server rejects
a refresh while the access token is still valid). A 401 with
x-auth-error: token_expired drives a single refresh and one retry — invisible
to the caller.
A single-flight RefreshCoordinator inside Mero serialises refresh so
concurrent requests that all hit a 401 share one in-flight refresh. Because
refresh tokens are single-use (rotated on every refresh), it re-reads the
token store first — so if another process or a background worker already rotated
the token, that newer bundle is adopted instead of replaying a consumed one
(which would revoke the whole token family). Supplying a refreshLockFile in the
config extends that guarantee across processes via an exclusive file lock.
Hosted SSO (deep link)
Section titled “Hosted SSO (deep link)”For hosted login, open the node’s login URL, and feed the callback deep link back
in — the native analog of the web redirect flow. On Android, SsoLauncher opens
the URL in a Chrome Custom Tab:
import com.calimero.mero.Meroimport com.calimero.mero.auth.AuthLoginOptionsimport com.calimero.mero.auth.SsoLauncherimport com.calimero.mero.TokenData
// 1. Launch the hosted login (opens a Custom Tab).SsoLauncher.launch( context, nodeUrl = "https://your-node.example", options = AuthLoginOptions(callbackUrl = "myapp://auth-callback", mode = "login", permissions = listOf("admin")),)
// 2. In the deep-link Activity that receives myapp://auth-callback:val callback = Mero.parseAuthCallback(intent.dataString ?: "")if (callback != null) { mero.setTokenData( TokenData(callback.accessToken, callback.refreshToken, expiresAt = 0L) ) // callback also carries applicationId, contextId, contextIdentity, nodeUrl}parseAuthCallback reads the URL hash fragment
(access_token, refresh_token, application_id, context_id,
context_identity, node_url) and returns null if no access token is present.
Passing expiresAt = 0L tells setTokenData to derive the real expiry from the
JWT. Both SSO helpers are also standalone functions in
com.calimero.mero.auth.
Persistence
Section titled “Persistence”Pass a tokenStore in the config so tokens survive app launches.
EncryptedPrefsTokenStore (AndroidX Security, hardware-backed key) is the secure
default; the memory store is ephemeral.
// Secure, persisted across launches — AndroidX EncryptedSharedPreferencesval mero = Mero( MeroConfig( baseUrl = "https://your-node.example", tokenStore = EncryptedPrefsTokenStore(context), ))
// Isolate multiple nodes with distinct files:val store = EncryptedPrefsTokenStore(context, fileName = "mero_tokens_prod")
// Ephemeral (the default when tokenStore is null)val ephemeral = Mero( MeroConfig(baseUrl = "https://your-node.example", tokenStore = MemoryTokenStore()))Implement TokenStore (getTokens / setTokens / clear, all synchronous) to
back tokens with anything else — see the reference.
Inspecting and clearing auth state
Section titled “Inspecting and clearing auth state”mero.isAuthenticated // Boolean — is a bundle present?mero.getTokenData() // TokenData? (debugging / handoff)mero.clearToken() // drop the bundle + clear the store (local only)mero.logout() // clearToken() + best-effort server revoke