Saltar al contenido principal

Multi-Tenancy

Appilot is a multi-tenant platform where each organization's data is fully isolated.

How it works​

Every user belongs to one or more organizations. The JWT token carries the active organization context, and all API queries are scoped accordingly.

User A ─── Organization 1 ──┐
├─── Shared Appilot Backend
User B ─── Organization 2 ──┘

Organization 1 and Organization 2 share infrastructure but never see each other's data.

What's isolated per organization​

ResourceIsolation level
Knowledge contentFully isolated
Domains & URL patternsFully isolated
User membershipsPer-organization roles
RAG files & documentsFully isolated
AI configurationPer-organization settings
Analytics & activityFully isolated
ConversationsPer-user, per-organization
Knowledge requestsFully isolated

Organization context in APIs​

Every API request is scoped to the organization in the JWT:

Authorization: Bearer <token with org_id=abc>
GET /api/knowledge
→ Returns only knowledge for organization "abc"

There is no way to query another organization's data through the API — the backend enforces row-level data filtering.

Users in multiple organizations​

A user can belong to multiple organizations. To access data from a different organization, they must switch context:

POST /api/auth/switch-organization
{ "organizationId": "other-org-uuid" }
→ Returns a new JWT with the updated org context

Implications for developers​

When integrating the widget or extension:

  • Widget: The Widget API key determines which organization's knowledge is used. The backend resolves the organization from the key — no orgId needed in configuration.
  • Extension: The user's active organization (set during login) determines the knowledge scope
  • API: All calls are automatically scoped — no need to pass organization IDs in each request

Widget API keys and tenancy​

Each Widget API key is bound to exactly one organization. When the widget sends a request with the X-Widget-Key header, the backend:

  1. Looks up the key in widget_api_keys
  2. Resolves the organization_id from the key record
  3. Validates the request's Origin against the key's allowed domains
  4. Scopes all data access to that organization

This means a single page cannot access data from multiple organizations through the widget.