# Apply object grants

```{raw} html
<div class="mo-api-page-show-toc" aria-hidden="true"></div>
```

Save the complete grant changes for one role on one object. Saving changes the actions available to that role on the object.

```text
PUT https://moi.matrixorigin.cn/newmoi/workspaces/{workspace_id}/iam/permissions/objects/{resource_type}/{resource_id}/roles/{role_id}/grants
```

## Preparation before calling

Select the object and role to grant, then [view the object permission view](get-object-permission-view.md#confirm-object-grant-state) to confirm the current grant state. Next, [view the permission schema](../application-permissions/get-permission-schema.md#select-policy-inputs) to select supported actions and grant scopes.

Prepare a [personal access token](../../../../../guides/genesis/api-keys.md) with the required permissions for the target workspace and the [target workspace ID](../../../../../guides/ai-studio/resource-center/workspace.md#copy-a-workspace-id).

## Request parameters

:::::::{div} mo-api-tabs
::::::{tab-set}
:::::{tab-item} Input example

```bash
curl -X PUT "https://moi.matrixorigin.cn/newmoi/workspaces/$WORKSPACE_ID/iam/permissions/objects/$RESOURCE_TYPE/$RESOURCE_ID/roles/$ROLE_ID/grants" \
  -H "X-API-Key: $AI_STUDIO_API_KEY" \
  -H "X-Workspace-ID: $WORKSPACE_ID" \
  -H "Content-Type: application/json" \
  -d '{
    "schema_version": "current-schema-version",
    "expected_policy_version": 1,
    "expected_role_lifecycle_version": 1,
    "request_id": "req-001",
    "changes": [{"remove": false, "action_id": "workflow.read"}]
  }'
```

:::::
:::::{tab-item} Parameter description

### Path parameters

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `workspace_id` | string | Yes | Target workspace ID. |
| `resource_type` | string | Yes | Resource type of the target object. |
| `resource_id` | string | Yes | Resource ID of the target object. |
| `role_id` | string | Yes | Role ID receiving the grant changes. |

### Request body

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `schema_version` | string | Yes | Permission schema version used by this change. |
| `expected_policy_version` | integer | No | Policy version used for concurrency checks; cannot be less than 0. |
| `expected_role_lifecycle_version` | integer | Yes | Current role lifecycle version; must be greater than 0. |
| `request_id` | string | Yes | Caller-generated idempotency request ID. |
| `changes` | object array | Yes | Grant changes to save; must contain at least one item. |
| `changes[].remove` | boolean | No | `true` removes a grant; omitted or `false` adds a grant. |
| `changes[].action_id` | string | Yes | Action ID in the permission schema. |
| `changes[].condition_hash` | string | No | Hash of the condition expression. |

:::::
::::::
:::::::

## Successful response

On success, the grant changes are saved and a new policy version is returned. Replaying the same request ID with identical content does not apply the changes again.

:::::::{div} mo-api-tabs mo-api-response-tabs
::::::{tab-set}
:::::{tab-item} Response example

```json
{"code":"OK","msg":"OK","data":{"workspace_id":"workspace-001","resource_type":"workflow","resource_id":"workflow-001","target_role_id":"role-001","previous_policy_version":1,"policy_version":2,"statement_count":1,"added_count":1,"removed_count":0,"idempotent_replay":false,"canonical_policy_hash":"sha256:example","validate_only":false,"request_id":"req-001","trace_id":"trace-001"}}
```

:::::
:::::{tab-item} Field details

| Field | Type | Description |
| --- | --- | --- |
| `code` | string | `OK` on success. |
| `msg` | string | `OK` on success. |
| `data.workspace_id` | string | Target workspace ID. |
| `data.resource_type` | string | Target resource type. |
| `data.resource_id` | string | Target resource ID. |
| `data.target_role_id` | string | Role ID receiving the grant changes. |
| `data.previous_policy_version` | integer | Policy version before the update. |
| `data.policy_version` | integer | Policy version after the update. |
| `data.statement_count` | integer | Number of policy statements after the update. |
| `data.added_count` | integer | Number of added statements. |
| `data.removed_count` | integer | Number of removed statements. |
| `data.idempotent_replay` | boolean | Whether this is an idempotent replay of the same request. |
| `data.canonical_policy_hash` | string | Hash of the policy after saving. |
| `data.validate_only` | boolean | Always `false` for this endpoint. |
| `data.request_id` | string | Request correlation ID. |
| `data.trace_id` | string | Trace ID. |

:::::
::::::
:::::::

## Error response

:::::::{div} mo-api-tabs mo-api-response-tabs
::::::{tab-set}
:::::{tab-item} Response example

```json
{"code":"ErrParamInvalid","msg":"Invalid request parameters","data":null}
```

:::::
:::::{tab-item} Field details

| Field | Type | Description |
| --- | --- | --- |
| `code` | string | Error code. |
| `msg` | string | Error message. |
| `data` | null | — |

:::::
::::::
:::::::
