profile: field names an isolated tenant scope so one gateway can safely serve many tenants without leaking memory or secrets between them.
Quick Start
1
Bind two tenants to the same agent
Give each route a different
profile: value. The same support agent serves both tenants, but each route names its own isolation scope.2
Read the resolved profile in code
resolve_route() copies the winning binding’s profile onto the RouteMatch, so the wrapper knows which tenant scope to enter for the turn.3
Leave a route unscoped
Omit
profile: (or leave it blank) and the route stays unscoped — match.profile is None.How It Works
resolve_route() picks the most-specific matching binding and copies its profile onto the returned RouteMatch. An unmatched route yields RouteMatch(profile=None).
Fail-Closed Contract
This page documents the routing-protocol contract only:
RouteBinding.profile and RouteMatch.profile are defined on the gateway protocol. The wrapper wiring that actually enters a profile’s memory namespace / secret scope is a follow-up — describe the contract to integrators, but don’t rely on the wrapper isolation subsystem until it ships.Configuration Options
Best Practices
Give every tenant its own profile name
Give every tenant its own profile name
Use one stable, tenant-specific value per route (
acme, globex). Never reuse a profile name across tenants — that would merge their memory and secret scopes.Bind tenants on stable identifiers
Bind tenants on stable identifiers
Route tenant profiles on
channel_id or account — stable platform ids — rather than display names, which change.Keep profile names out of user-controlled input
Keep profile names out of user-controlled input
Profile names come from your config, not from message content. Never derive a profile from a field a user can set.
Related
Route Bindings
The full routing surface — match by peer, role, channel, account, and priority.
Scoped Approvals
Durable, agent-scoped approval grants that don’t leak across agents.

