SPB Git

Repository Public

security.md 3.5 KB

# Security and threat model

# Assets

xAI API key (spend), the studio (publication rights), private prompts and drafts, visitor privacy.

# Controls

Threat Control
Key leaks to the browser, logs or API Key read only in src/lib/env.ts (server); never serialised; structured logger redacts authorization and anything matching xai-…; scripts/secrets-scan.ts scans client chunks and tracked files in pnpm check
Studio takeover No default password: scripts/bootstrap-owner.ts generates a one-time password (scrypt hash stored), forced change at first login; TOTP second factor (enforced once enrolled); sessions are random 256-bit tokens stored hashed, HttpOnly; Secure; SameSite=Strict, 12 h idle / 7 d absolute; login rate limit 5/min/IP + 10/h/account
Privilege misuse Roles owner > editor > viewer; every studio page, server action and API route calls requireRole() server-side; all mutations are written to audit_log
CSRF SameSite=Strict cookie + Origin check on every mutating request; Server Actions are origin-checked by Next.js
XSS React escaping, no dangerouslySetInnerHTML on user or model text, CSP (default-src 'self', no remote scripts, frame-ancestors 'none')
Runaway spend Budget gate before every paid call, kill switch, bounded retries, regeneration cap, scheduler quota, idempotency keys (no duplicate paid generation), circuit breaker
SSRF The server fetches only api.x.ai and provider result URLs, which are validated against an allow-list of xAI hosts (src/providers/http.ts). No user-supplied URL is ever fetched
Upload abuse The studio accepts no file uploads in this version (all media is generated); nothing to scan. Reference uploads, if added, must validate MIME/size and run a scanner
Private media exposure /media/* serves only assets linked to a published film; everything else needs a studio session or a signed URL (HMAC-SHA256, expiry)
Abuse of public write endpoints Reactions, analytics and reports are rate-limited per hashed visitor and accept fixed-shape payloads only
Injection Parameterised SQL (postgres-js tagged templates) everywhere

# Content safety and provenance

  • Every film carries a visible "AI-generated" disclosure, a public provenance block (models, dates, pipeline stages, human approval) and container metadata in the MP4 (comment, description). C2PA signing is not implemented (no signing certificate); the provenance JSON is served at /api/films/:slug.
  • No impersonation: the brief validator and the Quality Critic reject real, named people; voices are provider presets only (no cloning).
  • Factual series must pass the Research Editor: each claim needs a source, otherwise the film is labelled fiction/speculation or held for a human.
  • Moderation happens before publication (provider moderation flag + critic safety score + human approval). /report files a takedown request; an operator can unpublish in one action (assets stop being served).

# Visitor data

No account, no third-party script, no advertising identifier. A visitor is a daily-rotating hash (sha256(secret | day | ip | user-agent)), used only to de-duplicate views and likes; raw IPs are not stored. Analytics events are deleted after 90 days; bookmarks live in the browser (localStorage).

# Known gaps

Passkeys (WebAuthn) are not implemented (password + TOTP instead). C2PA not implemented. No external error tracker (structured logs + PM2 + health probe). Docker Compose file is provided but the production deployment is PM2 on macOS.

Files main
Menu

Theme