Tenant Isolation
Overview
Section titled “Overview”Bridge Town is a multi-tenant platform. Every piece of data — projects, models, data sources, tokens, audit logs — belongs to exactly one tenant. Tenants cannot see or access each other’s data.
Row-Level Security (RLS)
Section titled “Row-Level Security (RLS)”PostgreSQL Row-Level Security enforces isolation at the database level. Every request sets the tenant context before executing any queries:
SET LOCAL app.current_tenant_id = '<tenant-uuid>';RLS policies on every table filter rows to only those matching the current tenant. This means:
- A SQL injection cannot access another tenant’s data
- Application bugs cannot leak cross-tenant data
- Even raw database queries are scoped
Authentication flow
Section titled “Authentication flow”- Request arrives with a Bearer token (JWT or API token)
- Auth middleware validates the token and extracts
tenant_idanduser_id - Database session is opened with
SET LOCAL app.current_tenant_id - Route handler executes — all queries are automatically scoped
- Session closes — tenant context is cleared
Dual-mode authentication
Section titled “Dual-mode authentication”Bridge Town supports two authentication methods:
| Method | Format | Use case |
|---|---|---|
| Auth0 JWT | eyJ... (contains .) | Web UI sessions |
| API token | btk_... (argon2id hashed) | MCP clients, CLI, CI/CD |
Both methods resolve to the same (tenant_id, user_id) pair. The auth middleware auto-detects the format.
Project storage isolation
Section titled “Project storage isolation”Each tenant’s projects are stored in a dedicated namespace within the internal project storage layer. All project storage operations are scoped to the authenticated tenant’s namespace — cross-tenant access at the storage layer is not possible.
Sandbox isolation
Section titled “Sandbox isolation”Model execution runs in Docker containers with --network none. Containers are created per-run and destroyed after execution. No persistent state, no network access, no cross-tenant contamination.