Reelora docs
v1.1.0
Live demo Get help
● Ship · What protects your service

Security.
What is built in and what is yours to do.

Playback addresses are signed and expire, purchases and ad rewards are verified on the server, the coin ledger is append-only, and console secrets are encrypted and write-only. Your part is the server, the keys and the backups.

Signed mediaServer-side verificationEncrypted, write-only secretsAudit log

01Built in

AreaHow it is protected
VideoLocked episodes are only served from signed addresses that expire (default 6 hours). Tampered, expired or reused-for-another-episode addresses get 403. Optional BunnyCDN token mode checks every request at the edge.
CoinsCoins are never added on the device. The wallet is an append-only ledger on the server.
PurchasesApp Store transactions verified against Apple's root certificate (embedded in the server code, checked by fingerprint) and your bundle id; Google Play through the Android Publisher API; Stripe by signed webhook; PayPal by server capture with exact amount and currency. Each purchase is bound to the account that made it.
Ad rewardsCredited only from AdMob's signed server-side verification callback, each transaction once, with a daily cap.
ConsoleSign-in with rate limits, optional two-factor (TOTP), roles, audit log of every sign-in and change, history with rollback. No console page answers without signing in.
SecretsAPI keys and service accounts are stored encrypted with ADMIN_SECRET_KEY, write-only (replace or test, never read back), owner only.
Rate limitsGuest sign-up 30 per IP per hour, registration 10 per IP per hour, sign-in 20 per IP and 8 per account per 15 minutes, checkout 20 per viewer per hour, manual top-ups 5 per viewer per day.
HeadersThe web player, studio and share pages send a Content Security Policy; the console also sends frame-ancestors 'none' and X-Frame-Options: DENY.

02Your part

  • Keep .env out of version control and readable only by the server user.
  • Back up ADMIN_SECRET_KEY: without it stored secrets cannot be decrypted.
  • Keep DEMO_MODE=false on a live service.
  • Set TRUST_PROXY_HOPS correctly so limits see real client addresses.
  • Only set COUNTRY_HEADER when every request passes through the proxy that fills it.
  • Turn on two-factor for owners; give team members the smallest role they need.
  • Keep the operating system, Node.js and ffmpeg updated, and run npm audit after updates.

03Rotating keys, and what to do if you lose one

Windows

The commands below are for Linux or macOS. On Windows run them in WSL or Git Bash.

Create every new key with openssl rand -hex 32, put it in server/.env and restart the server. What happens next depends on the key:

KeyWhat changing it breaksFor how longSteps
MEDIA_SIGNING_KEYPlayback addresses already handed out stop working at once.Until the player asks for a new address: viewers who press play again get a new one immediately. Without rotation an address lives at most the Playback address lifetime (Media & CDN, default 360 minutes).Set the new value, restart. Nothing else to do. Do it at a quiet hour if you want to avoid interrupting playing viewers.
ADMIN_SECRET_KEYEvery secret saved in the console (Stripe, PayPal, Google Play service account, Firebase service account, AI keys, BunnyCDN key, webhook secret) can no longer be decrypted. Accounts, settings that are not secrets, and all viewer data stay.Until you enter the secrets again. Payments, push and AI that need a secret fail in the meantime.Have every provider secret at hand, set the new value, restart, then enter each secret again in the console and use Test where offered. Check Console → Status.
ORIGIN_PULL_SECRETBunnyCDN pulls from /media/origin are refused while Bunny and the server send different values.A few seconds to minutes, until both sides match. Video the CDN has already cached keeps playing.Change the Bunny edge rule and .env one right after the other, then restart.
ADMIN_SETUP_TOKENNothing once an owner exists: it is never accepted again.-Remove it from .env after the first sign-in.

Lost ADMIN_SECRET_KEY? The encrypted secrets cannot be recovered. Set a new key as above and enter the secrets again; nothing else is lost. Lost the owner password? Use reset-owner on the server. Provider key leaked? Revoke it in the provider's dashboard first, then save the new one in the console.

04Viewer data and account deletion

Viewers start as guests; an e-mail and password are optional. Viewers can delete their account and its data from the app (DELETE /api/me), which both stores require. The data lives in your database on your server.