Security Implementation
Audience: End users and non-technical stakeholders Last Updated: 2026-04-05 Version: 2.0.0
Overview
Llamafin takes a multi-layered approach to security, protecting your authentication credentials, personal data, and communications at every level. This document explains how the application handles authentication, session management, encryption, and network security in plain language -- without exposing implementation details that could compromise security.
Key Concepts
1. Route Protection
Every protected screen in Llamafin is guarded by an authentication gate. When you navigate to a page that requires login:
- The app checks whether you have a valid, restored session
- If your session is valid, you proceed immediately
- If you are not logged in, you are redirected to the login screen
- Your intended destination is remembered so you return there after logging in
The authentication check waits for the app to fully restore your session from storage before making a decision. This prevents a brief "flash" of the login screen on startup when you are already authenticated.
2. Authentication Methods
Llamafin supports two authentication methods, both with identical security:
| Method | Description |
|---|---|
| Standard Login | Username and password authenticated against your Jellyfin server |
| Quick Connect | Enter a short code displayed on your Jellyfin server's Quick Connect screen -- no password needed |
Both methods result in the same type of session token, stored and managed identically.
3. Session Tokens
When you authenticate successfully, Llamafin receives an access token from your Jellyfin server. This token:
- Is stored in the app's persistent storage on your device
- Is attached to every API request automatically
- Is used to identify you to the Jellyfin server
- Remains valid until the Jellyfin server invalidates it
You do not need to manually manage tokens -- they are handled transparently.
4. Session Restoration
When you reopen Llamafin:
- The app reads your stored session from persistent storage
- It validates that the session data is present and not expired
- Your identity is restored, including your user profile and server connection
- The app verifies your server is still reachable before granting full access
If restoration fails (e.g., the server is no longer available or the session was revoked), you are returned to the login screen.
5. Session Keep-Alive
While you are actively using Llamafin, the app periodically checks that your session is still valid:
- A health check runs every 5 minutes when you are online
- It verifies your account is still active on the Jellyfin server
- If the server reports your session is invalid, you are automatically logged out and returned to the login screen
- If the check fails due to network issues, it silently passes -- the next user action will detect the problem
6. Automatic Session Termination
Your session is automatically terminated and you are logged out when:
- The Jellyfin server returns a "401 Unauthorized" or "403 Forbidden" response (indicating your token is no longer valid)
- You manually sign out from the app
- The server you are connected to is removed from your configuration
When this happens:
- Your authentication token is deleted from storage
- Your user identity is cleared
- Your playback queue is cleared
- You are redirected to the login screen
7. Device Identity
Each Llamafin installation has a unique device identity that includes:
- A unique device ID (generated on first launch)
- A cryptographic key pair (for peer-to-peer communication)
- Device model information
This identity is used to:
- Identify your device to the Jellyfin server (visible in the server's session list)
- Establish encrypted connections with other Llamafin devices on your network
- Distinguish between multiple installations of the app
Your device identity persists across sign-outs and is only reset if you clear all app data or reinstall.
8. Peer-to-Peer Encryption
When Llamafin devices communicate directly with each other on your local network (for remote control and remote device control), all messages are encrypted end-to-end:
- Devices exchange public keys to establish a shared secret
- Each message is encrypted with AES-256-GCM (the same encryption standard used by governments and financial institutions)
- A unique initialisation vector is used for every message
- Keys are derived using HKDF with SHA-256 for additional security
This means that even on an untrusted network, other devices on your network cannot read or modify the commands exchanged between your Llamafin devices.
9. Password Handling
Llamafin does not store or hash your password. Your credentials are:
- Sent directly to your Jellyfin server during authentication
- Handled by the Jellyfin server's own authentication system
- Never cached, logged, or persisted by Llamafin
After authentication, only the access token is stored -- not your password.
10. Network Security
| Aspect | How Llamafin Handles It |
|---|---|
| Connection Protocol | Supports both HTTP and HTTPS connections to your Jellyfin server |
| Certificate Validation | Uses standard browser/OS certificate validation |
| Data in Transit | Encrypted when using HTTPS; unencrypted when using HTTP |
| Local Network | P2P communication is encrypted regardless of network type |
Recommendation: For connections over the internet, always configure your Jellyfin server with HTTPS to protect your credentials and data in transit.
Configuration
Server Configuration
When adding or configuring a Jellyfin server:
| Setting | Description |
|---|---|
| Server URL | The address of your Jellyfin server (e.g., https://my-server.example.com or http://192.168.1.100:8096) |
| Protocol | HTTPS is recommended for internet-facing servers; HTTP is acceptable for local networks |
| Player Name | The name that appears in Jellyfin's active sessions list (configurable in Advanced Settings) |
Security-Related Settings
| Setting | Location | Description |
|---|---|---|
| Player Name | Settings > Advanced | Identifies your device to the Jellyfin server |
| Keep Screen On | Settings > Appearance > Player | Prevents device sleep during playback (uses native APIs) |
| Haptics | Settings > Advanced | Enable/disable haptic feedback (uses native device hardware) |
Session Management
Llamafin does not expose direct session management controls (like "revoke all tokens") because session validity is managed by the Jellyfin server. To invalidate your session:
- From Llamafin: Sign out from the app
- From Jellyfin: Revoke the session from the Jellyfin server's dashboard
How It Works
Authentication Flow
1. You enter credentials or Quick Connect code
↓
2. App verifies device identity is ready (device info + cryptographic keys loaded)
↓
3. Credentials sent to Jellyfin server
↓
4. Server validates and returns access token
↓
5. Token stored securely on device
↓
6. User identity saved (including anonymized hash for P2P)
↓
7. Settings and library data loaded
↓
8. You are navigated to the app
Request Security Flow
Every API request to your Jellyfin server follows this path:
1. App constructs API request with relative URL
↓
2. Server URL interceptor adds your server's base URL
↓
3. Server URL interceptor sets device identity header
↓
4. Auth interceptor appends your access token to the header
↓
5. Request sent to Jellyfin server over HTTP or HTTPS
↓
6. Response received
↓
7. If 401/403: session terminated, you are logged out
↓
8. If 5xx error: automatic retry (up to 3 times with backoff)
↓
9. If error persists: user notified with toast message
Session Restoration Flow
1. App starts
↓
2. Stored session read from device storage
↓
3. Session validated (token present, not expired)
↓
4. User identity and anonymized hash restored
↓
5. Server connection verified
↓
6. If valid: app proceeds to main interface
↓
7. If invalid: app redirects to login screen
Peer-to-Peer Security Flow
1. Device discovers other Llamafin devices on local network
↓
2. Devices exchange public keys
↓
3. Each device computes a shared secret (ECDH key agreement)
↓
4. Shared secret strengthened via HKDF key derivation
↓
5. Messages encrypted with AES-256-GCM + unique IV
↓
6. Encrypted messages sent over local network
↓
7. Receiving device decrypts with same shared secret
↓
8. On disconnect: shared secret discarded
Integration with Other Features
| Feature | Security Integration | Description |
|---|---|---|
| Authentication | Token storage, session rehydration | Core security foundation for all features |
| Downloads | Authenticated downloads | Download requests carry the same authentication token |
| Library | Authenticated browsing | Library data fetched with authenticated API calls |
| Player | Authenticated playback | Playback reporting requires valid session |
| Connect P2P | ECDH + AES-256-GCM encryption | All P2P messages encrypted end-to-end |
| Remote Control | Session-based targeting | Remote playback targets identified by session identity |
| Settings | Server configuration | Server URLs and credentials managed securely |
| Network | Online/offline awareness | Session checks gated by network status |
Error Handling & Reliability
Session Expiry Detection
| Method | How It Works |
|---|---|
| Server rejection | When Jellyfin returns 401/403, Llamafin immediately terminates the session |
| Keep-alive check | Periodic health checks detect expired sessions proactively (though failure handling is currently limited) |
| Rehydration failure | On app restart, expired or missing sessions fail restoration, redirecting to login |
Network Error Recovery
| Scenario | Recovery |
|---|---|
| Temporary server error (5xx) | Automatic retry with exponential backoff (100ms, 200ms, 400ms) |
| Network disconnection | Requests paused; restored when network returns |
| Server URL change | All subsequent requests use the new server URL |
| SSL certificate error | Browser/OS handles certificate validation; invalid certificates blocked |
Authentication Error Handling
| Error | User Experience |
|---|---|
| Invalid credentials | Error message displayed; you can retry |
| Server unreachable | Network error message displayed; retry option available |
| Quick Connect expired | Code is no longer valid; generate a new code |
| Session expired | Automatic logout with notification; return to login screen |
Technical Specifications
| Specification | Value | Description |
|---|---|---|
| Authentication Methods | 2 | Standard login + Quick Connect |
| Token Format | Jellyfin access token | Server-generated opaque string |
| Token Storage | Ionic Storage | IndexedDB (web), SQLite (Android), WKWebView (iOS) |
| Token Attachment | HTTP header | X-Emby-Authorization with token suffix |
| Session Keep-Alive | Every 5 minutes | Health check via GET /Users/Me |
| User ID Hashing | SHA-256 | One-way hash for P2P identification |
| P2P Key Exchange | ECDH | Elliptic Curve Diffie-Hellman |
| P2P Message Encryption | AES-256-GCM | Industry-standard symmetric encryption |
| Key Derivation | HKDF-SHA-256 | Key strengthening with info string |
| IV Generation | 96-bit random | Cryptographically secure random IV per message |
| HTTP Retries | 3 attempts | Exponential backoff: 100ms, 200ms, 400ms |
| Retry Scope | 5xx + network only | 4xx errors (including auth) not retried |
| Route Guards | 1 | AuthGuard with session rehydration awareness |
| HTTP Interceptors | 6 | Server URL, Error, Auth, Retry, Timestamp, Unauthorised |
Known Limitations
Token Management
- No automatic token refresh: Llamafin relies on the Jellyfin server's token expiration policy. When a token expires, you are logged out on the next API call that receives a 401 response.
- No client-side timeout: Session validity is determined entirely by the server's response, not by elapsed time.
Network Security
- No certificate pinning: The app accepts any TLS certificate that the browser/OS validates. On untrusted networks, a sophisticated attacker with a forged certificate could potentially intercept traffic.
- No HTTPS enforcement: The app allows connections to servers over plain HTTP. For local networks, this is generally acceptable. For internet connections, HTTPS is strongly recommended.
Storage Security
- Tokens not encrypted at rest: Access tokens are stored in the app's database without additional encryption. On mobile devices, this is protected by the OS-level device encryption. On web browsers, tokens are accessible to anyone with access to the browser's storage.
Related Documentation
- Authentication & Security -- Login flow, Quick Connect, session management
- Llamafin Connect (P2P) -- Peer-to-peer encryption details
- State Management -- How session state is managed
- Offline Support -- Network security in offline mode