Expert security decisions for iOS/tvOS: when Keychain vs UserDefaults, certificate pinning trade-offs, API key protection strategies, and secure data lifecycle management. Use when storing sensitive data, implementing authentication, or hardening app security. Trigger keywords: Keychain, security, certificate pinning, encryption, API key, token storage, secure storage, biometric, jailbreak, data protection
View on GitHubKaakati/rails-enterprise-dev
reactree-ios-dev
January 25, 2026
Select agents to install to:
npx add-skill https://github.com/Kaakati/rails-enterprise-dev/blob/main/plugins/reactree-ios-dev/skills/security-best-practices/SKILL.md -a claude-code --skill security-best-practicesInstallation paths:
.claude/skills/security-best-practices/# Security Best Practices — Expert Decisions
Expert decision frameworks for iOS security choices. Claude knows Keychain APIs — this skill provides judgment calls for when security measures add value and implementation trade-offs.
---
## Decision Trees
### Storage Selection
```
What type of data?
├─ Credentials (passwords, tokens, secrets)
│ └─ Keychain (always)
│ kSecAttrAccessibleAfterFirstUnlock typical
│
├─ User preferences
│ └─ Is it sensitive? (e.g., PIN enabled)
│ ├─ YES → Keychain
│ └─ NO → UserDefaults is fine
│
├─ Large sensitive files
│ └─ File system + Data Protection
│ .completeFileProtection option
│
└─ Non-sensitive app state
└─ UserDefaults or files
No special protection needed
```
### Certificate Pinning Decision
```
What's your threat model?
├─ Consumer app, standard security
│ └─ Trust system CA validation
│ ATS (App Transport Security) is sufficient
│
├─ Financial/healthcare/enterprise
│ └─ Pin certificates
│ But plan for rotation!
│
├─ High-value target (banking, crypto)
│ └─ Pin public key (not certificate)
│ Survives cert renewal
│
└─ Internal enterprise app
└─ May need custom CA trust
ServerTrustManager with custom evaluator
```
**The trap**: Pinning without rotation plan. When cert expires, app stops working.
### API Key Protection Strategy
```
Who controls the server?
├─ You control backend
│ └─ Don't embed API keys in app
│ Authenticate users, server makes API calls
│
├─ Third-party API, user-specific
│ └─ OAuth flow
│ User authenticates, gets their own token
│
└─ Third-party API, app-level key
└─ Is key truly needed client-side?
├─ NO → Proxy through your backend
└─ YES → Obfuscate + attestation
Accept risk of extraction
```
### Keychain Access Level
```
When does data need to be accessible?
├─ Only when device unlocked
│ └─ kSecAttrAccessibleWhenUnlocked
│ Most secure for user-facing data
│
├─ Background refresh needed
│ └─ kSecAttrAcce