18.7 Permission per tool
- Approved by
- Panaversity ·
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.
- Grace signs in and picks Brightline. Her role in Brightline is
auditor. The sign-in server turns that into one permission,ap:read. - She asks about an invoice.
get_purchase_orderneedsap:read. It runs. - She asks about a vendor.
find_vendoralso needsap:vendors.read. The connector answers 403, "you may not do this", and names every permission the call needs. - 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. - 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,memberorauditor. Role names are written in code type, so "amember" means the role, not just anyone in the company. A role belongs to a membership, and the company'sowneroradminsets it.ownerandadmincan also add and remove people.memberandauditorcannot. - 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:
| Role | Scopes |
|---|---|
owner, admin, member | ap:read, ap:vendors.read |
auditor | ap:read |
| Tool | Scope it needs |
|---|---|
list_open_invoices, get_purchase_order, search_policy | ap:read |
find_vendor | ap: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.

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?
Sources
- Owner
- Panaversity