Skip to content

Multi-Tenancy

Hierarchy

Organization
├── Team (with roles: admin, member, viewer)
│   └── Workspace
│       └── Project
│           ├── Tasks
│           └── Workflow Instances
├── Skills (org-scoped)
├── Configs (org-scoped)
└── Secrets (org/team/workspace-scoped)

How Scoping Works

TenantMiddleware resolves request.organization and request.project from:

  1. X-Organization / X-Project headers (API clients)
  2. Session (active_organization_id / active_project_id)
  3. First membership (fallback)

Views filter queries by request.organization to prevent cross-tenant data leaks.

Auth Stack

  • django-guardian: object-level RBAC
  • django-oauth-toolkit: OAuth2 for external integrations
  • Scoped API keys: per-key scopes, expiry, dispatcher binding
  • HMAC callbacks: signed with CALLBACK_SIGNING_KEY
  • Hashed tokens: callback tokens stored as SHA-256, never plaintext