Keychain Secure Storage
Relevant source files
The following files were used as context for generating this wiki page:
Keychain Secure Storage in the putio-ios project provides a centralized, encrypted mechanism for persisting sensitive user credentials, specifically OAuth access tokens. By leveraging the iOS Keychain via the KeychainAccess library, the application ensures that user sessions remain secure across app restarts and protected from unauthorized access by other applications.
The system is primary managed by the PutioKeychain helper class, which acts as a wrapper around the lower-level Keychain APIs. This module is critical for the application's authentication lifecycle, including initial sign-in, session persistence, and secure logout procedures.
Architecture and Components
The Keychain storage architecture is built around a singleton pattern to ensure consistent access to credentials throughout the app's lifecycle.
PutioKeychain Class
The PutioKeychain class is the core component of this module. It initializes a Keychain instance using a specific serviceKey (defined by APP_KEYCHAIN_SERVICE) to namespace the stored data. Sources: Putio/Common/Helpers/Keychain.swift:5-15
| Component | Description |
|---|---|
sharedInstance | Static singleton for global access. |
serviceKey | The unique identifier for the Keychain service (e.g., the app's bundle ID or a specific service name). |
tokenKey | Hardcoded string "access_token" used as the key for the OAuth token. |
keychain | The underlying KeychainAccess instance. |
Sources: Putio/Common/Helpers/Keychain.swift:6-12
Class Diagram
The following diagram illustrates the structure of the PutioKeychain helper and its primary methods.
The diagram shows the simplified structure of the PutioKeychain class used for managing session tokens. Sources: Putio/Common/Helpers/Keychain.swift:5-28
Authentication Data Flow
The Keychain is integrated directly into the AppDelegate to manage user sessions during application startup and state transitions.
Token Retrieval and Initialization
During application(_:didFinishLaunchingWithOptions:), the app attempts to authenticate the user. It queries PutioKeychain for an existing token. If found, the token is passed to the PutioSDK to authorize network requests. Sources: Putio/AppDelegate.swift:130-136, Putio/Common/API/PutioSDK.swift:11
This diagram outlines the token retrieval flow used to determine if a user should see the main interface or the login screen. Sources: Putio/AppDelegate.swift:130-138
Session Destruction (Logout)
When a user logs out, the application explicitly clears the Keychain to prevent unauthorized session reuse. The logout() function in AppDelegate coordinates the removal of the token from the Keychain and the SDK. Sources: Putio/AppDelegate.swift:226-232
Lifecycle Management Methods
The PutioKeychain class provides three primary methods for managing the lifecycle of the access token:
- getToken(): Retrieves the current string value associated with
access_token. - setToken(_ token: String): Securely writes or updates the token in the Keychain.
- clearToken(): Removes the token by setting its value to
nil.
Sources: Putio/Common/Helpers/Keychain.swift:17-27
Testing and Verification
Security and persistence changes are considered "Regression Hotspots" in the project. Developers are required to run specific validation steps when modifying Keychain logic. Sources: CLAUDE.md:63-65
Unit Testing
The PutioKeychainTests verify the integrity of the storage mechanism. A key test case, testTokenRoundTripUsesScopedServiceKey, ensures that tokens can be set, retrieved, and cleared correctly using a unique service key for isolation during tests. Sources: PutioTests/PutioKeychainTests.swift:8-16
E2E Reset Logic
In debug environments, the application supports state resetting for End-to-End (E2E) testing. This process involves calling clearToken() to ensure each test run starts from an unauthenticated state. Sources: Putio/AppDelegate.swift:80-84
Summary
Keychain Secure Storage provides the foundational security layer for user authentication in putio-ios. By encapsulating the access_token management within PutioKeychain, the project ensures that sensitive credentials are handled consistently across the AppDelegate, SDK initialization, and testing environments. Verification of this system is mandatory during any changes to auth or persistence layers.