Store both access and refresh tokens in the Keychain, not UserDefaults, and always replace the stored refresh token after a successful exchange. Keep the access token short-lived so role changes and revocations take effect quickly. On refresh, preserve the session through transient errors, and clear tokens only when the server returns a terminal invalid_grant response.
Why This Matters for Security Teams
Session tokens in iOS apps are not just a convenience layer; they are the live credential path that determines whether a user stays authenticated, gets re-authorised, or loses access after a risk event. If tokens are stored unsafely, refreshed inconsistently, or revoked too late, attackers can reuse them even after a password reset or account recovery. Current guidance suggests treating token handling as a security control, not a UI detail.
This is especially important because mobile apps often fail in ways desktop teams do not expect. Tokens can survive app reinstalls, be backed up unintentionally, or remain valid long after the user believes a session is gone. Apple Keychain is the normal secure storage choice, but storage alone does not solve lifecycle risk. Security teams should pair it with short token lifetimes, refresh token rotation, and server-side invalidation aligned to controls like NIST SP 800-53 Rev 5 Security and Privacy Controls and the broader guidance in the IOS app secrets leakage report.
In practice, many security teams encounter token theft, session persistence, or broken logout only after a leaked mobile build or compromised endpoint has already preserved the credential path.
How It Works in Practice
The correct pattern is straightforward: store access and refresh tokens in the iOS Keychain, keep access tokens short-lived, and treat refresh tokens as single-use or rotated credentials. After a successful refresh exchange, the app should overwrite the old refresh token immediately rather than keeping both values around. That matters because replay risk rises sharply when a stolen refresh token remains usable across multiple exchanges.
For mobile apps, the main design goal is to preserve the user session through normal network failures while still letting the server enforce revocation when needed. The app should retry transient refresh failures, but it should not blindly log the user out on connectivity loss. Instead, only a terminal invalid_grant response should trigger token purge and full reauthentication. That distinction prevents avoidable session drops while still respecting server-side security decisions.
- Use the Keychain for both access and refresh tokens, not UserDefaults or plaintext files.
- Rotate refresh tokens on every successful exchange and delete the prior token from storage.
- Keep access token TTL short enough that role changes and revocations take effect quickly.
- Handle transient network or server errors without clearing the session prematurely.
- Clear local tokens only after a terminal invalid_grant or equivalent hard-fail response.
This approach aligns with the token hygiene concerns documented in the State of Non-Human Identity Security and with NIST’s expectation that credentials be protected in transit, at rest, and through their full lifecycle. It also reflects the reality that secret sprawl is often a lifecycle problem, not just a storage problem, as shown in the State of Secrets Sprawl 2026.
These controls tend to break down when apps use long-lived refresh tokens across multiple device states because revoked or copied tokens may continue working until the next server-side validation.
Common Variations and Edge Cases
Tighter token rotation often increases implementation complexity, requiring organisations to balance session continuity against stronger replay resistance. That tradeoff becomes visible in offline-first apps, multi-device sign-in flows, and apps that support background refresh, where aggressive invalidation can frustrate users if the refresh path is not designed carefully.
There is no universal standard for every app’s refresh cadence yet, but current guidance suggests that high-risk apps should favor shorter TTLs and stronger server-side revocation checks. Some teams also layer device binding, app attestation, or additional risk checks before issuing a new refresh token, but these are compensating controls rather than substitutes for proper token rotation. If a refresh token is shared across devices, copied into logs, or exposed through debug tooling, the entire session model weakens quickly.
Another common edge case is background execution. An app may need to refresh a token while the user is inactive, but the refresh path still must respect terminal failures and update stored state atomically. Partial writes, race conditions, and concurrent refresh requests can leave an app holding stale tokens even after a successful exchange. The safest approach is a single refresh coordinator, atomic Keychain updates, and explicit handling for revoked sessions.
Practitioners should also watch for backup and migration behavior. Keychain settings, app group sharing, and device restore policies can unintentionally widen token exposure if they are not reviewed during release hardening. In complex enterprise deployments, this guidance can break down when legacy identity providers do not support refresh token rotation or when session revocation is not enforced consistently across all backend services.
Standards & Framework Alignment
This section maps relevant standards and security frameworks to the operational risks and controls described in this guidance.
OWASP Non-Human Identity Top 10, OWASP Agentic AI Top 10 and CSA MAESTRO address the attack and risk surface, while NIST AI RMF and NIST CSF 2.0 set the governance and control requirements practitioners need to meet.
| Framework | Control / Reference | Relevance |
|---|---|---|
| OWASP Non-Human Identity Top 10 | NHI-03 | Refresh token rotation reduces reuse risk after compromise. |
| OWASP Agentic AI Top 10 | Runtime credential handling mirrors dynamic authorisation needs. | |
| CSA MAESTRO | Supports secure lifecycle control for autonomous workloads and secrets. | |
| NIST AI RMF | Governance and risk controls apply to session token lifecycle decisions. | |
| NIST CSF 2.0 | PR.AC-1 | Authentication and credential management underpin session token security. |
Rotate refresh tokens on every exchange and invalidate the prior token immediately.
Related resources from NHI Mgmt Group
- How do security teams reduce authentication risk in Python without breaking user experience?
- How should security teams reduce dependence on password vaults without breaking user access?
- How should security teams protect PII in AI pipelines without breaking user workflows?
- How should security teams implement endpoint DLP without breaking user productivity?