This document describes the secure token storage implementation for the Swara Studio Python API client.
The Python client now uses a multi-layered security approach for storing OAuth tokens:
- OS Keyring (Primary) - Uses system keychain/credential manager
- Encrypted File (Fallback) - AES encryption with machine-specific keys
- Plaintext File (Legacy) - Only used when other methods unavailable
| Storage Method | Security Level | Description |
|---|---|---|
| OS Keyring | High | Platform-native encryption, requires OS authentication |
| Encrypted File | Medium | AES-256 encryption with PBKDF2 key derivation |
| Plaintext File | Low | Unencrypted storage (legacy compatibility only) |
pip install requestspip install keyring cryptography PyJWTpip install secretstorage # For better Linux keyring supportfrom idtap.client import SwaraClient
# Client automatically uses secure storage
client = SwaraClient()
# Check authentication and storage info
auth_info = client.get_auth_info()
print(f"Security level: {auth_info['storage_info']['security_level']}")from idtap.secure_storage import SecureTokenStorage
from idtap.auth import login_google, load_token
# Create secure storage instance
storage = SecureTokenStorage()
# Check storage capabilities
info = storage.get_storage_info()
print(f"Storage method: {info['storage_method']}")
print(f"Security level: {info['security_level']}")
# Manual authentication
login_google(storage=storage)
# Load tokens
tokens = load_token(storage=storage)The system automatically migrates existing plaintext tokens to secure storage:
- Automatic Migration: Happens during first use of new client
- Backwards Compatibility: Old token files are automatically detected and migrated
- Safe Cleanup: Legacy files removed only after successful migration
from idtap.secure_storage import SecureTokenStorage
storage = SecureTokenStorage()
success = storage.migrate_legacy_tokens()
print(f"Migration successful: {success}")- Expiration Detection: Automatic detection of expired tokens
- Secure Deletion: Proper cleanup when clearing tokens
- Cross-Platform: Works on macOS, Windows, and Linux
- Algorithm: AES-256 in Fernet mode (symmetric encryption)
- Key Derivation: PBKDF2-HMAC-SHA256 with 100,000 iterations
- Key Material: Username + service name + machine ID
- Salt: Fixed application salt for consistency
- CSRF Protection: State parameter validation in OAuth flow
- Secure Random: Cryptographically secure token generation
- Machine Binding: Encryption keys tied to specific machine
- Primary: Keychain Services
- Fallback: Encrypted file in
~/.swara/.tokens.enc - Permissions: 0o600 (user read/write only)
- Primary: Windows Credential Manager
- Fallback: Encrypted file in
%USERPROFILE%\.swara\.tokens.enc - Permissions: User-only access
- Primary: Secret Service (GNOME Keyring, KWallet)
- Fallback: Encrypted file in
~/.swara/.tokens.enc - Permissions: 0o700 directory, 0o600 file
⚠️ WARNING: Secure storage unavailable. Install 'keyring' and 'cryptography' packages for secure token storage.
Solution: Install security dependencies
pip install keyring cryptographyProblem: Keyring not available in headless environments
Solution:
- Install
secretstorage:pip install secretstorage - Or use encrypted file fallback (automatic)
Problem: "Stored tokens are expired" message
Solution: Re-authenticate
from idtap.auth import login_google
login_google() # Will overwrite expired tokensRun the test suite to verify your installation:
cd python/
python test_secure_storage.pyfrom idtap.client import SwaraClient
client = SwaraClient(auto_login=False)
auth_info = client.get_auth_info()
print(f"Storage method: {auth_info['storage_info']['storage_method']}")
print(f"Security level: {auth_info['storage_info']['security_level']}")- Install All Dependencies: Use
keyringandcryptographyfor maximum security - Regular Updates: Keep dependencies updated for security patches
- Environment Security: Secure your development environment
- Token Rotation: Re-authenticate periodically in production environments
- Audit Logging: Monitor authentication events in production
store_tokens(tokens: Dict[str, Any]) -> bool: Store tokens securelyload_tokens() -> Optional[Dict[str, Any]]: Load stored tokensclear_tokens() -> bool: Clear all stored tokensis_token_expired(tokens: Dict[str, Any]) -> bool: Check token expirationget_storage_info() -> Dict[str, Any]: Get storage method informationmigrate_legacy_tokens() -> bool: Migrate from plaintext storage
service_name: Service identifier for keyring storageusername: Current system username
login_google(base_url, storage, host, port): Authenticate with Google OAuthload_token(storage, token_path): Load tokens with backwards compatibilityclear_token(storage, token_path): Clear tokens from all storage locations
When contributing to the secure storage implementation:
- Security Review: All changes require security review
- Backwards Compatibility: Maintain compatibility with existing token storage
- Cross-Platform Testing: Test on macOS, Windows, and Linux
- Documentation: Update security documentation for any changes
If you discover security vulnerabilities in the token storage implementation, please report them responsibly:
- Do not create public GitHub issues for security vulnerabilities
- Contact the development team directly
- Provide detailed information about the vulnerability
- Allow time for fixes before public disclosure