SeleID

Quickstart

Android (Kotlin)

Overview · React Native and Expo · Android · iOS · Register an app · API reference · Errors and security · Changelog

Coming soon @seletech/seleid-client is not on npm yet. These pages describe version 0.1.0 so you can plan an integration. See the roadmap.

There is no Kotlin SDK yet (Planned). The published TypeScript SDK does not run natively. Until a native SDK exists, Android apps use the protocol directly. The snippets below show the protocol steps; they are not SeleID APIs and are untested against production, where sign-in for outside apps is not open.

The token endpoint answers with the standard snake_case fields (access_token, token_type, expires_in, id_token, refresh_token, scope), so a standard OpenID library such as AppAuth can parse it. Older camelCase aliases are still present for our own apps and are deprecated; do not rely on them. Sign-in for outside apps is Planned: it stays off until SeleTech switches it on for registered apps.

Endpoints

PurposeURL
Discoveryhttps://auth.seleid.dev/.well-known/openid-configuration
Authorize (browser)https://auth.seleid.dev/authorize
Token (POST, form-encoded)https://auth.seleid.dev/oauth/token (confidential apps: client_secret_basic or client_secret_post; public apps: PKCE only)
Userinfo (GET, Bearer access token; Planned, off by default)https://auth.seleid.dev/oauth/userinfo
Revocation (POST, RFC 7009; Planned, off by default)https://auth.seleid.dev/oauth/revoke
Session check (GET, Bearer access token; Planned, off by default)https://auth.seleid.dev/v1/session/context
Signing keyshttps://auth.seleid.dev/.well-known/jwks.json

Required authorize parameters: client_id, exact redirect_uri, response_type=code, scope containing openid, state, nonce (16 to 256 characters), code_challenge (S256, 43 to 128 characters). Token request: grant_type=authorization_code, client_id, code, redirect_uri, code_verifier; refresh uses grant_type=refresh_token, client_id, refresh_token. Refresh tokens rotate: persist the new one before using it, never replay a refresh request.

PKCE and the authorize request

Pkce.kt

import android.util.Base64
import java.security.MessageDigest
import java.security.SecureRandom

fun randomUrlSafe(bytes: Int = 32): String {
    val raw = ByteArray(bytes).also { SecureRandom().nextBytes(it) }
    return Base64.encodeToString(raw, Base64.URL_SAFE or Base64.NO_WRAP or Base64.NO_PADDING)
}

fun challengeFor(verifier: String): String {
    val digest = MessageDigest.getInstance("SHA-256").digest(verifier.toByteArray(Charsets.US_ASCII))
    return Base64.encodeToString(digest, Base64.URL_SAFE or Base64.NO_WRAP or Base64.NO_PADDING)
}

SignIn.kt

// Open with Chrome Custom Tabs (androidx.browser:browser), never an embedded WebView.
val uri = android.net.Uri.parse("https://auth.seleid.dev/authorize").buildUpon()
    .appendQueryParameter("client_id", CLIENT_ID)
    .appendQueryParameter("redirect_uri", "com.example.app:/seleid")
    .appendQueryParameter("response_type", "code")
    .appendQueryParameter("scope", "openid profile email")
    .appendQueryParameter("state", state)
    .appendQueryParameter("nonce", nonce)
    .appendQueryParameter("code_challenge", challengeFor(verifier))
    .appendQueryParameter("code_challenge_method", "S256")
    .build()
androidx.browser.customtabs.CustomTabsIntent.Builder().build().launchUrl(context, uri)

Declare an intent filter for your custom scheme on the activity that receives the redirect, read code and state from the intent data, compare state with the saved value, then POST the code to the token endpoint from a background thread with the saved code_verifier.

Token storage

Keep the refresh token in encrypted storage, for example EncryptedSharedPreferences or a Keystore-wrapped key, never in plain SharedPreferences, logs or backups. Exclude the file from Auto Backup.

Session checks

The server-side session check (GET /v1/session/context) is Planned. Until it exists, treat a refusal on refresh (invalid_grant) as signed out and a timeout or 5xx as “unknown” (retry, do not sign out).

Register for updates on the roadmap. A Kotlin SDK mirroring the TypeScript one is Planned.

Last updated 2026-11-12Suggest an editReport a problem with this page