Scopes vs. Claims
## The Short Version
- **Scope** = *What* your app is asking permission to access
- **Claim** = *A piece of information* about a user (name, email, etc.)
Think of scopes as the **questions** your app asks, and claims as the **answers** the identity provider returns.
---
## Scopes
A scope is a string that identifies the *resource and access level* your app is requesting from the authorization server.
### Common Scopes
| Scope | What It Means |
|-------|---------------|
| `openid` | Request authentication (required for OIDC) |
| `profile` | Access to basic user profile info |
| `email` | Access to the user's email address |
| `phone` | Access to the user's phone number |
| `address` | Access to the user's postal address |
| `offline_access` | Issue a refresh token |
| `read:data` | Read access to a custom API |
| `write:data` | Write access to a custom API |
### How Scopes Work
When you request an authorization code, you list the scopes you want:
```http
GET /authorize?
response_type=code&
client_id=your_client_id&
redirect_uri=https://yourapp.com/callback&
scope=openid%20profile%20email&
state=random_string
```
The identity provider checks whether the **user** has authorized those scopes, and only grants what the user approved.
---
## Claims
A claim is a single **key-value pair** of information about a user. The identity provider returns claims inside the ID token or userinfo response.
### Standard OIDC Claims
| Claim | What It Is |
|-------|-----------|
| `sub` | Subject identifier — unique user ID |
| `name` | User's full display name |
| `given_name` | User's first name |
| `family_name` | User's last name |
| `email` | User's email address |
| `email_verified` | Whether the email has been verified |
| `picture` | URL to the user's profile picture |
| `phone_number` | User's phone number |
| `phone_number_verified` | Whether the phone number is verified |
| `preferred_username` | User's chosen username |
| `locale` | User's preferred language/region |
| `nonce` | Opaque value to prevent replay attacks |
| `at_hash` | Access token hash (for ID token validation) |
| `aud` | Audience — who this token is intended for |
| `iss` | Issuer — which identity provider issued the token |
| `exp` | Expiration timestamp |
| `iat` | Issued-at timestamp |
| `acr` | Authentication Context Class Reference |
| `amr` | Authentication Methods References |
| `azp` | Authorized party (client_id of the app) |
---
## How Scopes and Claims Relate
Scopes are the **request**. Claims are the **response**.
When you request scopes, the identity provider maps them to the corresponding claims:
| Scopes Requested | Claims Returned |
|------------------|-----------------|
| `openid` | `sub` |
| `openid profile` | `sub`, `name`, `given_name`, `family_name`, `preferred_username`, `picture` |
| `openid email` | `sub`, `email`, `email_verified` |
| `openid phone` | `sub`, `phone_number`, `phone_number_verified` |
| `openid profile email phone` | All of the above combined |
---
## Key Differences
| | Scope | Claim |
|--|-------|-------|
| **What it is** | A permission request | A piece of user data |
| **Direction** | Client → Identity Provider (request) | Identity Provider → Client (response) |
| **Format** | String identifier | Key-value pair (e.g. `"name": "Jane Doe"`) |
| **Examples** | `openid`, `profile`, `email` | `sub`, `name`, `email` |
| **Where it appears** | Authorization request URL | ID token, userinfo response |
---
## Example Flow
```
1. App requests: scope=openid profile email
2. User logs in and approves the requested scopes
3. Identity provider returns an ID token containing:
- sub, name, given_name, family_name, email, email_verified
(based on the approved scopes)
```