Files
Kordant/android/docs/security-practices.md

9.3 KiB

Security Practices — Kordant Android

Last updated: 2026-06-01
Package: com.kordant.android
Purpose: Document security practices for Play Store Data Safety form and user transparency


1. Encryption in Transit

TLS Configuration

All network communication between the Kordant Android app and backend servers is encrypted using TLS 1.2 or higher.

Implementation:

  • network_security_config.xml enforces cleartextTrafficPermitted="false" for all domains
  • Debug builds allow cleartext for local development via <debug-overrides>
  • API base URL uses HTTPS (https://api.kordant.com)

Certificate Pinning

The Android app implements SHA-256 certificate pinning for production and staging domains:

Domain Pin 1 (Primary) Pin 2 (Backup)
api.kordant.com Primary SHA-256 hash Backup SHA-256 hash
staging.api.kordant.com Staging SHA-256 hash Staging backup SHA-256 hash

File: res/xml/network_security_config.xml

Rotation: Pins include a backup for graceful certificate rotation. Update pins before certificate expiry. Expiration set to 2027-06-01.

TLS Enforcement Points

Component Enforcement
OkHttpClient HTTPS URLs only (BuildConfig.API_BASE_URL)
AUTH interceptor All auth requests via HTTPS
API service Retrofit base URL uses HTTPS
Image loading Coil via OkHttp with TLS

2. Encryption at Rest

EncryptedSharedPreferences

All sensitive data is stored in EncryptedSharedPreferences using:

Property Value
Key encryption AES256-SIV (deterministic, allows key lookup)
Value encryption AES256-GCM (authenticated encryption)
Master key Android Keystore (MasterKey.Builder with KeyScheme.AES256_GCM)
Library androidx.security:security-crypto

Data Stored Encrypted

Data Key File
Access token access_token SecureStorageManager.kt
Refresh token refresh_token SecureStorageManager.kt
User profile (PII) user_profile_json SecureStorageManager.kt
FCM device token fcm_device_token SecureStorageManager.kt
Biometric preference biometric_enabled SecureStorageManager.kt

Non-Sensitive Data (Unencrypted)

User preferences that do not contain PII are stored in Android's standard Preferences DataStore:

  • Theme selection (system/light/dark)
  • Language/locale
  • Notification preferences (alerts/marketing/system toggles)
  • Onboarding completion status
  • App version for migration tracking
  • Background sync toggle
  • Last sync timestamp

Spam Database (Hashed)

Phone numbers in the local SQLite spam database are SHA-256 hashed before storage.

Field Storage
number_hash SHA-256 hash of normalized phone number
pattern Wildcard pattern (e.g., +1-800-*)
action block, flag, allow
category scam, telemarketer, robocall, spam
spam_score 0-100 confidence score

Raw phone numbers are never written to disk in the spam database.


3. Secure Deletion

Overwrite-Then-Remove

The app implements secure deletion for sensitive keys to mitigate forensic recovery:

secureOverwriteAndRemove(key) {
    for (i in 0 until 3) {
        overwrite with random data → apply()
    }
    remove(key) → apply()
}

Deletion Methods

Method What It Clears Use Case
clearAllAuthData() Access token, refresh token, user profile Logout
clearAllData() All encrypted preferences including biometric Account deletion (GDPR)
clearAll() (DataStore) All user preferences Reset to defaults
clearAll() (CacheManager) API response cache Logout / cache clear
clearAll() (SpamDatabase) Spam numbers + call logs Full resync / account deletion

4. Root Detection & Anti-Tampering

Detection Methods

Check Detection Target
SU binary paths /system/bin/su, /system/xbin/su, /data/local/su, etc.
Busybox paths /system/xbin/busybox, /data/local/bin/busybox
Dangerous props ro.debuggable=1, ro.secure=0
Build tags test-keys, dev-keys
Magisk indicators /sbin/.magisk, /data/adb/magisk, Magisk packages
Root management packages Magisk, SuperSU, KingRoot, LuckyPatcher, etc.
SU command execution su -c id — checks if uid=0
App signature verification SHA-256 hash of signing certificate
Debugger detection android.os.Debug.isDebuggerConnected()
ADB over network service.adb.tcp.port system property
Emulator detection Known properties, model, manufacturer, fingerprint
Installer source verification Play Store, Amazon App Store, Samsung Galaxy Store

Response to Detection

Detection Behavior
Root detected Features degraded; reported to backend and Crashlytics
Tampering detected Biometric and payment features disabled
Emulator detected Features may be restricted
Untrusted install Warning logged, security restrictions applied

5. Log Sanitization

All network logs are sanitized before writing to prevent PII exposure:

Pattern Redacted To
Bearer <token> Bearer [REDACTED]
\b\d{10,15}\b (phone numbers) [PHONE_REDACTED]
Email addresses [EMAIL_REDACTED]
Refresh tokens in bodies "refreshToken":"[REDACTED]"
Access tokens in bodies "accessToken":"[REDACTED]"
ID tokens in bodies "idToken":"[REDACTED]"
Passwords in bodies "password":"[REDACTED]"

Implementation: NetworkModule.ktprovideLoggingInterceptor()

Log levels:

  • Debug builds: Full headers + sanitized bodies
  • Release builds: Headers only (no body logging)

6. Token Refresh Security

Automatic Silent Refresh

Property Value
Trigger HTTP 401 Unauthorized
Mechanism AuthInterceptor.intercept()refreshAccessToken()
Concurrency Synchronized via refreshLock to prevent race conditions
Fallback Clears tokens on refresh failure → user re-authenticates

Token Storage

Token Storage Encryption
Access token EncryptedSharedPreferences AES256-GCM
Refresh token EncryptedSharedPreferences AES256-GCM

7. Network Security

OkHttp Configuration

Property Value
Connect timeout 30 seconds
Read timeout 30 seconds
Write timeout 30 seconds
TLS enforcement Platform default (TLS 1.2+)
Certificate pinning SHA-256 pins for api.kordant.com

Retrofit API Configuration

Property Value
Base URL https://api.kordant.com/ (production)
Converter Kotlinx Serialization JSON
Headers X-Request-ID, X-Client-Version, X-Client-Platform

8. Biometric Authentication

Property Value
Library androidx.biometric:biometric
Storage Preference flag in EncryptedSharedPreferences
Root check Biometric disabled on rooted/tampered devices
Fallback Device credentials (PIN/pattern/password)

9. Data Collection Compliance

Data Minimization

The app collects only the data necessary for its core functionality:

Feature Minimum Data Required
Authentication Email, password (or Google account ID), name
Call Screening Incoming phone number (temporary, hashed for storage)
VoicePrint Voice recording samples
DarkWatch Watchlist items (email, phone, name to monitor)
Analytics Device info, app version (no personal identifiers)
Crash reporting Crash stack trace, device model, OS version
Data Type Consent Mechanism
Account creation Explicit signup form
Google Sign-In OAuth consent screen
Voice recordings RECORD_AUDIO permission + in-app rationale
Call screening READ_PHONE_STATE permission + in-app rationale
Notifications POST_NOTIFICATIONS (Android 13+) + in-app toggles
Crash reporting Crashlytics opt-out (configured in manifest)
Marketing communications Explicit opt-in via notification settings

10. Independent Security Review

Status: ⚠️ Pending

An independent third-party security audit is planned before the production launch. The audit will cover:

  • Penetration testing of the mobile application
  • API security assessment
  • Cryptographic implementation review
  • Privacy compliance review

11. Compliance Standards

Standard Status Notes
GDPR Compliant Data deletion, portability, consent, breach notification
CCPA Compliant Right to know, delete, opt-out, non-discrimination
COPPA Compliant No children under 13 data collection
Play Store Data Safety Complete All data types accurately declared
Android Target API 36 Compliant No deprecated API usage
TLS 1.2/1.3 Enforced Cleartext traffic blocked
OWASP MASVS ⚠️ Partial Security audit planned for full certification