---
title: "Create Roles"
description: "Roles are collections of permissions that can be assigned to principals (Accounts, API Keys, or external IAM identities) within a specific organizational scope."
stack: "Enterprise Stack (commercial) — version 0.21.0"
stack_version: "0.21.0"
stack_comparison: https://docs.walt.id/community-vs-enterprise.md
canonical_url: https://docs.walt.id/enterprise-stack/administration/access-and-permissions/roles/create-roles
generated: 2026-07-20
---
# Create Roles

Roles are collections of permissions that can be assigned to principals (Accounts, API Keys, or external IAM identities) within a specific organizational scope.

## Creating a Role

**Option: CURL**

Endpoint: `/v1/{target}/roles-api/roles/create` | [API Reference](https://enterprise.sandbox.walt.id/swagger/index.html#/Service%20%2F%20Roles/post_v1__target__roles_api_roles_create)

**Example Request**

```bash
curl -X 'POST' \
  'https://{orgID}.enterprise-sandbox.waltid.dev/v1/{target}/roles-api/roles/create' \
  -H 'accept: */*' \
  -H 'Authorization: Bearer {yourToken}' \
  -H 'Content-Type: application/json' \
  -d '{
  "name": "Issuer Operator",
  "permissions": [
    {
      "target": "waltid.production.issuer1",
      "action": "issuer-credential-issue",
      "operation": "ADD"
    },
    {
      "target": "waltid.production.issuer1",
      "action": "issuer-session-view",
      "operation": "ADD"
    }
  ]
}'
```

**Path Parameters**

- `orgID`: Your organization's Base URL. For example, if your organization is named `myorg`, your Base URL will be `myorg.enterprise-sandbox.waltid.dev` in the sandbox environment.
- `target`: The resource identifier for the new role, formatted as `{organizationID}.{roleID}` (e.g., `waltid.issuer-operator`)

**Body Parameters**

- `name`: _String_ - Human-readable name for the role
- `permissions`: _Array_ - List of permission objects defining what this role can and cannot do

**Permission Object**

| Field | Type | Description |
|-------|------|-------------|
| `target` | String | The scope where the permission applies (organization, tenant, or service path) |
| `action` | String | The permission name (e.g., `issuer-credential-issue`, `all`). See [Permissions Reference](https://docs.walt.id/enterprise-stack/administration/access-and-permissions/permissions/overview.md) |
| `operation` | String | `ADD` to grant the permission (allow), `REMOVE` to deny the permission |

---

**Response**

```json
{
  "_id": "waltid.issuer-operator",
  "name": "Issuer Operator",
  "permissions": [...]
}
```

**Response Codes**

- `201` - Role created successfully

## Permission Operations

### ADD (Allow)

Grants the specified permission. When a principal with this role attempts the operation, the permission check will pass (unless overridden by a deny rule).

```json
{
  "target": "waltid.production",
  "action": "issuer-credential-issue",
  "operation": "ADD"
}
```

### REMOVE (Deny)

Creates an explicit deny rule. This overrides any allow rules, even from other roles or broader scopes. Use this to create exceptions in broad permission grants.

```json
{
  "target": "waltid.production.sensitive-issuer",
  "action": "issuer-credential-issue",
  "operation": "REMOVE"
}
```

## Example: Full Admin with Restrictions

Create a tenant admin who can do everything except delete resources recursively:

```bash
curl -X 'POST' \
  'https://{orgID}.enterprise-sandbox.waltid.dev/v1/waltid.restricted-admin/roles-api/roles/create' \
  -H 'accept: */*' \
  -H 'Authorization: Bearer {yourToken}' \
  -H 'Content-Type: application/json' \
  -d '{
  "name": "Restricted Tenant Admin",
  "permissions": [
    {
      "target": "waltid.production",
      "action": "all",
      "operation": "ADD"
    },
    {
      "target": "waltid.production",
      "action": "delete-resource-recursive",
      "operation": "REMOVE"
    }
  ]
}'
```

## Adding Permissions to an Existing Role

You can add additional permissions to a role after creation:

**Option: CURL**

Endpoint: `/v1/{target}/roles-api/permissions/permissions/add-to-role`

**Example Request**

```bash
curl -X 'POST' \
  'https://{orgID}.enterprise-sandbox.waltid.dev/v1/{target}/roles-api/permissions/permissions/add-to-role' \
  -H 'accept: */*' \
  -H 'Authorization: Bearer {yourToken}' \
  -H 'Content-Type: application/json' \
  -d '{
  "target": "waltid.production.issuer1",
  "action": "issuer-credential-profile-view"
}'
```

**Path Parameters**

- `target`: The role ID to modify (e.g., `waltid.issuer-operator`)

**Body Parameters**

- `target`: The scope for the permission
- `action`: The permission to add
- `operation`: (Optional) Defaults to `ADD`. Set to `REMOVE` to add a deny rule.

---

**Response Codes**

- `200` - Permission added successfully

## Adding a Deny Rule to an Existing Role

To revoke a specific permission (create a deny rule):

```bash
curl -X 'POST' \
  'https://{orgID}.enterprise-sandbox.waltid.dev/v1/waltid.admin-role/roles-api/permissions/permissions/add-to-role' \
  -H 'accept: */*' \
  -H 'Authorization: Bearer {yourToken}' \
  -H 'Content-Type: application/json' \
  -d '{
  "target": "waltid.production",
  "action": "delete-resource",
  "operation": "REMOVE"
}'
```

Users with this role will be denied the `delete-resource` permission on `waltid.production` and all resources below it, even if they have broader `all` permissions.

## Viewing a Role

**Option: CURL**

Endpoint: `/v1/{target}/roles-api/roles/view`

**Example Request**

```bash
curl -X 'GET' \
  'https://{orgID}.enterprise-sandbox.waltid.dev/v1/{target}/roles-api/roles/view' \
  -H 'accept: application/json' \
  -H 'Authorization: Bearer {yourToken}'
```

**Path Parameters**

- `target`: The role ID to view (e.g., `waltid.issuer-operator`)

---

**Response**

```json
{
  "_id": "waltid.issuer-operator",
  "name": "Issuer Operator",
  "permissions": [
    {
      "target": "waltid.production.issuer1",
      "action": "issuer-credential-issue",
      "operation": "ADD"
    }
  ]
}
```

## Listing Roles

**Option: CURL**

Endpoint: `/v1/{target}/roles-api/roles/list`

**Example Request**

```bash
curl -X 'GET' \
  'https://{orgID}.enterprise-sandbox.waltid.dev/v1/{target}/roles-api/roles/list' \
  -H 'accept: application/json' \
  -H 'Authorization: Bearer {yourToken}'
```

**Path Parameters**

- `target`: The scope to list roles from (e.g., `waltid` for organization-level roles, `waltid.production` for tenant-level roles)

## Deleting a Role

**Option: CURL**

Endpoint: `/v1/{target}/roles-api/roles/delete`

**Example Request**

```bash
curl -X 'DELETE' \
  'https://{orgID}.enterprise-sandbox.waltid.dev/v1/{target}/roles-api/roles/delete' \
  -H 'accept: */*' \
  -H 'Authorization: Bearer {yourToken}'
```

**Path Parameters**

- `target`: The role ID to delete (e.g., `waltid.issuer-operator`)

---

**Response Codes**

- `200` - Role deleted successfully

**Error:**

Deleting a role removes it from all principals who have it assigned. Make sure no active users or API keys depend on the role before deletion.

## Related

- [Permissions Reference](https://docs.walt.id/enterprise-stack/administration/access-and-permissions/permissions/overview.md) - Complete list of available permissions
- [Assign Role to Account](https://docs.walt.id/enterprise-stack/administration/access-and-permissions/accounts/assign-role.md)
- [Assign Role to API Key](https://docs.walt.id/enterprise-stack/administration/access-and-permissions/api-keys/assign-role.md)
