> ## Documentation Index
> Fetch the complete documentation index at: https://cloudinary.com/documentation/llms.txt
> Use this file to discover all available pages before exploring further.

# Assign roles

This guide describes the Roles and Permissions system. For details on all roles available in the legacy system, see [Role-based permissions](user_provisioning#role_based_permissions).

> **INFO**:
>
> :title=Which permissions system do you have?
> Use the rollout schedule to find out:

> * **Enterprise accounts**: Broad Enterprise migration hasn't started yet. If your team hasn't already been moved with Cloudinary's help, you're still on the legacy system.

> * **Existing free and paid accounts**: Migration starts May 12, 2026.

> * **New free accounts (created since February 2026)**: You may already have the new system.
> You can confirm which permissions system you have. Open **Console Settings** and look for **Role Management**. If it's listed, your account is on Roles and Permissions. If it isn't listed, you're still on the legacy permissions model. 
> ![Global role management](https://cloudinary-res.cloudinary.com/image/upload/f_auto/q_auto/bo_1px_solid_grey/roles_interface.png "thumb: w_800,dpr_2, width:800, with_code:false, with_url:false, popup:true")
> The Roles and Permissions system provides more granular, flexible access control than the legacy system. 

> * For a quick comparison, see [Roles and Permissions vs. legacy](dam_admin_users_groups#roles_and_permissions_vs_legacy). 

> * If your account is being migrated, see [Migrating to Roles and Permissions](permissions_migration) to understand what changes.

## Overview

You can assign all roles defined in your account to principals, including users, groups, and API keys.

* Use the Permissions API to assign [global, folder, and collection roles](#assign_roles_via_the_permissions_api).
  > **NOTE**: :title=For Free plan customers:

  The Permissions API isn't available on the Free plan. You can [manage roles and permissions](dam_admin_permissions) via the [Console](https://console.cloudinary.com/app/settings/role-management) only and assign folder roles to API keys and other principals programmatically via the [Admin API](#assign_folder_roles_via_the_admin_api).

* Use the Admin API to assign [folder roles](#assign_folder_roles_via_the_admin_api).

> **TIP**: To learn how to provision roles using SAML SSO, see [SAML SSO](permissions_manage_roles_ui#saml_sso).

## Assign roles via the Permissions API

Enterprise customers can use their account management keys to manage and assign all roles via the Permissions API.

#{partialdoc}partial_permissions_url_auth{partialdoc}

### Method 1: Assign a role to multiple principals

Use this method when you want to assign the **same role** to multiple principals.

**Endpoint:**  
`PUT /permissions/roles/{role_id}/principals`

The request body should include:

* An `operation` field (at the top level) that defines whether to add or remove the listed principals.
* A `principals` array containing one or more principal assignment objects.

{table:class=first-column} Field               | Applies To         | Description            |
|--------------------|--------------------|-------------------------|
| `operation`         | Top-level          | Whether to **add** or **remove** the listed principals from the role. **Values:** `add`, `remove`                                                   |
| **Principal object fields:** |                    | _(Each object in the `principals` array must include the following fields.)_                                                                             |
| `principal_type`    | Each role assignment     | Type of principal. **Values:** `user`, `group`, `apiKey`, `provisioningKey`                                                                         |
| `principal_id`      | Each role assignment    | Unique ID of the user, group, or key receiving the role.                                                                                                 |
| `scope_id` | Each role assignment (if scoped to a product environment) | The product environment ID. Find this on the [Product Environments](https://console.cloudinary.com/app/settings/product-environments) page. |
| `policy_parameters` | Each role assignment (if the role applies to a specific folder or collection) | ID of the folder or collection the permission applies to.                                                                                                 |

#### Example 1: Assign principals to an account role

```json
{
  "operation": "add",
  "principals": [
    {
      "principal_type": "user",
      "principal_id": "1234abc",
    },
    {
      "principal_type": "user",
      "principal_id": "9876xyz",
    }
  ]
}
```

#### Example 2: Assign a global role across different product environments

```json
{
  "operation": "add",
  "principals": [
    {
      "principal_type": "user",
      "principal_id": "1234abc",
      "scope_id": "975l29lz02jt0836fhwi"
    },
    {
      "principal_type": "user",
      "principal_id": "9876xyz",
      "scope_id": "weliweo37829jtklpole"
    }
  ]
}
```

#### Example 3: Assign a content role to different folders

```json
{
  "operation": "add",
  "principals": [
    {
      "principal_type": "user",
      "principal_id": "1234abc",
      "scope_id": "975l29lz02jt0836fhwi",
      "policy_parameters": {
        "folder_id": "asdfjkl12347890"
      }
    },
    {
      "principal_type": "user",
      "principal_id": "9876xyz",
      "scope_id": "975l29lz02jt0836fhwi",
      "policy_parameters": {
        "folder_id": "bggoiu0987654"
      }
    }
  ]
}
```

#### Example 4: Remove a principal from a role

```json
{
  "operation": "remove",
  "principals": [
    {
      "principal_type": "user",
      "principal_id": "1234abc",
    }
  ]
}
```

### Method 2: Assign roles to a principal

Use this method to assign multiple roles of different permission types and scopes (account, product environment, global, and content) to a single principal:

`PUT /permissions/principal_roles`

The request body should include:

* An `operation` field (at the top level) that defines whether to add or remove the roles from the specified principal.
* A `principal` object specifying the principal to assign roles to.
* A `roles` array containing one or more role assignment objects. Each object may optionally include `scope_id` and/or `policy_parameters`, depending on the role.

{table:class=first-column} Field               | Applies To         | Description            |
|--------------------|--------------------|-------------------------|
| `operation`         | Top-level          | Whether to **add** or **remove** the listed roles from the principal. **Values:** `add`, `remove`                                                   |
| **Principal object fields:** |                    | _(The `principal` object must include the following fields.)_                                                                             |
| `principal_type`    | The principal     | Type of principal. **Values:** `user`, `group`, `apiKey`, `provisioningKey`                                                                         |
| `principal_id`      | The principal     | Unique ID of the user, group, or key receiving the role.   |
**Role object fields:** |                    | _(Each object in the `roles` array must include the following fields.)_
`id`                | Each role          | ID of the role to apply to the principal.
| `scope_id` | Each role assignment (if scoped to a product environment) | The product environment ID. Find this on the [Product Environments](https://console.cloudinary.com/app/settings/product-environments) page. |
`policy_parameters` | Each role assignment (if the role applies to a specific folder or collection) | ID of the folder or collection the permission applies to.

#### Example: Assign multiple roles of different types to a principal

```json
{
  "operation": "add",
  "principal": {
    "type": "user",
    "id": "user_abc123"
  },
  "roles": [
    {
      "id": "cld::role::account::billing",
    },
    {
      "id": "cld::role::prodenv::ml_admin",
      "scope_id": "975l29lz02jt0836fhwi"
    },
    {
      "id": "cld::role::folder::manager",
      "scope_id": "975l29lz02jt0836fhwi",
      "policy_parameters": 
      {
        "folder_id": "asdfjkl12347890"
      }
    },
    {
      "id": "custom::role::prodenv::overseer",
      "scope_id": "975l29lz02jt0836fhwi"
    }
  ]
}
```

### Inspecting role assignments

Use these endpoints to view current role assignments and permissions:

{table:class=no-borders overview} Endpoint                                      | Use Case                                       |
|----------------------------------------------|------------------------------------------------|
| [GET /roles/{role_id}/principals](permissions_api#tag/roles/GET/v2/accounts/{account_id}/permissions/roles/{role_id}/principals) | See who has a specific role.  |
| [GET /principal_roles](permissions_api#tag/principals/PUT/v2/accounts/{account_id}/permissions/principal_roles)  | See what roles a user or key has.    |
| [GET /principal_roles/inspect](permissions_api#tag/principals/GET/v2/accounts/{account_id}/permissions/principal_roles/inspect) | View effective permissions for a user or key (debug access issues). |

#### View effective permissions

Use the `GET /principal_roles/inspect` endpoint to check which roles or permission policies apply to a user, group, or key, based on specific content, product environments, or scopes.

This endpoint is especially useful for debugging access issues, such as:

* Why a user can or can't access a folder or collection

* Whether a key has permission to perform an action in a specific product environment

* Confirming inherited or global role assignments

You can filter by:

* Principal: `principal_type` and `principal_id`

* Scope: `scope_type` (`account` or `prodenv`), and `scope_id` if needed

* Content instance: `folder_id`, `collection_id`, or `asset_id`

To inspect broad access, you can also use special values like `folder_id=all`.

> **TIP**: See the [GET /principal_roles/inspect](permissions_api#tag/principals/GET/v2/accounts/{account_id}/permissions/principal_roles/inspect) for specific code examples.

## Assign folder roles via the Admin API

You can use the Admin API to assign folder roles to users, groups, and API keys. This provides an alternative method for folder role assignment alongside the [Permissions API](#assign_roles_via_the_permissions_api).

> **NOTE**:
>
> :title=For Free plan customers:
> The Admin API `folder_operations/invite` endpoint is available for assigning folder roles to API keys and other principals. However, Free plan customers don't have access to the full Permissions API for managing and assigning other role types.
> For additional role management options on the Free plan, see:

> * [Managing and assigning global roles in the Console](dam_admin_role_management)

> * [Assigning folder and collection roles to users and groups in the Media Library](dam_admin_role_management#assign_folder_and_collection_roles_to_users_and_groups)

###  Base URL and authentication
You can assign roles to users, groups, and product environment API keys to grant permissions for specific folder instances via the [Admin API](admin_api).

By default, the Admin API endpoints use the following format:

`https://api.cloudinary.com/v1_1/:cloud_name/:action`

For example, to list all video assets in the `cld-docs` product environment:

```
GET https://api.cloudinary.com/v1_1/cld-docs/resources/video
```

The API uses **Basic Authentication** over secure HTTP. Your Cloudinary **API Key** and **API Secret** (which can be found on the [API Keys](https://console.cloudinary.com/app/settings/api-keys) page of your Cloudinary Console Settings) are used for the authentication.

You can experiment with returning a list of the images in your own Cloudinary product environment by replacing the `API_KEY`, `API_SECRET`, and `CLOUD_NAME` in the cURL command below:

```
curl https://<API_KEY>:<API_SECRET>@api.cloudinary.com/v1_1/<CLOUD_NAME>/resources/image
```

### folder_operations/invite

Enables you to grant or remove roles for a specific folder to a principal (user, group, or API key).

Method | Description
---|---
GET<code class="code-method">/folder_operations/invite/:folder_external_id | [Lists the principals and roles assigned to a folder.](#get_folder_roles)
POST<code class="code-method">/folder_operations/invite/:folder_external_id | [Assigns or removes roles for a folder to a principal.](#assign_folder_roles)

---

#### Get folder roles

Lists the principals and their roles assigned to a specific folder.

##### Syntax
`GET /folder_operations/invite/:folder_external_id`

##### Required parameters
Parameter | Type | Description
---|---|---
folder_external_id | String | The immutable identifier (external_id) of the folder, returned by [Get root folders](admin_api#get_root_folders) or [Get subfolders](admin_api#get_subfolders).

##### Example
Get the roles assigned to a specific folder:

```curl
curl https://<API_KEY>:<API_SECRET>@api.cloudinary.com/v1_1/<CLOUD_NAME>/folder_operations/invite/<FOLDER_EXTERNAL_ID>
```

##### Sample response
```json
{
    "shared_with": [
        {
            "type": "user",
            "id": "cec735fd65b7d541f35d9f661d130f",
            "folder_id": "cd7e9d690a014c68ae8b58f08e090cb03a",
            "roles": [
                {
                    "id": "cld::role::folder::manager",
                    "description": "Editor permissions, plus delete, share internally, and download all assets.",
                    "name": "Manager",
                    "inherited": false
                }
            ]
        }
    ]
}
```

---

#### Assign folder roles

Assigns or removes roles for a specific folder to a principal (user, group, or API key). 

The operation supports system folder roles such as `cld::role::content::folder::editor`. For a full list of system folder roles, see [Folder roles](permissions_system_roles_policies#folder_roles).

Enterprise customers can also create and assign custom roles via this endpoint using the custom role's ID. To learn more about custom roles, see [Manage roles via API](permissions_manage_roles_api).

##### Syntax
`POST /folder_operations/invite/:folder_external_id`

##### Required parameters
Parameter | Type | Description
---|---|---
folder_external_id | String | The immutable identifier (external_id) of the folder, returned by [Get root folders](admin_api#get_root_folders) or [Get subfolders](admin_api#get_subfolders).
principal_type | String | The principal type. **Possible values**: `user`, `group`, or `apiKey`
principal_id | String | The ID of the principal. For type `apiKey`, use the key string itself.
operation | String | The operation to perform: `add` to grant roles, `remove` to revoke them.
roles | Array[String] | The IDs of the roles to assign or revoke. **Example**: `cld::role::content::folder::editor`

##### Examples
Assign the folder manager role to an API key:

```curl
curl https://<API_KEY>:<API_SECRET>@api.cloudinary.com/v1_1/<CLOUD_NAME>/folder_operations/invite/<FOLDER_EXTERNAL_ID> \
  -H "Content-Type: application/json" \
  -d '{
      "principal": {
        "id": "799451857115779",
        "type": "apiKey"
        },
      "operation": "add",
      "roles": ["cld::role::folder::manager"]
      }'
```

Assign the folder editor role to a user:

```curl
curl https://<API_KEY>:<API_SECRET>@api.cloudinary.com/v1_1/<CLOUD_NAME>/folder_operations/invite/<FOLDER_EXTERNAL_ID> \
  -H "Content-Type: application/json" \
  -d '{
      "principal": {
        "id": "cec735fd65b7d541f35d9f661d130f",
        "type": "user"
        },
      "operation": "add",
      "roles": ["cld::role::folder::editor"]
      }'
```

##### Sample response
```json
{
  "success": true
}
```

> **See also**:
>
> * [Role-based permissions](permissions_overview): An overview of Cloudinary's role-based permissions solution

> * [Role management in the Console](permissions_manage_roles_ui): UI-based role management

> * [Manage roles](permissions_manage_roles_api): How to manage roles via API

> * [System role and policy reference](permissions_system_roles_policies): A list of all system roles and system permission polices provided by Cloudinary

> * [Permissions API reference](permissions_api): Full list of endpoints and schemas

> * [Define custom policies](permissions_custom_policies): Create and apply policies outside of roles