Tenant Isolation
agent-runner uses the pool model: a shared proxy Lambda and a shared DynamoDB table serve every tenant. Isolation is enforced in the application layer, not by separate infrastructure per tenant.
How a tenant is identified
- The proxy reads the
slugfrom the request’sHostheader. - It resolves
tenant_idvia theSLUG#<slug>GSI1 lookup (60-second in-memory cache). - The credential (Cognito JWT claim or API key record) carries its own
tenant_id.
The binding check
The credential’s tenant_id must equal the tenant resolved from the
Host header. A mismatch is always a 403 — never a 401. This rejects
cross-tenant replay: a valid credential for tenant A cannot be used
against tenant B’s proxy URL.
Every control-plane Lambda performs the same binding verification — no request is processed cross-tenant.
Per-tenant data boundaries
- Each tenant has its own KMS CMK, provisioned at signup.
- DynamoDB rows are partitioned by
TENANT#<id>; cross-tenant queries are not part of any access pattern. - STS session tags (
tenant_id,identity_id,caller_type,bedrock_region) carry through to Bedrock CloudTrail so usage is attributable per tenant. - Skill secrets and MCP credential providers are namespaced under the tenant ID in Secrets Manager / AgentCore.
Last updated on