v0.3.0 — Now on Maven Central

Secrets storage,
done right for KMP.

A coroutine-first Kotlin Multiplatform library that wraps native secure storage — EncryptedSharedPreferences on Android and Keychain Services on iOS — behind one tiny, suspendable API. No hand-rolled crypto.

dependencies {
    implementation("io.github.alims-repo:secure-vault:0.3.0")
    // Optional — Compose Multiplatform helpers:
    implementation("io.github.alims-repo:secure-vault-compose:0.3.0")
}
# gradle/libs.versions.toml
[libraries]
secure-vault = { module = "io.github.alims-repo:secure-vault", version = "0.3.0" }
secure-vault-compose = { module = "io.github.alims-repo:secure-vault-compose", version = "0.3.0" }
dependencies {
    implementation 'io.github.alims-repo:secure-vault:0.3.0'
    implementation 'io.github.alims-repo:secure-vault-compose:0.3.0'
}
Why SecureVault

Designed like a library you'd actually want to depend on.

Small surface, sealed errors, suspending I/O, explicit visibility — every public symbol earns its place.

OS-native crypto

No bespoke ciphers. AES-256-GCM via the Android Keystore on one side, Keychain Services on the other — you inherit OS guarantees, not custom risk.

Coroutine-first

Every operation is suspend and dispatches onto the right I/O dispatcher per platform. No manual withContext, no blocked main threads.

Sealed errors

One VaultException hierarchy: InvalidKey, CryptoFailure, Tampered, StorageUnavailable. Catch what matters, ignore platform noise.

Namespaced

Vaults are scoped per VaultConfig.namespace. Isolate auth tokens from feature flags, or one product from another in the same app.

Tiny API

Six suspending methods total: put, get, remove, contains, clear, keys. That's the whole library.

ABI-stable

Public surface pinned with binary-compatibility-validator. Patch releases never break consumers — by construction.

Usage

One API. Two native backends.

Write your business logic against SecureVault in commonMain. One factory call, identical on every target.

commonMain/AuthRepository.kt
class AuthRepository(
    private val vault: SecureVault,
) {
    suspend fun saveSession(token: String) =
        vault.put("session", token)

    suspend fun session(): String? =
        vault.get("session")

    suspend fun logout() =
        vault.remove("session")
}
androidMain/App.kt
class App : Application() {
    override fun onCreate() {
        super.onCreate()
        // no Context plumbing — captured via androidx.startup
        val vault = SecureVault("com.acme.auth")
    }
}
iosApp/ContentView.swift
let vault = SecureVaultsKt.SecureVault(
    namespace: "com.acme.auth",
    accessibility: .afterFirstUnlock
)
API at a glance

Six methods. That's the whole contract.

All methods are suspend and may throw VaultException. Full KDoc shipped in the artefact's sources jar.

SignatureDescription
put(key, value)Store a value, overwriting any previous one.
get(key)Return the value for key, or null if absent.
remove(key)Delete the entry. Idempotent — no-op if the key isn't present.
contains(key)Return true if a value is currently stored under key.
clear()Remove every entry inside this vault's namespace.
keys()Snapshot of the current key set in this namespace.
Supported targets

Where it runs.

More targets (JVM/Desktop, watchOS) are planned for v0.2 — see the changelog for the roadmap.

TargetBackend
androidEncryptedSharedPreferences (Android Keystore)
iosArm64Keychain Services (kSecClassGenericPassword)
iosSimulatorArm64Keychain Services (kSecClassGenericPassword)