Getting Started
The Identity Development Kit (IDK) is a Kotlin Multiplatform library providing foundational technologies for digital identity, mobile credentials (mDocs/ISO 18013-5), and cryptographic operations.
Platform Support
- Android (minSdk 27, targetSdk 35, Java 17+)
- iOS (iosX64, iosArm64, iosSimulatorArm64)
- JVM (Java 21+)
- JavaScript/WASM (experimental)
Installation
Add to your build.gradle.kts:
dependencies {
// Core APIs and utilities
implementation("com.sphereon.idk:lib-core-api-public:0.10.0")
// Cryptography (KMS providers, signing, verification)
implementation("com.sphereon.idk:lib-crypto-core:0.10.0")
implementation("com.sphereon.idk:lib-crypto-kms-common:0.10.0")
// Mobile credentials - ISO 18013-5 (mDL/mDoc)
implementation("com.sphereon.idk:lib-mdoc-core:0.10.0")
implementation("com.sphereon.idk:lib-mdoc-datatransfer:0.10.0")
// CBOR encoding/decoding
implementation("com.sphereon.idk:lib-cbor:0.10.0")
// Or include all libraries
implementation("com.sphereon.idk:lib-all:0.10.0")
}
Key Features
Mobile Credentials (mDoc/mDL)
Complete ISO/IEC 18013-5 implementation for mobile driving licenses and credentials:
- Device engagement (QR code, NFC, BLE)
- Data transfer protocols with session encryption
- Selective disclosure and reader authentication
- Works on Android and iOS
Cryptography & Key Management
Multiplatform cryptographic operations with pluggable KMS providers:
- Mobile: iOS Secure Enclave, Android Keystore
- Cloud: AWS KMS, Azure Key Vault/HSM
- Software: Ephemeral in-memory keys
- Supports RSA, ECDSA, COSE signatures
Data Link Layer
- BLE: Bluetooth Low Energy GATT for Android/iOS
- NFC: Host Card Emulation (Android), NFC tag reading
Trust Establishment
X.509 certificate validation and trust list management:
- ETSI Trust Lists: TS 119 612 support for EU qualified trust services
- Certificate validation: Path building, revocation checking
- Trust anchors: CA bundles, DID resolution, OpenID Federation
- Multi-model: Extensible framework for custom trust models
Configuration & Multi-Tenancy
- Dependency Injection: Kotlin Inject / Amazon LastMile DI with KSP code generation
- Configuration abstractions: Type-safe provider configs (AWS, Azure, Software, Mobile)
- Multi-tenant support: Isolated key storage by tenant, principal, or session
- Spring Boot integration: REST API, and application mode for multi-tenant services
Quick Start: mDoc Holder
Present credentials via QR code + BLE:
import com.sphereon.mdoc.engagement.*
import com.sphereon.mdoc.transfer.*
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
// 1. Get engagement manager (injected via DI)
val manager: MdocEngagementManager = getEngagementManager()
// 2. Create engagement with QR + BLE transport
manager.createEngagement {
engagement { qr { scheme = "mdoc:" } }
retrieval { ble { centralClientMode = true } }
}
// 3. Display QR code
val qrEngagement = manager.qrEngagement.value
displayQrCode(qrEngagement.uri)
// 4. Handle session events
launch {
manager.eventHub.sessionState.collect { state ->
when (state.phase) {
UiPhase.ENGAGEMENT -> {
if (state.qrMode == QrMode.DISPLAY) showQr()
if (state.nfcState == NfcState.FOREGROUND) showNfcPrompt()
}
UiPhase.TRANSFER -> {
if (state.userInteractionRequired) {
showConsentDialog(state.deviceRequest!!)
}
}
UiPhase.TERMINAL -> {
when (state.terminalOutcome) {
TerminalOutcome.SUCCESS -> showSuccess()
TerminalOutcome.ERROR -> showError()
}
}
}
}
}
Quick Start: Cryptography
The cryptography system uses KeyManagerService as the central entry point, typically injected via DI. KMS providers are configured through properties or programmatically via config objects.
import com.sphereon.crypto.kms.*
import com.sphereon.crypto.kms.provider.software.*
// 1. Get DI components (typically via Kotlin Inject)
val app = MyAppComponent.create(...)
val session = app.userContextManager
.getAnonymous()
.sessionContextManager
.createOrGetFromId("session-id")
// 2. KeyManagerService is injected with providers from configuration
// Providers are created from PrincipalConfig properties like:
// kms.providers.software.type = "software"
// kms.providers.aws.type = "aws"
// kms.providers.aws.region = "us-east-1"
val keyManager = session.keyManagerService
// 3. Generate key (uses default provider or specify provider ID)
val keyPair = keyManager.generateKeyAsync(
alg = SignatureAlgorithm.ES256
)
// 4. Get key info for signing
val keyInfo = keyPair.toManagedKeyInfo<CoseKeyType>(
visibility = KeyVisibility.PUBLIC,
encoding = KeyEncoding.COSE
)
// 5. Sign data
val signature = keyManager.createRawSignature(
keyInfo = keyInfo,
input = "Hello, World!".encodeToByteArray(),
requireX5Chain = false
)
val isValid = keyManager.isValidRawSignature(
keyInfo = keyInfo,
input = "Hello, World!".encodeToByteArray(),
signature = signature
)
Programmatic Configuration
You can also create providers programmatically:
// Create provider from config object
val softwareProvider = SoftwareKmsProviderImpl(
config = SoftwareKmsProviderConfig(id = "software"),
execution = session.asCoreApiServiceComponent().serviceExecution,
keyStoreManager = null
)
// Initialize KeyManagerService with providers
val keyManager = KeyManagerServiceImpl(
kmsProviders = setOf(softwareProvider),
keyResolvers = setOf(CoseJoseProvidedKeyResolverServiceImpl(X509VerifyServiceImpl()))
)
Multi-Tenancy Support
Key storage is scoped by DI context (app/tenant/principal/session):
// Scoping is handled by DI framework
// Keys are automatically isolated by:
// - APP: Shared across application
// - TENANT: Isolated per tenant (REST APIs)
// - PRINCIPAL_TENANT: Isolated per user + tenant
// - SESSION: Isolated per session (default for mobile)
Quick Start: Trust Validation
Validate certificates against ETSI trust lists:
import com.sphereon.trust.etsi.*
import com.sphereon.crypto.resolution.*
// 1. Resolve ETSI trust list (via identifier resolution)
val tslResult = identifierService.resolve(
ExternalIdentifierETSITslOpts(
identifier = "https://ec.europa.eu/tools/lotl/eu-lotl.xml",
verifySignature = true,
territory = "EU"
)
) as ExternalIdentifierETSITslResult
// 2. Extract trust anchors from trust list
val trustAnchors = tslResult.trustAnchors
.mapNotNull { it.certificateDER?.encodeToBase64() }
// 3. Validate certificate against trust anchors
val x5cResult = identifierService.resolve(
ExternalIdentifierX5cOpts(
identifier = listOf(certToValidate.encodeToBase64()),
trustAnchors = trustAnchors,
verify = true
)
) as ExternalIdentifierResult.X5c
// 4. Check validation result
val isTrusted = x5cResult.verificationResult.valid
Resources
- GitHub Repository
- ISO/IEC 18013-5:2021 - Mobile Driving License standard
- ETSI TS 119 612 - Electronic Signatures and Trust Services
- Changelog