Skip to main content

API authentication

Cinephage uses Better Auth for authentication with session-based login and API key support.

Authentication Methods​

MethodUse CaseAuth Type
SessionWeb UI accessCookie-based
Main API KeyFull API access, automationHeader/Query
Streaming API KeyMedia server integrationHeader/Query

Session Authentication​

Login flow​

  1. POST to /api/auth/sign-in/credential with username and password
  2. Server creates session and sets cookie
  3. Subsequent requests include session cookie automatically

Session properties​

PropertyValue
Duration7 days
RefreshEvery 24 hours
Cookie Namecinephage_session
HttpOnlyYes
SameSiteLax

Single admin architecture​

Cinephage uses a single-administrator model:

  • First user registration becomes the admin
  • Additional registrations are disabled after setup
  • Only one user account exists per installation

API Key Authentication​

API key types​

Key TypePermissionsUse Case
Main API KeyFull access to all endpointsAutomation, scripts, tools
Streaming API KeyLive TV, EPG, streaming onlyMedia server integration

Streaming API key permissions​

AllowedDenied
/api/livetv/*/api/library/*
/api/streaming/*/api/settings/*
/api/livetv/playlist.m3u/api/indexers/*
/api/livetv/epg.xmlAdmin-only operations

Using API keys​

Via Header (Recommended):

curl -H "x-api-key: cinephage_your_key_here" \
http://localhost:3000/api/library/movies

Via Query Parameter:

curl "http://localhost:3000/api/livetv/playlist.m3u?api_key=cinephage_your_key_here"
When to Use Query Parameter

Some media servers (Plex, Jellyfin) can't send custom headers. Use the query parameter for M3U playlist URLs.

Managing API keys​

Navigate to Settings > System:

ActionDescription
ViewShow full key value
CopyCopy to clipboard
RegenerateCreate new key (old key invalidates)
Regenerating Keys

Regenerating a key immediately invalidates the old key. Update any services using the key before regenerating.

API key storage​

API keys are encrypted at rest:

  • Algorithm: AES-256-GCM
  • Encryption key derived from BETTER_AUTH_SECRET
  • Stored in userApiKeySecrets database table

Rate Limiting​

API key rate limits​

Key TypeWindowMax Requests
Streaming API1 hour10,000

Configure via environment variables:

VariableDefaultDescription
STREAMING_API_KEY_RATE_LIMIT_WINDOW_MS3600000Window in ms (1 hr)
STREAMING_API_KEY_RATE_LIMIT_MAX10000Max requests/window

Login rate limiting​

LimitValue
Max Attempts5
Window15 minutes

Endpoint Authorization​

Authorization levels​

LevelFunctionDescription
None-Public endpoint
requireAuthrequireAuth()Any authenticated user
requireAdminrequireAdmin()Admin role required

Response codes​

CodeMeaning
200Success
401Not authenticated
403Authenticated but not authorized

Common endpoint patterns​

Public (No Auth):

  • /api/health
  • /api/ready
  • Most GET endpoints

Authenticated (requireAuth):

  • /api/library/* (read operations)
  • /api/search

Admin Only (requireAdmin):

  • /api/settings/*
  • /api/indexers/* (create/update/delete)
  • /api/download-clients/* (create/update/delete)

Environment Variables​

Required​

VariableDescription
BETTER_AUTH_SECRETSecret for session signing and encryption

Optional​

VariableDefaultDescription
BETTER_AUTH_URLFrom settingsBase URL for auth callbacks
BETTER_AUTH_TRUSTED_ORIGINSNoneAdditional trusted origins

Generating BETTER_AUTH_SECRET​

# Using openssl
openssl rand -base64 32

# Using Node.js
node -e "console.log(require('crypto').randomBytes(32).toString('base64'))"
Changing BETTER_AUTH_SECRET

Changing this secret will:

  • Invalidate all active sessions (users must re-login)
  • Make encrypted API keys unreadable (must regenerate)
  • Cannot be undone

Trusted Origins​

Cinephage automatically trusts:

  1. Local development: localhost:3000, localhost:5173, 127.0.0.1
  2. Private networks: RFC1918 addresses (10.x, 172.16-31.x, 192.168.x)
  3. Environment configured: BETTER_AUTH_URL, ORIGIN
  4. Settings configured: External URL from Settings > System

Security Best Practices​

API key security​

  • Don't commit keys to version control
  • Use environment variables in scripts
  • Use Streaming API Key for media servers (least privilege)
  • Regenerate compromised keys immediately

BETTER_AUTH_SECRET​

  • Generate a unique value for each installation
  • Back it up securely - needed for database restoration
  • Don't change it unless absolutely necessary
  • Treat it like a password - keep it secret

Network security​

  • Use HTTPS in production
  • Restrict admin endpoints with reverse proxy rules
  • Use VPN for remote access when possible

Troubleshooting​

"401 unauthorized"​

Session auth:

  • Session may have expired - log in again
  • Cookie may be blocked - check browser settings

API key auth:

  • Key may be invalid - verify in Settings > System
  • Key may be wrong type - use Main API Key for library access

"403 forbidden"​

  • Authenticated but not admin
  • Check if endpoint requires admin role
  • Streaming API Key used for non-streaming endpoint

API key not working​

  1. Check key is correct - Copy from Settings > System
  2. Check header name - Must be x-api-key
  3. Check permissions - Streaming key has limited access
  4. Check rate limits - May be temporarily blocked

Sessions invalid after restart​

If all sessions are invalidated after restart:

  • BETTER_AUTH_SECRET may have changed
  • Database may have been reset
  • This is expected behavior with new secret

See Also​