Skip to content
The AI Agent Factory

18.7 Permission per tool

Approved by
Panaversity ·
8 min read

In everyday life. In an office building, a cleaner's badge opens every corridor but no office. A manager's opens her team's offices. A visiting auditor's opens the records room, and only during the audit. The badges are the same kind of card. What each opens depends on who holds it.

What you will learn. How what a person is in a company becomes permissions in a token, and what happens when a tool needs more than the token carries.

Why it matters. An outside checker should read invoices without seeing vendor bank details. Permission per tool is how one connector does both.

One request, start to finish. Brightline hires an outside auditor, Grace: someone from another firm who checks the accounts. She may read invoices, purchase orders and policies, but not vendor details, which include bank account endings and the AP team's private notes.

  1. Grace signs in and picks Brightline. Her role in Brightline is auditor. The sign-in server turns that into one permission, ap:read.
  2. She asks about an invoice. get_purchase_order needs ap:read. It runs.
  3. She asks about a vendor. find_vendor also needs ap:vendors.read. The connector answers 403, "you may not do this", and names every permission the call needs.
  4. Her app asks for more. It goes back to the sign-in server, asking for both permissions. The sign-in server checks her role and does not grant ap:vendors.read.
  5. She gets a clear answer. The app shows that her role does not allow vendor details. She asks Ana if she needs them.

What is the difference between a role and a scope?

Two words that are easy to mix up:

  • A role is what a person is inside one company: owner, admin, member or auditor. Role names are written in code type, so "a member" means the role, not just anyone in the company. A role belongs to a membership, and the company's owner or admin sets it. owner and admin can also add and remove people. member and auditor cannot.
  • A scope is one named permission a token carries. Each tool in the connector needs one or more scopes.

The sign-in server turns a role into scopes when it makes a token. The connector never sees roles, only scopes. So it asks one question per call: "does this token carry every scope this tool needs?"

Brightline's mapping:

RoleScopes
owner, admin, memberap:read, ap:vendors.read
auditorap:read
ToolScope it needs
list_open_invoices, get_purchase_order, search_policyap:read
find_vendorap:read and ap:vendors.read

Every call needs ap:read, and find_vendor also needs ap:vendors.read.

How does an app ask for more?

An app first asks for the scopes the connector's 401 names, the minimum for ordinary use, here ap:read. When a call needs more, the connector answers 403 and should list every scope that call needs, all at once, so the app asks only once. An app acting for a person should then step up: ask the sign-in server again for its old scopes plus the new ones, and retry. Ana, an owner, sees one more consent screen, approves, and continues. Grace, an auditor, is not granted the extra scope, and the app gives up instead of asking again and again.

Remember the two refusals as a pair: 401 means the token is missing, wrong or expired. 403 means a good token without the right permission.

Read-only today. Every Brightline tool reads. When Chapter 23 adds the first tool that acts, such as schedule_payment, it gets its own scope, ap:pay, which no role has until someone decides who may move money.

At work. The builder adds the auditor role to docs/auth-spec.md with Ana, as a manager: who may see vendor bank endings? Ana says everyone except auditors. The builder asks Claude Code for a test where an auditor's token calls find_vendor and must get 403 naming both scopes.

The operating rule: give each tool the scopes it needs, map each role to the fewest scopes it needs, ask for the minimum first, and answer a missing scope with a 403 that names every scope the call needs.

The standards behind this concept: the MCP authorization specification's scope and step-up rules.1 Field guide F4 shows the exact 403.

Three columns joined by arrows. Left, roles: owner, admin, member, auditor. Middle, scopes: ap:read and ap:vendors.read, and a greyed future ap:pay that no role has. Right, tools: list_open_invoices, get_purchase_order and search_policy need ap:read. find_vendor also needs ap:vendors.read. Below, a step-up loop: a token with ap:read calls find_vendor, gets 403 naming ap:read and ap:vendors.read, the app asks the sign-in server again, and an owner or member is granted it while an auditor is not.

Figure 18.10. Roles become scopes at the sign-in server. Every tool needs ap:read, and find_vendor also needs ap:vendors.read. A missing scope gets a 403 and a chance to step up.

Check yourself

Question 1 / 7

0 answered

Grace has the role auditor at Brightline. She calls find_vendor. What does the connector answer?

  1. Authorization, MCP specification 2026-07-28, MCP.↑
Owner
Panaversity