Android SDK
Integrate TrustPin into your Android application for comprehensive certificate pinning security.
Platform Requirements
| Platform | Minimum Version | Features |
|---|---|---|
| Android | API 21 (Android 5.0 Lollipop) | OkHttp interceptor, TrustManager, SSL Socket Factory |
| JVM | Java 11+ | SSL Socket Factory, Manual verification |
Kotlin Version: 1.9.0+
Note: While the SDK supports Android API 21+, we recommend API 23+ (Android 6.0 Marshmallow) for improved security features and TLS 1.2 support by default.
Installation
Gradle (Kotlin DSL)
Add TrustPin to your build.gradle.kts:
dependencies {
implementation("cloud.trustpin:kotlin-sdk:2.0.0")
}Gradle (Groovy)
Add to your build.gradle:
dependencies {
implementation 'cloud.trustpin:kotlin-sdk:2.0.0'
}Maven
Add to your pom.xml:
<dependency>
<groupId>cloud.trustpin</groupId>
<artifactId>kotlin-sdk</artifactId>
<version>2.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
Add this to your Application class:
import cloud.trustpin.kotlin.sdk.TrustPin
import cloud.trustpin.kotlin.sdk.TrustPinMode
import android.app.Application
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.launch
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
lifecycleScope.launch {
try {
TrustPin.setup(
organizationId = "your-org-id",
projectId = "your-project-id",
publicKey = "your-base64-public-key",
mode = TrustPinMode.STRICT
)
println("TrustPin initialized")
} catch (e: Exception) {
println("TrustPin setup failed: ${e.message}")
}
}
}
}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 with OkHttp
OkHttp Interceptor (Recommended)
The easiest way to integrate TrustPin with OkHttp:
import cloud.trustpin.kotlin.okhttp.TrustPinOkHttpInterceptor
import okhttp3.OkHttpClient
val client = OkHttpClient.Builder()
.addInterceptor(TrustPinOkHttpInterceptor())
.build()
// Use with Retrofit
val retrofit = Retrofit.Builder()
.baseUrl("https://api.example.com/")
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.build()SSL Socket Factory
For direct OkHttp configuration:
import cloud.trustpin.kotlin.okhttp.TrustPinSSLSocketFactory
import okhttp3.OkHttpClient
val client = OkHttpClient.Builder()
.sslSocketFactory(
TrustPinSSLSocketFactory(),
TrustPinX509TrustManager()
)
.build()Integration with HttpsURLConnection
Global Configuration
Set TrustPin globally for all HttpsURLConnection requests:
import cloud.trustpin.kotlin.okhttp.TrustPinSSLSocketFactory
import javax.net.ssl.HttpsURLConnection
// Apply globally
HttpsURLConnection.setDefaultSSLSocketFactory(TrustPinSSLSocketFactory())
// Now all HttpsURLConnection requests use certificate pinning
val connection = URL("https://api.example.com/data")
.openConnection() as HttpsURLConnectionPer-Connection Configuration
Apply to specific connections:
import cloud.trustpin.kotlin.okhttp.TrustPinSSLSocketFactory
val connection = URL("https://api.example.com/data")
.openConnection() as HttpsURLConnection
connection.sslSocketFactory = TrustPinSSLSocketFactory()Manual Certificate Verification
Verify certificates programmatically:
import cloud.trustpin.kotlin.sdk.TrustPin
import cloud.trustpin.kotlin.sdk.TrustPinError
try {
TrustPin.verify(
domain = "api.example.com",
certificate = pemCertificateString
)
println("Certificate is valid and pinned")
} catch (error: TrustPinError.PinsMismatch) {
println("Certificate doesn't match configured pins")
} catch (error: TrustPinError.DomainNotRegistered) {
println("Domain not configured for pinning")
} catch (error: TrustPinError.AllPinsExpired) {
println("All pins have expired for this domain")
} catch (error: TrustPinError) {
println("Verification error: ${error.message}")
}Configuration
Pinning Modes
Strict Mode
Rejects connections to unregistered domains:
TrustPin.setup(
organizationId = "your-org-id",
projectId = "your-project-id",
publicKey = "your-base64-public-key",
mode = TrustPinMode.STRICT // Recommended for production
)Permissive Mode
Allows unregistered domains to bypass pinning:
TrustPin.setup(
organizationId = "your-org-id",
projectId = "your-project-id",
publicKey = "your-base64-public-key",
mode = TrustPinMode.PERMISSIVE // For development/testing
)Logging
Configure logging levels:
import cloud.trustpin.kotlin.sdk.TrustPinLogLevel
// Set log level (default: NONE)
TrustPin.setLogLevel(TrustPinLogLevel.DEBUG)
// Available levels:
// TrustPinLogLevel.NONE - No logging (production)
// TrustPinLogLevel.ERROR - Errors only
// TrustPinLogLevel.INFO - Errors + informational messages
// TrustPinLogLevel.DEBUG - All messages (development)Error Handling
TrustPin provides comprehensive error types:
import cloud.trustpin.kotlin.sdk.TrustPinError
try {
TrustPin.verify(domain, certificate)
} catch (error: TrustPinError) {
when (error) {
is TrustPinError.InvalidProjectConfig -> {
// Setup or configuration issues
println("Invalid configuration")
}
is TrustPinError.PinsMismatch -> {
// Certificate doesn't match pins - SECURITY CRITICAL
println("Certificate mismatch - possible MITM attack")
}
is TrustPinError.DomainNotRegistered -> {
// Domain not configured (strict mode only)
println("Domain not registered")
}
is TrustPinError.AllPinsExpired -> {
// All pins expired for domain
println("Pins expired")
}
is TrustPinError.InvalidServerCert -> {
// Invalid certificate format
println("Invalid certificate")
}
is TrustPinError.ErrorFetchingPinningInfo -> {
// Network error fetching configuration
println("Network error")
}
is TrustPinError.ConfigurationValidationFailed -> {
// Signature validation failed
println("Signature validation failed")
}
}
}Best Practices
Setup & Initialization
- Initialize in
Application.onCreate()for app-wide coverage - Use coroutine scope for async setup
- Handle setup errors gracefully - don’t block app launch
- Set log level before setup for complete logging
Security
- Use
TrustPinMode.STRICTin production - Monitor pin validation failures
- Rotate pins before expiration
- Keep credentials secure (use BuildConfig or environment variables)
- Use HTTPS for all pinned domains
Performance
- Configuration caching is automatic (10-minute TTL)
- Reuse OkHttpClient instances
- Use
TrustPinLogLevel.NONEorERRORin production - Initialize early in app lifecycle
Development Workflow
- Start with
TrustPinMode.PERMISSIVEduring development - Test all endpoints with pinning enabled
- Validate configurations in staging
- Switch to
TrustPinMode.STRICTfor production releases - Use
TrustPinLogLevel.DEBUGfor troubleshooting
Complete Example
Application Setup
import android.app.Application
import androidx.lifecycle.ProcessLifecycleOwner
import androidx.lifecycle.lifecycleScope
import cloud.trustpin.kotlin.sdk.TrustPin
import cloud.trustpin.kotlin.sdk.TrustPinMode
import cloud.trustpin.kotlin.sdk.TrustPinLogLevel
import kotlinx.coroutines.launch
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
ProcessLifecycleOwner.get().lifecycleScope.launch {
// Set log level first
TrustPin.setLogLevel(
if (BuildConfig.DEBUG) TrustPinLogLevel.DEBUG
else TrustPinLogLevel.ERROR
)
// Initialize TrustPin
try {
TrustPin.setup(
organizationId = BuildConfig.TRUSTPIN_ORG_ID,
projectId = BuildConfig.TRUSTPIN_PROJECT_ID,
publicKey = BuildConfig.TRUSTPIN_PUBLIC_KEY,
mode = if (BuildConfig.DEBUG) {
TrustPinMode.PERMISSIVE
} else {
TrustPinMode.STRICT
}
)
} catch (e: Exception) {
// Handle gracefully
android.util.Log.e("TrustPin", "Setup failed", e)
}
}
}
}Network Client with Retrofit
import okhttp3.OkHttpClient
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import cloud.trustpin.kotlin.okhttp.TrustPinOkHttpInterceptor
object NetworkClient {
private val okHttpClient = OkHttpClient.Builder()
.addInterceptor(TrustPinOkHttpInterceptor())
.build()
val retrofit: Retrofit = Retrofit.Builder()
.baseUrl("https://api.example.com/")
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create())
.build()
}
// Usage
interface ApiService {
@GET("data")
suspend fun getData(): Response<Data>
}
val apiService = NetworkClient.retrofit.create(ApiService::class.java)Troubleshooting
Setup Fails with InvalidProjectConfig
- Verify credentials in TrustPin Dashboard
- Check for whitespace or special characters
- Ensure public key is properly base64-encoded
- Confirm
Applicationclass is registered in manifest
Certificate Verification Fails
- Confirm domain is registered in dashboard
- Verify certificate format (must be PEM-encoded)
- Check pin expiration dates
- Test with
TrustPinMode.PERMISSIVEfirst
Network Requests Fail
- Ensure
INTERNETpermission in manifest - Verify TrustPin is initialized before network requests
- Check for ProGuard/R8 obfuscation issues
- Enable debug logging to see detailed errors
OkHttp Integration Issues
- Ensure interceptor is added before other interceptors
- Verify OkHttp version compatibility (3.x or 4.x)
- Check that TrustPin setup completed successfully
- Test with a simple request first
ProGuard/R8 Configuration
If using code obfuscation, add these rules to proguard-rules.pro:
# TrustPin SDK
-keep class cloud.trustpin.** { *; }
-keepclassmembers class cloud.trustpin.** { *; }
# OkHttp (if not already included)
-dontwarn okhttp3.**
-keep class okhttp3.** { *; }API Reference
Core Classes
TrustPin- Main SDK interface for setup and verificationTrustPinMode- Pinning modes (STRICT,PERMISSIVE)TrustPinOkHttpInterceptor- OkHttp interceptorTrustPinSSLSocketFactory- SSL Socket FactoryTrustPinError- Error typesTrustPinLogLevel- Logging configuration
Key Methods
// Setup
suspend fun setup(
organizationId: String,
projectId: String,
publicKey: String,
mode: TrustPinMode = TrustPinMode.STRICT
)
// Manual verification
suspend fun verify(domain: String, certificate: String)
// Logging
fun setLogLevel(level: TrustPinLogLevel)Production Deployment
Production Configuration
1. Set Production Mode
import cloud.trustpin.kotlin.sdk.TrustPin
import cloud.trustpin.kotlin.sdk.TrustPinMode
import cloud.trustpin.kotlin.sdk.TrustPinLogLevel
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
lifecycleScope.launch {
// Production configuration
TrustPin.setLogLevel(TrustPinLogLevel.ERROR)
TrustPin.setup(
organizationId = BuildConfig.TRUSTPIN_ORG_ID,
projectId = BuildConfig.TRUSTPIN_PROJECT_ID,
publicKey = BuildConfig.TRUSTPIN_PUBLIC_KEY,
mode = TrustPinMode.STRICT // Always strict in production
)
}
}
}2. Build Configuration
Add credentials to build.gradle.kts:
android {
defaultConfig {
// ...
buildConfigField("String", "TRUSTPIN_ORG_ID", "\"${System.getenv("TRUSTPIN_ORG_ID")}\"")
buildConfigField("String", "TRUSTPIN_PROJECT_ID", "\"${System.getenv("TRUSTPIN_PROJECT_ID")}\"")
buildConfigField("String", "TRUSTPIN_PUBLIC_KEY", "\"${System.getenv("TRUSTPIN_PUBLIC_KEY")}\"")
}
buildTypes {
release {
isMinifyEnabled = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
}3. ProGuard/R8 Rules
Add to proguard-rules.pro:
# TrustPin SDK
-keep class cloud.trustpin.** { *; }
-keepclassmembers class cloud.trustpin.** { *; }
# Prevent stripping of TrustPin error types
-keep class cloud.trustpin.kotlin.sdk.TrustPinError { *; }
-keep class cloud.trustpin.kotlin.sdk.TrustPinError$* { *; }4. Google Play Submission
Before publishing to Google Play:
- Test on multiple devices and Android versions
- Verify ProGuard/R8 doesn’t break TrustPin
- Test with internal testing track first
- Update Data Safety section in Play Console
- Include attribution in app description
AndroidManifest.xml
Ensure internet permission is declared:
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:name=".MyApplication"
...>
</application>
</manifest>Resources
- Repository: github.com/trustpin-cloud/TrustPin-Kotlin
- API Docs: trustpin-cloud.github.io/TrustPin-Kotlin
- Dashboard: app.trustpin.cloud
- Support: support@trustpin.cloud