Android / Kotlin SDK
Integrate TrustPin into your Android or JVM application for native certificate pinning.
Current version: cloud.trustpin:kotlin-sdk 5.0.0
Platform Requirements
| Platform | Minimum Version |
|---|---|
| Android | API 25+ (full feature support) |
| JVM | Java 11+ |
Kotlin Version: 2.3.0+
Note: The Maven Central artifact is an Android AAR. For server-side JVM, desktop, or Compose Multiplatform targets, request access to the hardened JVM JAR via support@trustpin.cloud.
Installation
Gradle (Kotlin DSL)
Add TrustPin to your build.gradle.kts:
dependencies {
implementation("cloud.trustpin:kotlin-sdk:5.0.0")
}Gradle (Groovy)
Add to your build.gradle:
dependencies {
implementation 'cloud.trustpin:kotlin-sdk:5.0.0'
}Maven
Add to your pom.xml:
<dependency>
<groupId>cloud.trustpin</groupId>
<artifactId>kotlin-sdk</artifactId>
<version>5.0.0</version>
</dependency>Quick Start
1. Get Your Credentials
Sign in to the TrustPin Dashboard and retrieve:
- Organization ID
- Project ID
- Public Key (Base64-encoded)
2. Initialize TrustPin
Ship a trustpin.json asset in your app and load it with TrustPinConfiguration.fromAssets(context). Credentials stay out of source.
Place trustpin.json at app/src/main/assets/trustpin.json:
{
"organization_id": "your-org-id",
"project_id": "your-project-id",
"public_key": "your-base64-public-key",
"mode": "strict"
}Build-variant overrides follow standard Android source-set merging — drop a different file under src/debug/assets/trustpin.json or src/staging/assets/trustpin.json to use per-flavor credentials.
| Key | Type | Required | Notes |
|---|---|---|---|
organization_id | String | Yes | Non-empty |
project_id | String | Yes | Non-empty |
public_key | String | Yes | Base64-encoded ECDSA P-256 public key |
mode | String | No | "strict" (default) or "permissive" |
configuration_url | String | No | Must be HTTPS. Overrides the default CDN endpoint |
Then load it during Application.onCreate():
import android.app.Application
import cloud.trustpin.kotlin.sdk.TrustPin
import cloud.trustpin.kotlin.sdk.TrustPinConfiguration
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
CoroutineScope(Dispatchers.IO).launch {
try {
val config = TrustPinConfiguration.fromAssets(this@MyApplication)
TrustPin.setup(config)
TrustPin.requirePinned()
println("TrustPin initialized")
} catch (e: Exception) {
println("TrustPin setup failed: ${e.message}")
}
}
}
}TrustPin.requirePinned() is a belt-and-suspenders gate — call it once after setup, immediately before constructing any HTTP client that depends on pinning, to fail loudly if the configuration didn’t load.
Don’t forget to register your Application class in AndroidManifest.xml:
<application
android:name=".MyApplication"
...>
</application>3. Add Network Permission
Ensure your AndroidManifest.xml includes:
<uses-permission android:name="android.permission.INTERNET" />Integration Approaches
| Approach | Best For | Setup Complexity |
|---|---|---|
| OkHttp Integration (Recommended) | Most Android apps | 🟢 Low |
| Retrofit Integration | REST API clients (uses OkHttp under the hood) | 🟢 Low |
| Ktor Client Integration | Ktor-based apps and KMP shared modules | 🟡 Medium |
| Manual Verification | Custom transports, non-OkHttp stacks | 🟠 High |
OkHttp Integration (Recommended)
TrustPinSSLSocketFactory.create() returns an SSL socket factory wired to your TrustPin configuration. Pass it — along with its trust manager — to OkHttpClient.Builder:
import cloud.trustpin.kotlin.sdk.ssl.TrustPinSSLSocketFactory
import okhttp3.OkHttpClient
import java.util.concurrent.TimeUnit
val sslSocketFactory = TrustPinSSLSocketFactory.create()
val httpClient = OkHttpClient.Builder()
.connectTimeout(30, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS)
.sslSocketFactory(sslSocketFactory, sslSocketFactory.trustManager())
.build()Retrofit Integration
Retrofit uses OkHttp under the hood — share the same TrustPin-backed client:
class ApiClient {
private val okHttpClient by lazy {
val sslSocketFactory = TrustPinSSLSocketFactory.create()
OkHttpClient.Builder()
.connectTimeout(30, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.sslSocketFactory(sslSocketFactory, sslSocketFactory.trustManager())
.build()
}
private val retrofit by lazy {
Retrofit.Builder()
.baseUrl("https://api.example.com/")
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create())
.build()
}
}Ktor Client Integration
Plug TrustPin into Ktor’s OkHttp engine:
import io.ktor.client.*
import io.ktor.client.engine.okhttp.*
import okhttp3.OkHttpClient
private val httpClient by lazy {
val sslSocketFactory = TrustPinSSLSocketFactory.create()
HttpClient(OkHttp) {
engine {
preconfigured = OkHttpClient.Builder()
.sslSocketFactory(sslSocketFactory, sslSocketFactory.trustManager())
.build()
}
}
}Manual Verification
For custom transports, validate a domain/certificate pair directly with the suspending API:
import java.security.cert.X509Certificate
val certificate: X509Certificate = /* ... */
TrustPin.verify("api.example.com", certificate)Named Instances (Multi-Tenant)
The SDK supports independent named instances via TrustPin.instance(id) for apps that talk to multiple TrustPin projects (for example, separate consumer and admin backends). Because the bundled-asset path loads a single trustpin.json per build, multi-tenant setups currently require the programmatic configuration API — see the upstream Kotlin SDK docs for usage.
Logging
Set the desired verbosity before calling setup() to capture initialization logs:
import cloud.trustpin.kotlin.sdk.TrustPinLogLevel
TrustPin.setLogLevel(TrustPinLogLevel.INFO)Available levels: NONE, ERROR, INFO, DEBUG.
Error Handling
TrustPinError is a sealed class with the following variants:
| Variant | Meaning |
|---|---|
DomainNotRegistered | Strict mode and the host isn’t in the configuration |
PinsMismatch | Server certificate doesn’t match any active pin |
AllPinsExpired | Configuration is stale — rotate pins in the dashboard |
InvalidServerCert | Server returned an unparseable certificate |
InvalidProjectConfig | Bad credentials or invalid configuration |
ErrorFetchingPinningInfo | Network failure while loading the configuration |
ConfigurationValidationFailed | JWS signature didn’t verify against the project’s public key |
NotInitialized | An API was called before setup() completed successfully |
UnsupportedDevice | The runtime environment doesn’t support the required security primitives |
try {
TrustPin.setup(config)
} catch (e: TrustPinError.InvalidProjectConfig) {
// Bad credentials
} catch (e: TrustPinError.ErrorFetchingPinningInfo) {
// Network failure during setup
} catch (e: TrustPinError.NotInitialized) {
// setup() wasn't called, or it failed silently — guard with requirePinned()
} catch (e: TrustPinError) {
// Any other TrustPin failure (UnsupportedDevice, etc.)
}Best Practices
Setup & Initialization
- Initialize in
Application.onCreate()for app-wide coverage. - Use a coroutine scope for async setup — the 5.0 API is suspend-only.
- Call
TrustPin.requirePinned()aftersetup(), before constructing any HTTP client that depends on pinning. - Set the log level before
setup()to capture initialization output. - Handle setup errors gracefully — don’t block app launch.
Security
- Use
TrustPinMode.STRICTin production. - Prefer SPKI pinning; rotate pins in the dashboard before they expire.
- Monitor pin validation failures.
- Keep credentials outside source control — prefer
TrustPinConfiguration.fromAssets(context)with per-flavortrustpin.jsonfiles, or fetch them at runtime and usewithAndroidStorage(context). - Use HTTPS for all pinned domains.
Performance
- Configuration is cached for 10 minutes with a stale-while-revalidate fallback.
- Reuse
OkHttpClientinstances rather than creating one per request. - Use minimal log levels in production.
Complete Documentation
For the full API reference, ProGuard/R8 rules, and additional integration patterns, visit:
Resources
- Repository: github.com/trustpin-cloud/kotlin.sdk
- API Reference: trustpin-cloud.github.io/kotlin.sdk
- Maven Coordinates:
cloud.trustpin:kotlin-sdk:5.0.0 - Dashboard: app.trustpin.cloud
- Support: support@trustpin.cloud