API key security
Default API key
WARNING: The default API key (dev-api-key-12345) is for development only and must be changed in production.
Changing the API key
Set the API key environment variable
Update the
JOYSTICK_API_KEY in your .env file or docker-compose.yml:Update all services
The API key must be set in both services that use it:
- PocketBase: Uses it to authenticate with Joystick API
- Switcher: Uses it to authenticate with Joystick API
API key storage
Best practices:- Never commit API keys to version control
- Add
.envto.gitignore - Use environment variables or secrets management services
- Rotate API keys periodically
- Use different keys for different environments (dev, staging, production)
JWT token authentication
How JWT authentication works
- User authenticates with PocketBase using email/password
- PocketBase returns a JWT token
- Client includes JWT in subsequent requests via:
Authorization: Bearer <token>header, or?token=<token>query parameter
Getting a JWT token
Using JWT tokens
Bearer token in header
Query parameter
Token expiration
JWT tokens expire after a configured period (typically 24 hours). When a token expires:- Requests will return
401 Unauthorized - Client must re-authenticate to get a new token
- Implement token refresh logic in your application
Token security best practices
- Store tokens securely (e.g., httpOnly cookies, secure storage)
- Never expose tokens in URLs in production (use headers instead)
- Implement token refresh before expiration
- Validate tokens on the server side
- Use HTTPS in production to prevent token interception
Permissions system
Feature-based permissions
Joystick uses a feature-based permission system. Users must have specific permissions to access certain endpoints.Permission types
| Permission | Endpoints | Description |
|---|---|---|
device-cpsi | GET /api/cpsi | Access cellular signal information |
device-battery | GET /api/battery | Access battery status |
device-gps | GET /api/gps | Access GPS location data |
device-imu | GET /api/imu | Access IMU sensor data |
notifications | POST /api/notifications/send | Send notifications |
Assigning permissions
Permissions are stored in thepermissions collection in PocketBase:
- Go to PocketBase admin panel at
http://localhost:8090/_/ - Navigate to the
permissionscollection - Create or edit permission records for users
- Add the required permission names to the user’s permission list
Device access control
Users can only control devices they have explicit access to.Device allow list
Each device has anallow field containing an array of user IDs:
Granting device access
Network security
Firewall configuration
Only expose necessary ports to the internet: Public (with authentication):- Port 80 (HTTP) - Main application
- Port 443 (HTTPS) - If using TLS
- Port 8080 - Traefik dashboard
- Port 8084 - Dozzle logs
- Port 8090 - PocketBase admin
- Port 9997 - MediaMTX API
Example firewall rules (ufw)
HTTPS/TLS configuration
For production deployments, enable HTTPS using Let’s Encrypt with Traefik.Update Traefik configuration
Enable HTTPS redirect
CORS configuration
CORS is currently configured to allow all origins (*). For production, restrict to specific domains:
Docker security
Run containers as non-root
By default, containers run as root. For production, create a non-root user:Use read-only root filesystem
Limit container resources
Security scanning
Scan images for vulnerabilities:PocketBase security
Admin account
- Create a strong password for the admin account
- Change the default admin email
- Enable two-factor authentication if available
- Restrict admin panel access to specific IPs
Database backups
Regularly backup PocketBase data:Collection rules
Configure PocketBase collection rules to restrict access:- List/View:
@request.auth.id != ""(authenticated users only) - Create/Update/Delete:
@request.auth.id = owner(owner only)
MediaMTX security
Authentication
Configure authentication inmediamtx.yml:
API access
Restrict API access to localhost or specific IPs:Security checklist
Before deploying to production:- Change default API key (
JOYSTICK_API_KEY) - Enable HTTPS with valid SSL certificates
- Configure firewall rules
- Set strong passwords for PocketBase admin
- Restrict CORS to specific domains
- Configure proper file permissions for volumes
- Enable Docker security scanning
- Set up automated backups
- Review and restrict PocketBase collection rules
- Configure MediaMTX authentication
- Disable Traefik insecure API
- Disable Dozzle in production or add authentication
- Set resource limits on containers
- Enable audit logging
- Document security procedures for your team