A scope authorises a read and says nothing about volume. An agent reads a
thousand records in seconds where a person clicks ten, and until now nothing
noticed: the token is valid, the tool is permitted, the ACL passes. That gap
stopped being theoretical the day an autonomous run started reading the whole
catalog on a schedule.
identifier: credential keys the counter on the sub claim — the end user,
whoever is asking on their behalf — so an agent looping under one person's
identity spends that person's budget and cannot spend everyone's. Verified on
catalog: pm-user and ro-user hold separate counters.
Per-route namespace, so a busy domain cannot exhaust another's.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
16 routes: Office (single key, full CRUD + employees sub-resource)
and Employee (single key, full CRUD + reports + customers
sub-resources). MCP layer built with the single-route pattern from
the start.
Only domain where customer role has zero access — verified against
ReferenceDataPermission.check(): read_only/product_manager/support
get reads, writes are admin-only, customer isn't in the allow-list
at all. All 9 MCP tool ACLs reflect this exactly.
Keycloak (local): workforce-api-audience + mcp-workforce-audience
client scopes, resource clients, broker/librechat attachments.
Deploy key and broker secret reused/mirrored, same pattern as every
domain since payments-api.