Teams are the primary isolation unit in ManyLayers. Every API key belongs to a team. Every model access control, rate limit, token budget, and firewall setting is configured at the team level. Use teams to reflect how your organization actually works — one team per product, department, or project. Each team operates independently: they have their own model allow-list, their own spending budget, and their own guardrail configuration.

What a team controls

SettingDescription
Model allow-listWhich models this team’s keys can call. Requests to unlisted models return 403.
Rate limitsRequests per minute (RPM) and tokens per minute (TPM) for the team in aggregate.
Token budgetMonthly token cap. Exhausted budgets return 402 until the next period.
USD budgetMonthly spending cap in dollars. Enforced alongside the token budget.
Firewall modemonitor (log prompt injection attempts) or block (reject them).
Default routingThe default gateway config applied to all requests from this team.

Authorization model

Authorization has three rungs, and each is granted separately. Nothing is inherited from the rung above it.
Organization  →  Product  →  Workspace

Organization

There is exactly one organization role: Owner, held by one person. The Owner manages the organization — its members, its security settings, and who may reach each product. That is authority over access to the products, not access within them.
Owning the organization grants no product access. An Owner who has not been granted Gateway cannot open Gateway, cannot call /v1, and sees no Gateway workspaces. This is deliberate: the person who administers billing and membership is often not a user of the products.
Ownership changes hands through an explicit, audited transfer. An organization always has exactly one Owner — the database enforces it.

Product

Each product — Gateway, Studio, Deployer — is granted independently:
RoleAccess
No accessThe default. The product is hidden in the switcher and every one of its API routes returns 403.
MemberReads the product’s resources and uses them: calls models, holds conversations, views deployments.
EditorEverything a Member does, plus creating and modifying resources — applications and keys in Gateway, agents and knowledge in Studio, training jobs in Deployer.
AdminEverything an Editor does, plus product administration: providers, policies, guardrails, budgets, and who may reach the product’s workspaces.
Product roles are product-specific. A Studio Editor authors agents; a Deployer Editor runs training jobs and scales deployments. Granting one product never grants another.

Workspace

A workspace belongs to exactly one product and takes the same three roles: Admin, Editor, Member, set on the workspace’s own members list.
A workspace role is effective only while its holder also has access to the workspace’s product. Gateway: No Access plus Gateway workspace: Admin is denied. The membership is kept rather than deleted — it becomes effective the moment the product is granted, so restoring somebody’s access is one decision rather than a re-invitation to every workspace.
A product Admin reaches every workspace of their product, including ones created later. An Editor or Member reaches only the workspaces they are a member of, and inside one the workspace role decides what they can do — which is what makes per-workspace permissions real.

Specific permissions

A role is a coarse bundle, and the useful cases often sit between two of them: somebody who should manage rate limits and nothing else. Rather than promoting them to Editor — which grants five other things — grant the single permission on top of their role. Permissions are namespaced to their product and can never cross:
gateway.policies.read      studio.agents.manage      deployer.training.manage
gateway.ratelimits.manage  studio.knowledge.read     deployer.deployments.scale
A grant is never a substitute for product access: gateway.policies.manage held by somebody with no Gateway access grants nothing at all. Roles and permissions are defined in application code, not in the database. There is no roles table, no permissions table and no way to invent a permission through the API — the database records only who holds what, where.

Account roles

Separately from the above, each account carries a role used by the content routes: member, editor, admin. (curator was renamed to editor so that a user row and an access row use one word for one authority.) Account roles are assigned directly, or mapped from your identity provider’s groups via the role_claim in your OIDC configuration.

Creating a team

From the admin UI: go to Admin → Teams → New team. Set the team name, choose which models to allow, and configure limits. Via the API:
curl -X POST http://localhost:8180/admin/teams \
  -H "Authorization: Bearer $ADMIN_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "engineering",
    "allowed_models": ["gpt-4o", "claude-3-5-sonnet"],
    "rpm_limit": 1000,
    "tpm_limit": 500000,
    "monthly_budget_usd": 500
  }'

Adding members to a team

Users are assigned to a team when their account is created, or you can update their team membership later. In SSO deployments, team membership can be derived automatically from the team_claim in the JWT — so when someone joins the “engineering” group in your IdP, they’re automatically placed in the engineering gateway team.

Common patterns

One team per product — your mobile app, web app, and internal tools each get their own team with separate budgets. You can see exactly which product is spending what. Shared model, different limits — both the data science team and the support team can use gpt-4o, but the data science team gets a higher TPM limit and larger monthly budget. Strict customer-facing controls — your customer-facing product team is in firewall block mode with a conservative model allow-list. Internal tools teams are in monitor mode with broader model access.

Next steps