Authentication
- Enable JWT validation — Set
AUTH_JWT_SECRET(HS256) orAUTH_JWKS_URL(RS256/ES256) on the key server. Never run without auth in production. See Configuration. - Validate JWT claims — Configure the key server to check
aud(audience) andiss(issuer) claims in JWTs to prevent token misuse across services. - Token refresh in player — Implement a
keyServerAuthcallback that returns a fresh token on each key request. See Player Authentication. - Token refresh in uploader — Pass an
authcallback toupload()that returns a fresh token. See Uploader Basic Usage. - Presign requires auth — If
ENABLE_PRESIGN=true, ensure authentication is also enabled. An unauthenticated presign endpoint allows anyone to upload to your S3 bucket. See Presign Endpoint.
CORS
- Set specific origins — Set
CORS_ORIGINSto your app’s exact domain (e.g.,https://app.example.com). Never use*in production. See Configuration. - CDN CORS headers — Configure your CDN to send
Access-Control-Allow-Originfor HLS segment requests. See CDN Configuration.
Secrets
- Store master key securely — Move
MASTER_KEY_HEXandSALT_HEXfrom plaintext env vars to a secret manager (AWS Secrets Manager, HashiCorp Vault, Doppler, etc.) - Back up master key + salt — Losing them means losing access to all encrypted content. Store backups in a separate location from the primary secret store.
- Rotate JWT secrets — Use short-lived JWTs (15-60 minutes). If using HS256, rotate the shared secret periodically.
Database
- Switch to Postgres — If running multiple key server instances or expecting >100 concurrent viewers, set
DATABASE_URLto a Postgres connection string. See Database. - Connection pooling — For Postgres, use a connection pooler (PgBouncer, Supabase Pooler) if running 3+ key server instances.
- Backups — Back up the leases table if you rely on lease revocation for access control.
TLS
- TLS on key server — Terminate TLS at your reverse proxy or load balancer (nginx, Caddy, ALB). The key server itself serves HTTP.
- TLS on CDN — Serve encrypted segments over HTTPS. Most CDNs do this by default.
- TLS on S3 — Use HTTPS for presigned upload URLs. AWS S3 and most compatible services default to HTTPS.
Rate limiting
- Key endpoint rate limiting — Add rate limiting on
GET /keys/:contentIdat the reverse proxy level. Suggested: 60 requests/minute per IP. - Presign endpoint rate limiting — If presign is enabled, limit
POST /presignmore aggressively (e.g., 10 requests/minute per user). - Lease creation rate limiting — Limit
POST /keys/leasesto prevent lease abuse (e.g., 10 requests/minute per user).
Monitoring
- Health check — Point your load balancer or uptime monitor at
GET /health. See Monitoring. - Key fetch latency — Track p50/p95 latency on key requests. Target: under 100ms p95.
- Error rates — Alert on elevated 401/403/500 rates from the key server.
- Player metrics — Call
player.getMetrics()to track time-to-first-frame, decrypt time, and stall count. See Player API Reference.
Content delivery
- CDN for segments — Serve encrypted HLS segments from a CDN, not directly from S3. See CDN Configuration.
- Cache policy — Segments are immutable (cache forever). Manifests may change (short TTL or no-cache). See CDN Configuration.
Key rotation (optional)
- Plan rotation strategy — If you need to rotate the master key, follow the dual-key deployment process. See Key Rotation.