> ## Documentation Index
> Fetch the complete documentation index at: https://docs.bedrock.quarry-systems.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Multi-tenant Authorization

> Isolating permissions across tenants with hierarchical scopes

## Overview

Multi-tenant applications need strong isolation between tenants while sharing common infrastructure. Bedrock Cloud provides built-in multi-tenancy with complete isolation between customers.

## Bedrock Cloud Multi-tenant Architecture

```
Tenant A (customer boundary)
└── Workspace
    └── Project (authorization configured here)
        ├── Production
        └── Staging

Tenant B (completely isolated)
└── Workspace
    └── Project
        ├── Production
        └── Staging
```

<Note>
  Each tenant is completely isolated. Users, roles, and permissions in one tenant cannot access another tenant's resources.
</Note>

## Setting Up Multi-tenancy

### 1. Create Tenants via Management API

```bash theme={null}
# Create Acme tenant
curl -X POST 'https://api.example.com/tenants' \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  -d '{
    "name": "Acme Corp",
    "slug": "acme-corp",
    "kind": "standard",
    "planKey": "pro",
    "maxUsers": 50
  }'

# Create Globex tenant
curl -X POST 'https://api.example.com/tenants' \
  -d '{
    "name": "Globex Inc",
    "slug": "globex-inc",
    "kind": "standard",
    "planKey": "pro",
    "maxUsers": 100
  }'
```

### 2. Build Tenant Structure

```bash theme={null}
# Create workspace for Acme
curl -X POST 'https://api.example.com/workspaces' \
  -d '{"tenantId": "tenant_acme", "name": "Main"}'

# Create project
curl -X POST 'https://api.example.com/projects' \
  -d '{
    "tenantId": "tenant_acme",
    "workspaceId": "workspace_main",
    "name": "CRM Application"
  }'

# Create environments
curl -X POST 'https://api.example.com/environments' \
  -d '{"tenantId": "tenant_acme", "projectId": "project_crm", "name": "Production"}'

curl -X POST 'https://api.example.com/environments' \
  -d '{"tenantId": "tenant_acme", "projectId": "project_crm", "name": "Staging"}'
```

### 3. Define Project-Level Roles

Roles and permissions are defined at the **Project** level:

```bash theme={null}
# Create roles for the CRM project
curl -X POST 'https://api.example.com/roles/batch' \
  -d '[
    {"name": "Admin", "description": "Full project access", "scopeId": "scope_project_crm"},
    {"name": "Sales Rep", "description": "Sales data access", "scopeId": "scope_project_crm"},
    {"name": "Viewer", "description": "Read only", "scopeId": "scope_project_crm"}
  ]'
```

## Tenant Isolation

### Users Can Only Access Their Tenant

```bash theme={null}
# Create user via Management API
curl -X POST 'https://api.example.com/users' \
  -d '{
    "kindeId": "kp_acme_user_1",
    "email": "user@acme.com",
    "firstName": "Acme",
    "lastName": "User",
    "defaultTenantId": "tenant_acme"
  }'

# Add to project with a role
curl -X POST 'https://api.example.com/memberships' \
  -d '{"subjectId": "subject_acme_user", "scopeId": "scope_project_crm"}'

curl -X POST 'https://api.example.com/role-assignments' \
  -d '{"roleId": "role_sales_rep", "membershipId": "membership_acme_user_crm"}'

# This user has NO access to Globex tenant
# They can only access Acme's CRM project and its environments
```

### Verifying Tenant Isolation

```typescript theme={null}
// Acme user tries to access Globex project
const decision = await bedrock.evaluate({
  actor: { subjectId: "subject_acme_user", subjectType: "user" },
  scopeId: "scope_project_globex_crm",  // Different tenant!
  action: "read",
  resource: { resourceType: "customer" }
});

// Result: DENIED
// User has no membership in any Globex scope
```

## Agents in Multi-tenant Environments

### Tenant-specific Agents

Each tenant can have their own AI agents scoped to their projects:

