4.8 KiB
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:
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"email": "your-email@example.com",
"expires_at": "2026-11-02T15:56:23Z",
"saved_at": "2025-11-02T15:56:23Z"
}
Token Lifecycle
-
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
-
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
-
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
- File permissions are set to
Docker Configuration
Volume Mount
The docker-compose.yml includes a volume mount for persistent storage:
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:
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:
- The bridge will launch a headless browser
- Authenticate with Kosmi using your credentials
- Extract and cache the JWT token
- 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.):
- The bridge checks the cached token
- If valid, uses it immediately (no browser needed)
- 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):
- The bridge automatically performs fresh authentication
- Updates the cached token
- 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:
- Check that the
./datadirectory exists and is writable - Verify the volume mount in
docker-compose.ymlis correct - Check container logs for permission errors
Force Token Refresh
To force a fresh authentication (e.g., if credentials changed):
# 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:
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
- Faster Startup: No browser automation on every restart (saves 10-15 seconds)
- Reduced Resource Usage: No need to launch Chromium on every startup
- Persistence: Token survives container rebuilds, restarts, and host reboots
- Automatic Refresh: Token is automatically refreshed before expiry
- Local Storage: Token is stored on your host machine, not in the container