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

# Roles and bindings

> Create custom roles and assign access to members and service accounts

Use `mthr iam roles` to define access and `mthr iam bindings` to assign it.
A **role version** is an immutable set of actions with its own role ID.
A **binding** assigns that exact role ID to one member or service account.
The tenant comes from your authenticated session.

Sign in as an **active tenant owner** for this administration workflow. Role
listing and mutations require ownership; owners can review tenant-wide direct
and effective grants. A custom role cannot delegate role or binding administration, service
account creation or deactivation, or service-account credential administration.
Built-in roles are protected: you can inspect them, but cannot change or disable
them. Service accounts can receive enabled custom roles belonging to their own
tenant; they cannot receive built-in roles, including Owners.

## Find the IDs you need

List identities and role versions:

```bash theme={null}
mthr members ls
mthr service-accounts ls
mthr iam roles ls
```

Copy a member ID, service-account ID, or role ID from the corresponding list.
In the examples below, replace uppercase placeholders with those IDs.
Role listing includes built-in roles and disabled custom versions. Inspect a
version before granting it:

```bash theme={null}
mthr iam roles get ROLE_ID
```

The result includes its exact actions, version number, selected action catalog,
state, and built-in status. Choose an enabled version for a new binding.

## Create a custom role

Role keys use lowercase letters, digits, and hyphens, cannot begin with a hyphen,
and have a maximum length of 100 characters. A new key starts at version 1.
This example creates a role with one exact action:

```bash theme={null}
mthr iam roles create tenant-reader \
  --action directory:GetTenant \
  --reason "Read tenant details for project automation" \
  --ticket ACCESS-201
```

To include multiple actions, repeat `--action`:

```bash theme={null}
mthr iam roles create tenant-member-reader \
  --action directory:GetTenant \
  --action directory:GetMember \
  --reason "Read tenant and member details" \
  --ticket ACCESS-202
```

You can also use `--action directory:GetTenant,directory:GetMember`. Action IDs are exact
and case-sensitive. Wildcards, duplicate actions, unknown actions, and reserved
administration actions are rejected. All requested actions must be present in
one finalized action catalog.

Keep the `role_id` returned by the command. The CLI generates it automatically;
`--role-id` is available when you need to supply a unique ID yourself. Creating a
role does not assign access to anyone.

Mount Thor automatically selects the **most recently finalized action catalog
containing every requested action**. No catalog flag is needed. If no compatible
finalized catalog exists, creation fails validation.

<Accordion title="Advanced: pin an action catalog version">
  `--version` numbers successive definitions of your role key. An **action catalog
  version** identifies the finalized set of action definitions used to validate
  that role. These are separate versions. Mount Thor stores the selected catalog
  on the role version and returns it as `catalog_version`.

  To reproduce a specific catalog selection, provide an explicit override. Replace
  `CATALOG_VERSION` with the finalized catalog you intend to use, for example one
  returned by `roles get`:

  ```bash theme={null}
  mthr iam roles create pinned-tenant-reader \
    --action directory:GetTenant \
    --catalog-version CATALOG_VERSION \
    --reason "Pin the reviewed action definitions" \
    --ticket ACCESS-203
  ```

  An explicit catalog must also contain every requested action. Existing role
  versions keep their original catalogs when newer catalogs are finalized.
  An idempotent API retry of the same request keeps its original selection too.
</Accordion>

Running `mthr iam roles create` again creates a new request with a new
idempotency key; after an uncertain response, use `roles ls` and `roles get` to
check whether the version was created before submitting another command.

## Assign a role

Grant a role version to an active member:

```bash theme={null}
mthr iam bindings grant \
  --member-id MEMBER_ID \
  --role-id ROLE_ID \
  --reason "Project read access" \
  --ticket ACCESS-204
```

Or grant an enabled tenant-local custom role to an active service account:

```bash theme={null}
mthr iam bindings grant \
  --service-account-id SERVICE_ACCOUNT_ID \
  --role-id ROLE_ID \
  --reason "Automation read access" \
  --ticket ACCESS-205
```

Supply exactly one of `--member-id` and `--service-account-id`. Keep the binding
ID returned by the grant, or find it later with `bindings ls`.

Service accounts support custom roles with one or multiple admitted actions,
subject to the same tenant, active-account, enabled-role, and reserved-action
checks. Creating or assigning a role does not issue a credential; see
[Service accounts](/platform/service-accounts).

Role creation, role disable, binding grant, and binding revoke each require
nonblank `--reason` and `--ticket` values. Use a meaningful audit reason and your
organization's ticket or change reference. Read commands do not require these
flags.

## Review assignments and effective access

```bash theme={null}
mthr iam bindings ls
mthr iam bindings ls --member-id MEMBER_ID
mthr iam bindings ls --service-account-id SERVICE_ACCOUNT_ID
mthr iam bindings ls --service-account-id SERVICE_ACCOUNT_ID --json
```

**Direct grants** show the binding ID, subject, role ID, and state, including
disabled bindings. **Effective grants** show the actions currently supplied by
active grants, with the role and binding IDs that provide each action. Use these
IDs to identify the assignment you intend to revoke. All IAM commands support
`--json`; grant lists retain both views and `authorization_generation`.

## Replace a role version

To change a role's actions, create the next version for the same key:

```bash theme={null}
mthr iam roles create tenant-reader \
  --version 2 \
  --action directory:GetTenant \
  --action directory:GetMember \
  --reason "Add member details to tenant-reader" \
  --ticket ACCESS-206
```

Versions must be consecutive. Inspect `roles ls` first if the key already exists.
The new version receives a new role ID. **Existing bindings remain attached to
the old version**; creating version 2 does not update or revoke version 1.

Grant the new role ID to each intended subject, then revoke its obsolete binding
ID. During that transition, both assignments can supply access. If access must
be removed before replacement, revoke the old binding first and allow for an
interruption while the replacement takes effect.

## Revoke a binding

Use the binding ID from the direct-grants list:

```bash theme={null}
mthr iam bindings revoke BINDING_ID \
  --reason "Project access ended" \
  --ticket ACCESS-207
```

This disables one assignment and keeps its history visible. Other active
bindings may still grant the same action. Review the subject's effective grants
afterward to see whether another assignment provides access.
Mount Thor refuses revocation of the last active owner binding.

## Disable a role version

To retire a custom version for every subject bound to it:

```bash theme={null}
mthr iam roles disable ROLE_ID \
  --reason "Retire this role version" \
  --ticket ACCESS-208
```

Disabling removes the access supplied by that version to both members and
service accounts. It does not disable other versions of the same role key or
erase binding history, and other roles can still supply the same actions.

The existing `mthr members grant`, `mthr members grants`, `mthr members revoke`,
and `mthr service-accounts grants` commands remain available. `mthr iam grants`
is an alias for `mthr iam bindings`; `list` aliases `ls`.
