Spaces:
Running
Running
docs: document Studio identity and tenant isolation setup
Browse files
docs/STUDIO_IDENTITY_SETUP.md
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# MediaRouter Studio identity and tenant isolation
|
| 2 |
+
|
| 3 |
+
MediaRouter Studio authenticates users with Supabase on the Next.js server and forwards a short-lived, signed identity envelope to MediaRouter. The shared MediaRouter API token is a server-to-server transport credential; it must never be exposed to browser code.
|
| 4 |
+
|
| 5 |
+
## Required configuration
|
| 6 |
+
|
| 7 |
+
Set these values in both environments:
|
| 8 |
+
|
| 9 |
+
- **Studio / Vercel:** `STUDIO_IDENTITY_SECRET` and `MEDIAROUTER_API_TOKEN`. Keep them server-only; do not use a `NEXT_PUBLIC_` prefix.
|
| 10 |
+
- **MediaRouter / Hugging Face Space:** `STUDIO_IDENTITY_SECRET` with the exact same secret value, plus the existing API authentication and production database configuration.
|
| 11 |
+
|
| 12 |
+
Use a cryptographically random secret of at least 32 bytes. Generate one with a password manager or a secure local random generator. Do not paste it into source control, logs, or chat. Restart/redeploy both services after setting it.
|
| 13 |
+
|
| 14 |
+
The Studio proxy signs the UTF-8 bytes of four newline-separated values in this order: timestamp (Unix seconds), Supabase user ID, normalized email, display name. It uses HMAC-SHA256 and sends the lowercase hexadecimal signature in `x-mr-studio-signature`. The backend validates the signature in constant time and rejects envelopes more than 300 seconds from server time.
|
| 15 |
+
|
| 16 |
+
## Tenant onboarding is explicit
|
| 17 |
+
|
| 18 |
+
A valid Supabase session proves identity, but it does **not** automatically grant a MediaRouter workspace. Before a user can use tenant-backed Studio APIs, the backend security database must contain:
|
| 19 |
+
|
| 20 |
+
1. An active `users` row whose `subject` exactly matches the Supabase user ID.
|
| 21 |
+
2. Exactly one active `workspace_memberships` row for that user, linked to an active `workspaces` row.
|
| 22 |
+
3. A supported membership role: `owner`, `admin`, `developer`, `operator`, `viewer`, or `member`.
|
| 23 |
+
|
| 24 |
+
Users with no active membership or more than one active workspace membership are denied. This is deliberate: the current Studio identity envelope has no workspace selector, and the backend must not guess a tenant. Do not solve onboarding by trusting a workspace ID from a browser request or by assigning every newly signed-in user an owner role. Implement a separately authorized invitation/provisioning flow before allowing self-service workspace creation.
|
| 25 |
+
|
| 26 |
+
## Authorization behavior
|
| 27 |
+
|
| 28 |
+
The backend treats the shared API key as transport authentication only when a signed Studio identity is present. It resolves the Supabase subject against persisted backend membership, replaces the key's tenant identity with that persisted principal, and intersects API-key scopes with the membership role's default scopes. Workspace owners/admins are mapped to the backend `developer` capability set, not the global API `admin` role. Viewer/member access is restricted to the viewer capability set.
|
| 29 |
+
|
| 30 |
+
If any Studio identity header is present, the complete envelope and signature are required. The Studio proxy also fails closed when it cannot validate a Supabase session; it must not forward the shared token as a fallback for an unidentified browser request.
|
| 31 |
+
|
| 32 |
+
## Production verification checklist
|
| 33 |
+
|
| 34 |
+
- [ ] Set the same random `STUDIO_IDENTITY_SECRET` in Vercel and the HF Space.
|
| 35 |
+
- [ ] Confirm `MEDIAROUTER_API_TOKEN` is only a server-side Vercel environment variable.
|
| 36 |
+
- [ ] Provision one explicit backend user and workspace membership for each Studio user, or implement an authorized invitation flow.
|
| 37 |
+
- [ ] Use a non-superuser tenant database role and verify forced RLS policies on production tables; a passing application-level check alone is not proof of database isolation.
|
| 38 |
+
- [ ] Test with two distinct Studio accounts: create/read/update/delete a project and access an asset/job in account A, then confirm account B cannot read, mutate, cancel, or download A's resources.
|
| 39 |
+
- [ ] Test expired and tampered signatures, disabled users/memberships/workspaces, and users with zero or multiple active memberships.
|
| 40 |
+
- [ ] Run the backend unit/integration tests and inspect production logs for denied cross-tenant access before merging/deploying.
|
| 41 |
+
|
| 42 |
+
This document describes the intended configuration and checks; it is not evidence that the live deployment has been configured or that the checklist has passed.
|