Architecture
Tenant Isolation
How Binexia isolates tenant data — schema-per-tenant, RLS, and Docker isolation.
Binexia uses three layers of isolation to ensure tenant data never leaks.
1. Schema-per-Tenant (Primary)
Each tenant gets five PostgreSQL schemas (tenant_data, tenant_semantic, tenant_config, tenant_agent_state, tenant_knowledge). The TENANT_SLUG environment variable determines which schemas the application uses.
Laravel's BelongsToProvider trait automatically scopes all queries to the current tenant's schemas. Models use $table = 'tenant_slug.table_name' syntax where the prefix is resolved at runtime from the environment.
2. PostgreSQL Row-Level Security (Optional)
Opt-in RLS policies add a defense-in-depth layer. When RLS_ENABLED=true:
- Policies restrict rows to the current tenant's slug
- Even if a query escapes the application-level scoping, the database enforces isolation
- Enabled in production, can be disabled for simpler local development
3. Docker Compose Isolation (Production)
In production, each customer gets their own Docker Compose stack on a dedicated server. This means:
- Separate PostgreSQL instances
- Separate Redis instances
- Separate Agno agent runtimes
- No shared processes between customers
Info
The IP testing and local development setups run a single tenant in one Docker Compose stack. This is safe because there's only one tenant.
Auth Scoping
SANCTUM_STATEFUL_DOMAINS restricts which domains can make authenticated API requests. In ip-test mode:
SANTUM_STATEFUL_DOMAINS=192.168.1.50,192.168.1.50:6080,localhost,localhost:6080Only requests from these origins are accepted as stateful (cookie-based) API requests.