# 05. Certificate Pinning & TLS Validation meta: id: ios-production-05 feature: ios-production priority: P1 depends_on: [] tags: [security, networking, production] objective: - Implement certificate pinning and TLS validation to prevent man-in-the-middle attacks on API communications deliverables: - Certificate pinning implementation in APIClient - TLS 1.3 enforcement - Certificate expiration monitoring - Fallback handling for certificate rotation steps: 1. Obtain server certificates: - Export production server certificate or public key - Include intermediate certificates if needed - Store certificate hash in app bundle 2. Implement certificate pinning: - Modify iOS/Kordant/Services/APIClient.swift - Use URLSessionDelegate with didReceiveChallenge - Compare server certificate with pinned hash - Support both certificate pinning and public key pinning 3. Configure TLS settings: - Enforce TLS 1.3 minimum - Disable weak cipher suites - Enable certificate transparency checking - Configure ATS (App Transport Security) in Info.plist 4. Add certificate rotation support: - Support multiple pinned certificates (old + new) - Grace period during rotation (30 days) - Alert when certificate nearing expiry 5. Implement fallback strategy: - If pinning fails, allow connection with additional verification - Log pinning failures for monitoring - Consider allowing override for enterprise users 6. Add tests: - Test with correct certificate → connection succeeds - Test with wrong certificate → connection fails - Test certificate rotation → seamless transition tests: - Unit: Test pinning with mock certificates - Integration: Test against staging with pinned cert - Security: Attempt MITM with Charles Proxy → blocked acceptance_criteria: - Certificate pinning active on all API requests - TLS 1.3 enforced for all connections - MITM attacks blocked (tested with proxy tools) - Certificate rotation supported with grace period - Pinning failures logged for monitoring - ATS configured in Info.plist - Unit tests covering pinning success and failure - No hardcoded certificates in source code (use hashes) validation: - Run app with correct cert → API calls succeed - Run app with Charles Proxy MITM → API calls fail - Check logs → pinning verification logged - Inspect Info.plist → ATS settings correct notes: - Use public key pinning (more stable than full certificate) - Include backup pin for certificate rotation - TrustKit is a popular library for iOS certificate pinning - Certificate expiry alerts prevent unexpected outages