Claude gateway: let a session choose which group (billing code and budget) it bills to
Preflight Checklist
- [x] I have searched existing requests and this feature hasn't been requested yet
- [x] This is a single feature request
Problem Statement
We run claude gateway with one managed.policies entry per Entra group. Each
group stands for a billing code: its policy sets cli.env.OTEL_RESOURCE_ATTRIBUTES
to that group's cost center, and the group has its own spend limit.
Some people work for more than one group, so they're in more than one, and today
they can't choose which one a session bills to:
- Attribution goes by list order. The policies are first-match-wins, so a
user in two groups always gets the first one listed, in every session. Being
added to a second group changes nothing. Reordering the list only moves
everyone who's in both groups at once.
- Budgets go by membership. Group spend limits apply to all of a user's
groups together (group_limit_mode, default min). So for that user, usage is
reported under one cost center while the limit comes from both groups.
- The client can't override it. The managed
envkey wins over user and
project settings, which is right for billing integrity. But it means the only
way to change billing code today is an admin changing the user's Entra
membership.
Proposed Solution
Let a session choose its billing group, and have the gateway check that choice:
- The client sends the choice as a request header (for example
x-claude-gateway-group: <group>), set in project .claude/settings.json.
ANTHROPIC_CUSTOM_HEADERS can carry this today if nothing managed pins it,
though a first-class setting would be cleaner.
- The gateway accepts the choice only if the group is in the user's token
claims. Otherwise it rejects the request, or ignores the choice and logs it.
- The gateway bills and enforces limits against the chosen group's policy and
spend limit, and applies that policy's cli.env to the session.
- With no choice set, it behaves exactly as today (first match), so existing
deployments don't change.
Setting this per project means work bills to the right code automatically. It
doesn't depend on someone remembering to switch. Entra membership still decides
which groups a user may bill to; only the choice among them moves to the
client.
Alternative Solutions
- Single membership per user: deterministic, but every switch needs an admin.
Doesn't work for people who regularly split time between groups.
- Reordering policies: changes the result for every dual-membership user at
once, not per person or per session.
- One gateway URL per group, each with its own
CLAUDE_CONFIG_DIRlocally:
works, but needs separate routing per group and doesn't scale.
- A proxy in front of the gateway that rewrites attribution: a separate service
to run and secure, and it duplicates the gateway's own group checks.
Priority
High - Significant impact on productivity
Feature Category
Configuration and settings
Use Case Example
- A developer is in group A (cost center A, budget A) and group B (cost center
B, budget B). Group A is listed first in managed.policies.
- Repo X belongs to B's program. Its
.claude/settings.jsonchooses group B. - In repo X, the gateway sees B in the user's token, so usage goes to cost
center B and counts against budget B.
- In any repo without a choice set, usage goes to A, as it does today.
- If the user is removed from group B, sessions in repo X are rejected (or fall
back to A and log it), so nobody can bill a group they aren't in.
Additional Context
- Observed on Claude Code 2.1.294–2.1.296, gateway signed in with Entra SSO,
group claims emitted as Group ID.
- Related, not a duplicate: #95269 (Desktop ignores
OTEL_RESOURCE_ATTRIBUTES
from project settings) shows people already want attribution set per project.
This request is the gateway-enforced version of that.