```bash theme={null}
# Create Acme's sales assistant agent
curl -X POST 'https://api.example.com/subjects' \
  -d '{
    "subjectType": "agent",
    "externalId": "acme-sales-assistant",
    "displayName": "Acme Sales Assistant",
    "meta": {"model": "claude-3", "purpose": "sales-support"}
  }'

# Add to Acme's CRM project only
curl -X POST 'https://api.example.com/memberships' \
  -d '{"subjectId": "subject_acme_agent", "scopeId": "scope_project_crm"}'

# Assign a restricted role
curl -X POST 'https://api.example.com/role-assignments' \
  -d '{"roleId": "role_viewer", "membershipId": "membership_agent_crm"}'

# This agent can ONLY access Acme's CRM project
```

### Agent Delegation

Agents should act on behalf of users for proper access control:

```typescript theme={null}
// Agent acting on behalf of a sales rep
const decision = await bedrock.evaluate({
  actor: { subjectId: "subject_acme_agent", subjectType: "agent" },
  onBehalfOf: { subjectId: "subject_sales_rep", subjectType: "user" },
  scopeId: "scope_project_crm",
  action: "read",
  resource: { resourceType: "customer" }
});

// Both agent AND user must have the permission
```

## Permission Patterns

### Project-Level Permissions

```bash theme={null}
# Create permissions at project level
curl -X POST 'https://api.example.com/permissions/batch' \
  -d '[
    {"scopeId": "scope_project_crm", "action": "read", "resourceType": "customer", "resourcePattern": "*", "key": "customer:read:*"},
    {"scopeId": "scope_project_crm", "action": "write", "resourceType": "customer", "resourcePattern": "*", "key": "customer:write:*"},
    {"scopeId": "scope_project_crm", "action": "delete", "resourceType": "customer", "resourcePattern": "*", "key": "customer:delete:*"},
    {"scopeId": "scope_project_crm", "action": "export", "resourceType": "report", "resourcePattern": "*", "key": "report:export:*"}
  ]'
```

### Environment-Specific Overrides

```bash theme={null}
# Disable delete in production environment
curl -X POST 'https://api.example.com/scope-overrides/permissions' \
  -d '{
    "childScopeId": "scope_env_production",
    "permissionId": "perm_delete",
    "state": "inactive"
  }'

# Only Admins can export in production
curl -X POST 'https://api.example.com/scope-overrides/role-permissions' \
  -d '{
    "childScopeId": "scope_env_production",
    "roleId": "role_sales_rep",
    "permissionId": "perm_export",
    "state": "revoke"
  }'
```

## Querying Tenant Access

Determine which projects a user has access to:

```typescript theme={null}
async function getUserProjects(subjectId: string, tenantId: string) {
  // Get all memberships for this subject
  const memberships = await fetch(
    `/memberships?subjectId=${subjectId}`
  );
  
  // Filter to projects within this tenant
  const projectMemberships = memberships.filter(m => 
    m.scopeId.startsWith('scope_project_') &&
    m.tenantId === tenantId
  );
  
  return projectMemberships.map(m => m.scopeId);
}

// Check access to a specific project
async function canAccessProject(subjectId: string, projectScopeId: string) {
  const decision = await bedrock.evaluate({
    actor: { subjectId, subjectType: "user" },
    scopeId: projectScopeId,
    action: "read",
    resource: { resourceType: "*" }
  });
  
  return decision.allowed;
}
```

## Best Practices

<AccordionGroup>
  <Accordion title="Define authorization at the Project level">
    Roles and permissions should be defined at the project level, not the tenant level. This allows each project to have its own authorization model.
  </Accordion>

  <Accordion title="Use environment overrides for production">
    Apply overrides to production environments to restrict dangerous operations.
  </Accordion>

  <Accordion title="Scope agents to specific projects">
    Don't give agents tenant-wide access. Scope them to the specific projects they need.
  </Accordion>

  <Accordion title="Use delegation for agent actions">
    When agents act on behalf of users, use the `onBehalfOf` field to ensure proper access control.
  </Accordion>

  <Accordion title="Map external IDs">
    Use `externalId` on tenants and users to map to your billing/CRM systems.
  </Accordion>
</AccordionGroup>

## Next Steps

<CardGroup cols={2}>
  <Card title="Scope Overrides" icon="sliders" href="/guides/scope-overrides">
    Fine-tune permissions at tenant level
  </Card>

  <Card title="Agent Governance" icon="robot" href="/guides/agent-governance">
    Manage agents across tenants
  </Card>
</CardGroup>
