jellytau/docs/architecture/09-security.md
Duncan Tourolle 09780103a7
Some checks failed
🏗️ Build and Test JellyTau / Run Tests (push) Failing after 12s
🏗️ Build and Test JellyTau / Build Android APK (push) Has been skipped
Traceability Validation / Check Requirement Traces (push) Failing after 1s
Split software arch desc for easier manintenance. Many fixes related to next video playing and remote playback
2026-03-01 19:47:46 +01:00

2.5 KiB

Security

Authentication Token Storage

Access tokens are not stored in the SQLite database. Instead, they are stored using platform-native secure storage:

flowchart TB
    LoginSuccess["Login Success"]
    KeyringCheck{"System Keyring<br/>Available?"}
    OSCredential["Store in OS Credential Manager<br/>- Linux: libsecret/GNOME Keyring<br/>- macOS: Keychain<br/>- Windows: Credential Manager<br/>- Android: EncryptedSharedPrefs"]
    EncryptedFallback["Encrypted File Fallback<br/>(AES-256-GCM)"]

    LoginSuccess --> KeyringCheck
    KeyringCheck -->|"Yes"| OSCredential
    KeyringCheck -->|"No"| EncryptedFallback

Key Format:

jellytau::{server_id}::{user_id}::access_token

Rationale:

  • Tokens in SQLite would be readable if the database file is accessed
  • System keyrings provide OS-level encryption and access control
  • Fallback ensures functionality on minimal systems without a keyring daemon

Secure Storage Module

Location: src-tauri/src/secure_storage/ (planned)

pub trait SecureStorage: Send + Sync {
    fn store(&self, key: &str, value: &str) -> Result<(), SecureStorageError>;
    fn retrieve(&self, key: &str) -> Result<Option<String>, SecureStorageError>;
    fn delete(&self, key: &str) -> Result<(), SecureStorageError>;
}

// Platform implementations
pub struct KeyringStorage;      // Uses keyring crate
pub struct EncryptedFileStorage; // AES-256-GCM fallback

Network Security

Aspect Implementation
Transport HTTPS required for all Jellyfin API calls
Certificate Validation System CA store (configurable for self-signed)
Token Transmission Bearer token in Authorization header only
Token Refresh Handled by Jellyfin server (long-lived tokens)

Local Data Protection

Data Type Protection
Access Tokens System keyring or encrypted file
Database (SQLite) Plaintext (metadata only, no secrets)
Downloaded Media Filesystem permissions only
Cached Thumbnails Filesystem permissions only

Security Considerations

  1. No Secrets in SQLite: The database contains only non-sensitive metadata
  2. Token Isolation: Each user/server combination has a separate token entry
  3. Logout Cleanup: Token deletion from secure storage on logout
  4. No Token Logging: Tokens are never written to logs or debug output
  5. IPC Security: Tauri's IPC uses structured commands, not arbitrary code execution