# How authorization works

This article describes application scopes, permissions, and roles, and how Mosaic places them on user and client access tokens. For an introduction, see [Authorization](/guides/user/authorization_overview).

## Example: an online store

The sections below use an online store to show how the model works.

Shoppers and store managers sign in through a storefront client.

- The application defines the scopes that client may request and the permissions each role grants.
- A scope says the client may call an operation.
- A permission says the user may perform the action.
- Your API checks both, scopes and permissions.


```mermaid
flowchart TB
  subgraph signin [ ]
    direction TB
    Shopper(["Role: Shopper"])
    Manager(["Role: Store manager"])
  end

  Client["<b>Storefront</b><br/>client"]

  subgraph app [Online store application]
    direction TB
    Scopes["<b>Scopes</b>"]
    Perms["<b>Permissions</b>"]
  end

  Shopper --> Client
  Manager --> Client
  Client -->|<b>client access token</b>:<br/>scope: store:browse| Scopes
  Client -->|<b>user access token</b>:<br/>scope: store:browse<br/>roles: Shopper<br/>permissions: browse-store| Perms
  Client -->|<b>user access token</b>:<br/>scope: payments:read<br/>roles: Store manager<br/>permissions: approve-payment| Perms
```

## Scopes

A scope is a privilege you assign to a client. Scopes are defined in the application. Assign them with the [Update client](/openapi/user/clients.openapi/other/updateclient) API: `allowed_scopes` is that assignment. The Admin Portal does not assign custom scopes yet. A client receives a scope only when it requests that scope and the scope is assigned to the client. When the flow includes a [consent screen](/guides/user/auth_consent), the user must also consent to that scope. The user access token then includes only the scopes that are assigned to the client, requested in the OIDC authorization request, and consented to by the user.

Scope values are case-sensitive and unique in the application.

Note
Reserved OAuth and OIDC scopes (`openid`, `profile`, `email`, `address`, `phone`, and `offline_access`) are granted to every client. They are not custom scopes, and you cannot create a custom scope with one of these values. If the client requests a reserved scope, Mosaic includes it in the token.

**Example**: The store defines these scopes:

| Scope | What the client may request |
|  --- | --- |
| `store:browse` | Browse the store catalog |
| `cart:read` | Read a cart |
| `cart:write` | Create or update a cart |
| `cart:checkout` | Start checkout |
| `payments:read` | Read payments |
| `payments:approve` | Approve a payment |


The storefront client is assigned `store:browse`, `cart:read`, `cart:write`, `cart:checkout`, and `payments:read`. It is not assigned `payments:approve`, so a request for that scope does not add it to the token.

In the store, starting checkout requires the `cart:checkout` scope on the token and the `checkout-cart` permission for the user.

## Permissions

A permission is an action a user is allowed to perform. Permissions are defined in the application. User roles reference those permissions, and you assign the roles to users.

Each permission has a system-generated ID, a mandatory value, and an optional description. The value is what your API checks. Values are unique in the application.

**Example**: The store defines these permissions:

| Permission | Action |
|  --- | --- |
| `browse-store` | Browse the store catalog |
| `create-cart` | Create a cart |
| `update-cart` | Add, change, or remove items in a cart |
| `delete-cart` | Delete a cart |
| `checkout-cart` | Start checkout for a cart |
| `view-payment` | View a payment |
| `approve-payment` | Approve a payment |


## User roles

A user role is a named set of permissions. The same permission can belong to more than one role. A user can have more than one role, and the user's permissions are the union of the permissions on those roles.

After the user signs in, your application reads two claims on the user access token. The `roles` claim lists every role assigned to the user. The `permissions` claim lists every permission on those roles. See [Role-based access control](/guides/user/how_rbac_works).

In a B2B application, member roles are also bundled into role groups, and those groups are assigned to organizations. See [Define app roles](/guides/user/b2b/b2b_define_app_roles) and [Create app role groups](/guides/user/b2b/b2b_create_role_groups).

**Example**: In the store, the roles reference permissions as follows:

| Role | Permissions |
|  --- | --- |
| Shopper | `browse-store`, `create-cart`, `update-cart`, `checkout-cart`, `view-payment` |
| Store manager | `browse-store`, `create-cart`, `update-cart`, `delete-cart`, `checkout-cart`, `view-payment`, `approve-payment` |


## How claims are issued in tokens

The claims in an access token define the access that was granted. Which claims Mosaic includes depends on the authorization request. On a token request, the client may send a list of scopes. Mosaic grants a requested scope only when that scope is assigned to the client. When the flow includes a consent screen, the user must also have consented to the scope. On a user access token, Mosaic derives permissions from the roles assigned to the user.

| Claim | Description |
|  --- | --- |
| `scope` | Lists requested scopes that are assigned to the client. Mosaic ignores any other requested scope. When the flow includes a consent screen, the user must also have consented to the scope. |
| `permissions` | On a user access token, lists the permissions on the user's roles. Requested scopes do not filter permissions. |
| `roles` | Lists the user's roles. |


Note
The permissions and scopes authorize calls to your APIs. They are separate from [client roles](/guides/user/manage_client_roles), which control access to Mosaic APIs and appear on client access tokens as `ts_permissions`.

### Example: User access token

The shopper signs in through the storefront client. That client requests the scopes `store:browse`, `cart:read`, `cart:write`, and `payments:approve`. `openid` is included because this is a user login.

Mosaic issues a user access token that includes:

| Claim | Value |
|  --- | --- |
| `scope` | `openid store:browse cart:read cart:write` |
| `permissions` | `browse-store`, `create-cart`, `update-cart`, `checkout-cart`, `view-payment` |
| `roles` | Shopper |


The token includes:

- `store:browse`, `cart:read`, and `cart:write` are included because they are assigned to the storefront client and the client requested them.
- `browse-store` and `checkout-cart` are included because they belong to the Shopper role. `checkout-cart` was not sent in the request.
- `view-payment` is included because it belongs to the Shopper role. Requested scopes do not filter permissions.
- The Shopper role is listed in `roles`.


The token does not include scopes that are not assigned to the client or permissions that are not on the shopper’s role:

- `payments:approve` is not in `scope`, because that scope is not assigned to the storefront client.
- `delete-cart` and `approve-payment` are not in `permissions`, because the Shopper role does not include them. A store manager's token includes both.


### Example: Client access token

A client access token, such as a token from the client credentials grant, follows the same scope rules. It does not include user permissions or user roles, because those come from roles assigned to a user.

If the storefront requests `store:browse` and `cart:read` for itself, the client access token includes:

| Claim | Value |
|  --- | --- |
| `scope` | `store:browse cart:read` |


## Next steps

Configure the store in the Admin Portal and send these requests in [Implement the authorization model](/guides/user/implement_authorization).

table th:first-of-type {
    width: 25%;
}