Mobile Permissions and Secure Storage
Mobile permissions control access to protected capabilities; secure storage protects sensitive application material. Design both as lifecycle concerns. Permission can be denied or revoked, and a stored token can expire, become unavailable, or need revocation.
Ask for the minimum capability when the user needs the feature, provide a useful denied path, and store secrets through appropriate operating-system facilities. A permission prompt and an encrypted file solve different problems.
TL;DR
- Request capabilities in context and offer a graceful denied path.
- Recheck permission state when returning to the feature.
- Use platform-backed secret/key storage with an explicit accessibility policy.
- Separate local deletion, server revocation and session expiry.
- Test lock state, process death, backup/restore and account changes on real target devices.
Quick Example
This complete Python model demonstrates fictional permission-state decisions only. It requests no permission and stores no token. The real platform callback and lifecycle behavior must be tested separately.
These state names are a teaching abstraction, not identical Android and iOS enum values. Map actual platform results deliberately; never convert an unfamiliar result into granted access.
Core Concepts
Permission lifecycle
Android’s runtime-permission guidance asks applications to check state, explain requests where appropriate and handle grant or denial. Details vary by capability and OS version. Avoid repeatedly prompting after refusal or making unrelated features depend on unnecessary access. Android permissions
Secret and key storage
Apple Keychain services stores small secrets in an encrypted keychain. Android Keystore stores cryptographic keys and restricts their use; it is not an arbitrary token-string database. On Android, protected application data can use an appropriately managed key, with the exact storage design and library reviewed for the platform. Apple Keychain · Android Keystore
Access and revocation
Storage accessibility, device/user authentication, server session state and token expiry are separate controls. Local encryption does not make a token valid forever or prevent an authorized running app from using it. Define what logout, account removal and device loss require.
Build a capability and storage matrix
Inventory each protected capability and each secret. For capabilities, record why the feature needs access and the alternative when it is unavailable. For secrets, record purpose, scope, expiry, accessibility, backup behavior and revocation route.
Choose storage accessibility from the actual use. Background synchronization and an interactive unlocked-device action may need different policies. Review whether data should migrate through backup or remain tied to the device, then test those behaviors rather than assuming a framework default.
Keep secrets out of logs, crash reports, clipboard, analytics payloads and screenshots. Redacting a settings screen does not prevent a debug logger from retaining the same token. Inspect the full flow from authentication response through storage, refresh, use and deletion.
Design denial and token recovery paths
When a permission is denied, explain the feature consequence and offer an appropriate alternative. Avoid punitive loops that prevent the user from leaving the prompt flow. If settings guidance is appropriate, return to the feature and recheck the actual state rather than assuming the user changed it.
Handle storage failure as a real state: absent item, key invalidation, failed user authentication, changed device lock policy or corrupted data. The safe response may be reauthentication and cleanup according to the application’s contract. Do not silently switch to plaintext storage when the protected path fails.
For refresh tokens, serialize or coordinate refresh where simultaneous callers could rotate the same credential. Preserve the distinction between an expired access token, a revoked refresh token and an unavailable network. An offline state should not repeatedly destroy valid local work, and a server denial should not trigger an infinite retry loop.
Define logout carefully. Clearing a local value does not necessarily revoke a remote session, and remote revocation may not be reachable while offline. Explain the remaining state and retry/reconciliation policy without claiming more than the system can guarantee.
Verify on the devices you support
Exercise first use, prior denial, limited access, revocation while backgrounded, process death, locked-device access, account switching, reinstall and approved backup/restore scenarios. Use dedicated test accounts and non-sensitive fixtures. Do not collect real user secrets to demonstrate a lifecycle issue.
Check the selected OS version, framework and storage library. Hardware backing and available authentication options differ across devices and key configuration; do not promise that every stored item is protected by identical hardware.
Retain allowed and denied outcomes, effective settings and the application response. The Python decision table does not request native permissions, exercise Keychain/Keystore, prove token confidentiality or validate server revocation.
Best Practices
Minimize retained authority
Store only necessary secret material with the narrowest practical scope and lifetime. Keep the server’s revocation and authorization rules part of the design.
Treat unknown state conservatively
Handle unexpected permission/storage results explicitly and record safe diagnostics without secret values. A fallback should preserve the intended protection.
Review the complete lifecycle
Test account changes, background work and recovery alongside the ordinary login. Many secret-handling defects occur after the initial successful storage call.
Common Mistakes
Bad: Treating a runtime permission as permission to expose all related user data.
Correct: Limit the feature to the actual granted scope and the user’s intended action.
Bad: Saving tokens in ordinary preferences after secure storage fails.
Correct: Handle the failure and reauthentication path without weakening protection.
Bad: Calling local token deletion complete server logout.
Correct: Implement and verify the remote session/revocation contract and offline limitations.
FAQ
Does Android Keystore directly store arbitrary token strings?
It manages cryptographic keys. Design secret data storage using the appropriate platform/library facilities and review the full lifecycle.
Should denial break the whole application?
Usually only the capability-dependent action should be affected; choose useful alternatives according to the product’s requirements.
Were native storage APIs tested here?
No. Only the fictional permission decision model ran. Device permission, storage and session checks remain pending.
Related Topics
- Mobile Development — Design the wider application lifecycle.
- Authentication vs Authorization — Separate identity and permission decisions.
- Offline Synchronization and Conflict Resolution — Preserve useful work across unavailable access.