# Lock a role to a workload (/docs/guides/operate/settings-profiles)



Lock a role to a workload [#lock-a-role-to-a-workload]

Settings profiles connect access control to scheduling. Give a role a default
[`workload`](/docs/reference/sql/settings/session#workload), then use `CONST`
when that role must not choose another one.

Before you begin [#before-you-begin]

* Set `RAWTREE_API_KEY` to an administrator API key.
* Use `analytics`. If it does not exist, create it with the [`POST /v1/databases` endpoint](/docs/reference/api/databases#post-v1databases).
* Pass `?database=analytics` on each query. If you omit it, the Query API uses the API key's stored default database.

1\. Create a role [#1-create-a-role]

Create a role for the service.

```sql test
CREATE ROLE analytics_analyst
```

2\. Create a workload [#2-create-a-workload]

Create a workload for the role.

```sql test
CREATE WORKLOAD analyst_workload ON CLUSTER 'default'
```

3\. Set the role's default workload [#3-set-the-roles-default-workload]

Set a default workload and prevent the role from changing it.

```sql test
CREATE SETTINGS PROFILE analytics_analyst_profile SETTINGS workload = 'analyst_workload' CONST TO analytics_analyst
```

4\. Create a role key [#4-create-a-role-key]

Create an API key that uses the role.

```bash
curl -X POST 'https://api.rawtree.com/v1/keys?database=analytics' \
  --header "Authorization: Bearer $RAWTREE_API_KEY" \
  --header "Content-Type: application/json" \
  -d '{"name":"analytics_analyst","database_roles":["analytics_analyst"]}'
```

The response contains the new key's ID and token.

```json
{
  "id": "<key-id>",
  "token": "rt_..."
}
```

Save the `token` value as `READER_API_KEY` and the `id` value as `READER_KEY_ID`.

5\. Query with the role key [#5-query-with-the-role-key]

Run a query with the returned key.

```bash
curl -X POST 'https://api.rawtree.com/v1/query?database=analytics' \
  --header "Authorization: Bearer $READER_API_KEY" \
  --header "Content-Type: application/json" \
  -d '{"sql":"SELECT 1"}'
```

6\. Test the workload constraint [#6-test-the-workload-constraint]

Try to select another workload.

```bash
curl -X POST 'https://api.rawtree.com/v1/query?database=analytics' \
  --header "Authorization: Bearer $READER_API_KEY" \
  --header "Content-Type: application/json" \
  -d '{"sql":"SELECT 1 SETTINGS workload = '\''batch'\''"}'
```

The API returns HTTP 400 with this response.

```json
{
  "error": "rawtree_error",
  "message": "Code: 452. DB::Exception: Setting workload should not be changed. (SETTING_CONSTRAINT_VIOLATION) (version 26.7.3.88 (official build))",
  "hint": "Check your SQL syntax."
}
```

`READONLY` and `CONST` constrain the individual setting. They do not grant
table access or replace a role grant.

Check the result [#check-the-result]

The query without a workload uses the profile default. The `batch` override
fails because the profile constrains
[`workload`](/docs/reference/sql/settings/session#workload) with `CONST`.

Cleanup [#cleanup]

If the service no longer needs the role key, delete it.

```bash
curl -X DELETE "https://api.rawtree.com/v1/keys/$READER_KEY_ID" \
  --header "Authorization: Bearer $RAWTREE_API_KEY"
```

Drop the profile before you drop the role.

```sql
DROP SETTINGS PROFILE analytics_analyst_profile
```

Drop the role after you delete its keys.

```sql
DROP ROLE analytics_analyst
```

Drop the workload after you drop the profile.

```sql
DROP WORKLOAD analyst_workload ON CLUSTER 'default'
```

Next steps [#next-steps]

* [Access-control concepts](/docs/concepts/access-control)
* [Workload scheduling concepts](/docs/concepts/workload-scheduling)
* [Settings-profile statements](/docs/reference/sql/statements/settings-profile)
