Security¶
Authentication model¶
No passwords stored in Meet¶
Meet does not manage passwords. All authentication is fully delegated to an external OIDC provider (Keycloak, Authentik, Google, etc.). Compromising the Meet database does not expose user credentials.
LiveKit JWT tokens¶
Clients authenticate with the LiveKit media server using short-lived JWTs:
- Signed by the Django backend using LIVEKIT_API_SECRET
- Encode: user identity, room name, and permissions
- Default TTL: 1 hour (LIVEKIT_TOKEN_TTL)
- If LIVEKIT_API_SECRET is compromised, anyone can forge tokens for your LiveKit server — rotate it immediately
Room access levels¶
| Level | Who can join |
|---|---|
| Public | Anyone with the URL |
| Authenticated | Requires OIDC login |
| Lobby | Requires host admission after authentication |
Media encryption¶
Transport encryption (DTLS-SRTP)¶
All WebRTC media is encrypted in transit using DTLS-SRTP. This is mandatory and enforced by all browsers — it cannot be disabled.
This is transport encryption: the LiveKit SFU decrypts and re-encrypts media to forward it. The server operator can theoretically see media content.
End-to-end encryption¶
True E2EE (where even the server cannot decrypt) is in development. When available, it will use WebRTC Insertable Streams / Encoded Transform API.
API security¶
Input validation¶
All API endpoints apply strict input validation. Enhanced validation was added in v1.10.0 to prevent injection and abuse.
CSRF protection¶
The Django backend uses CSRF tokens for browser-based requests. DJANGO_CSRF_TRUSTED_ORIGINS must include your exact HTTPS domain.
Object-level permissions¶
Room endpoints enforce per-object permission checks — users can only access rooms they own or are members of.
Rate limiting¶
API endpoints are rate-limited per authenticated user. The lobby endpoint uses participant-ID-based throttling. Rate limit failures can be tracked via Sentry (SENTRY_DSN).
Known security fixes (by version)¶
| Version | Component | Issue |
|---|---|---|
| v1.5.0 | Frontend | XSS on the recording download page |
| v1.6.0 | Backend | Object-level permission bypass on room endpoints |
| v1.6.0 | Backend | Application validation bypass for external JWTs |
| v1.13.0 | Backend | Email disclosure in room invitation endpoint |
| v1.14.0 | Backend | Participant metadata update permission enforcement |
| v1.14.0 | Multiple | CVEs: aiohttp, Vite, Django, Pillow |
| v1.15.0 | Backend | Room configuration validation |
| v1.15.0 | Frontend | Room IDs generated with non-cryptographic RNG (fixed) |
Always keep your instance up to date. Subscribe to GitHub Security Advisories.
Infrastructure hardening¶
Django secret key¶
Rotate immediately if compromised — invalidates all active sessions.LiveKit API secret¶
Keep at 32+ characters. Treat like a database password.TLS¶
- Use Let's Encrypt or a commercial CA
- Enable HSTS:
Strict-Transport-Security: max-age=31536000; includeSubDomains - Disable TLS 1.0/1.1 in nginx
- nginx-proxy handles this automatically with Let's Encrypt
Database¶
- Use a strong, unique password for PostgreSQL
- Never expose port 5432 publicly
- Use TLS if the database is on a separate host
Object storage (Garage/S3)¶
- Do not expose Garage/S3 ports publicly
- Use IAM-style policies to limit access to specific buckets
- Secure the webhook endpoint with
STORAGE_WEBHOOK_AUTH_TOKEN
Docker¶
The backend and frontend images run as non-root users. Avoid exposing /var/run/docker.sock in production (only nginx-proxy requires it for auto-discovery).
Kubernetes¶
The Meet Helm chart supports full restricted Pod Security Standards as of v1.14.0:
podSecurityContext:
runAsNonRoot: true
containerSecurityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: [ALL]
Reporting vulnerabilities¶
See SECURITY.md for the responsible disclosure policy.
Report vulnerabilities privately to: visio@numerique.gouv.fr
Do not open public GitHub issues for security vulnerabilities.