# Token Persistence Guide ## Overview The Kosmi bridge now caches JWT authentication tokens to avoid repeated browser automation on every startup. The token is stored in a local directory that persists across Docker container rebuilds and restarts. ## How It Works ### Token Cache Location The token cache is stored in a file called `kosmi_token_cache.json` in the following locations: - **Docker (Production)**: `./data/kosmi_token_cache.json` (mounted from your host machine) - **Local Development**: `~/.matterbridge/kosmi_token_cache.json` ### Token Cache Structure The cache file contains: ```json { "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "email": "your-email@example.com", "expires_at": "2026-11-02T15:56:23Z", "saved_at": "2025-11-02T15:56:23Z" } ``` ### Token Lifecycle 1. **On Startup**: The bridge checks for a cached token - If found and valid, it uses the cached token (no browser automation needed) - If expired or expiring within 7 days, it performs fresh authentication - If not found, it performs fresh authentication 2. **Token Expiry**: Kosmi JWT tokens expire after 1 year - The bridge automatically refreshes tokens that expire within 7 days - You'll see a log message indicating how long until the token expires 3. **Token Storage**: After successful authentication, the token is saved to the cache file - File permissions are set to `0600` (read/write for owner only) - The cache directory is created automatically if it doesn't exist ## Docker Configuration ### Volume Mount The `docker-compose.yml` includes a volume mount for persistent storage: ```yaml volumes: - ./data:/app/data:z ``` This mounts the `./data` directory from your host machine into the container at `/app/data`. ### Environment Variable The container sets the `MATTERBRIDGE_DATA_DIR` environment variable: ```yaml environment: - MATTERBRIDGE_DATA_DIR=/app/data ``` This tells the bridge where to store persistent data like the token cache. ## Usage ### First Run On the first run with email/password configured: 1. The bridge will launch a headless browser 2. Authenticate with Kosmi using your credentials 3. Extract and cache the JWT token 4. Save it to `./data/kosmi_token_cache.json` You'll see logs like: ``` level=info msg="No cached token found, performing authentication..." level=info msg="Starting browser automation for authentication..." level=info msg="💾 Token cached (expires in 8760h)" ``` ### Subsequent Runs On subsequent runs (container restarts, rebuilds, etc.): 1. The bridge checks the cached token 2. If valid, uses it immediately (no browser needed) 3. Connects to Kosmi in seconds You'll see logs like: ``` level=info msg="✅ Using cached token (expires in 8736h)" ``` ### Token Refresh When the token is close to expiring (within 7 days): 1. The bridge automatically performs fresh authentication 2. Updates the cached token 3. Continues normal operation You'll see logs like: ``` level=info msg="Cached token expires soon (2025-11-09T15:56:23Z), will refresh" level=info msg="Starting browser automation for authentication..." level=info msg="💾 Token cached (expires in 8760h)" ``` ## File Structure After running with authentication, your directory structure will look like: ``` irc-kosmi-relay/ ├── data/ # Persistent data directory │ └── kosmi_token_cache.json # Cached JWT token ├── docker-compose.yml ├── matterbridge.toml └── ... ``` ## Troubleshooting ### Token Cache Not Persisting If the token cache doesn't persist across container restarts: 1. Check that the `./data` directory exists and is writable 2. Verify the volume mount in `docker-compose.yml` is correct 3. Check container logs for permission errors ### Force Token Refresh To force a fresh authentication (e.g., if credentials changed): ```bash # Stop the container docker-compose down # Remove the cached token rm ./data/kosmi_token_cache.json # Start the container docker-compose up -d ``` ### Check Token Status To view the current cached token: ```bash cat ./data/kosmi_token_cache.json | jq . ``` This will show you: - When the token was saved - When it expires - Which email it's associated with ## Security Notes - The token cache file has restricted permissions (`0600`) for security - The token is a JWT that expires after 1 year - The cache file is stored locally and never transmitted - If you commit your code to version control, add `data/` to `.gitignore` ## Benefits 1. **Faster Startup**: No browser automation on every restart (saves 10-15 seconds) 2. **Reduced Resource Usage**: No need to launch Chromium on every startup 3. **Persistence**: Token survives container rebuilds, restarts, and host reboots 4. **Automatic Refresh**: Token is automatically refreshed before expiry 5. **Local Storage**: Token is stored on your host machine, not in the container