Scopes & Consent

A scope is a label attached to an access token that says “this token can do these things and nothing else.” Resource servers look at scopes before they honor a request.

The badge analogy

Picture a conference. At the door, you get a badge. The badge has stickers:

  • attendee: get into the main hall
  • lunch: eat in the cafeteria
  • backstage: not granted

You hand your badge to whoever you meet. A bouncer at the backstage door looks for the right sticker and turns you away.

OAuth2 scopes work the same way. The access token is the badge, each scope is a sticker, and the resource server is the bouncer.

GET /api/admin/users
Authorization: Bearer ...

→ 403 Forbidden (required scope: admin:users)

What scopes look like

Scopes are just short strings. There is no universal naming convention; pick one and be consistent. Common shapes:

  • read:orders, write:orders (verb
    )
  • orders.read, orders.write (resource.verb)
  • openid, profile, email (OIDC’s standard scopes, more on this in a moment)
  • admin (a coarse, role-like scope)

Scopes are usually requested in the authorization URL:

GET /authorize?
  response_type=code&
  client_id=my-frontend&
  scope=openid profile read:orders&
  ...

When a client requests scopes that affect the user’s data, the authorization server can show a consent screen:

my-frontend wants to:
  ☑ Access your basic profile
  ☑ Read your orders
  ☐ Modify your billing details

   [Deny]    [Allow]

Consent gives the user the final say. It is what makes OAuth2 feel like a delegation protocol and not a permission rubber-stamp.

Not every scope needs consent. Two categories:

  • User-consentable scopes: meaningful to the end user. Show them.
  • Internal/technical scopes: meaningless to the user (internal_service_call). Skip consent; the client is trusted.

Standard OIDC scopes

OIDC reserves a handful of well-known scopes:

ScopeMeaning
openidMandatory for OIDC. Triggers ID Token issuance.
profileAdds standard profile claims (name, family_name, picture…)
emailAdds email and email_verified claims
addressAdds address claim
phoneAdds phone_number claim
offline_accessRequests a refresh token

If you only see one OIDC scope in the wild, it will be openid. Without it, OIDC is not in play. You are doing plain OAuth2.

Scopes vs roles vs permissions

Newcomers often conflate three things. They are different.

  • Scope: what this token is allowed to do. Granted at authorization time, per client request, with possible user consent.
  • Role: what this user is, organizationally. A persistent attribute (admin, support, viewer). Roles are usually mapped into tokens as claims.
  • Permission: a fine-grained allowed action. Derived from roles, scopes, and policies inside the resource server.

For fine-grained authorization that goes beyond what scopes can encode, see AuthZen.

Client scopes

A common pattern is to attach default scopes to a client, so they are always present in tokens issued to that client. FerrisKey supports this directly: a client has default and optional scopes.

In FerrisKey

FerrisKey lets you define scopes per realm, attach them to clients (default or optional), and shape exactly which claims they add to tokens.