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:6080

Only requests from these origins are accepted as stateful (cookie-based) API requests.