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