Data Isolation

All tenant data is isolated at the application level. The SetActiveOrganization middleware ensures every request operates within the correct organization context.

How It Works

The middleware resolves the active organization from the X-Organization-Id header or the user's session:

# Include on every API request
X-Organization-Id: org_abc123

Once the active organization is set, all org-scoped queries automatically filter by organization_id. There is no need to manually add where clauses.

Middleware Stack

Org-scoped routes pass through this middleware chain in order:

auth → SetActiveOrganization → CheckEntitlement → org.can
  • auth — verifies the user is authenticated (Sanctum)
  • SetActiveOrganization — resolves the org from the header/session and sets it as the active tenant
  • CheckEntitlement — verifies the org's plan allows access to the requested feature
  • org.can — checks that the user has the required permission within the org

Scoped Resources

The following resources are automatically scoped to the active organization:

  • API keys
  • Webhooks
  • Projects and custom resources
  • Usage records and metering data
  • File uploads
  • Audit logs

Entitlements

The HasEntitlements trait on the Organization model provides plan-aware access control:

// Check if the org's plan includes a feature
$org->canAccess('advanced_analytics');

// Check if the org has exceeded a usage limit
$org->isOverLimit('api_calls');

// Get remaining quota
$remaining = $org->remaining('api_calls');
  • canAccess($feature) — returns true if the org's current plan grants access to the feature
  • isOverLimit($metric) — returns true if the org has exceeded the plan's limit for a given metric
  • remaining($metric) — returns the remaining quota for a usage-tracked metric