Prerequisites
- CLI installed and logged in (see setup skill).
- No cluster context required -- these are control-plane operations.
- The
/v2/roles, /v2/members, and /v2/groups routes must be enabled
for the caller's endpoint. They are still rolling out: a 404 from any
zilliz acl command means the API is not live there yet.
Commands Reference
zilliz acl is a three-level tree -- acl role, acl member, and acl group. It is deliberately absent from zilliz --help and shell completion while the routes roll out, but every command below runs today and every --help under it works.
Roles
# One project's roles: the pre-defined project roles plus that project's
# custom roles. --project-id is required; it is prompted for when omitted.
zilliz acl role list --project-id <project-id>
# Optional: --page <n>, --page-size <n>, --all
# Org roles (--project-id is rejected here: org roles have no project boundary)
zilliz acl role list --type org
zilliz acl role describe <role-id>
# Optional: --project-id <project-id>
zilliz acl role principals <role-id> --all
# Optional: --project-id <project-id>, --page <n>, --page-size <n>
# Lists the members, groups, and API keys the role is bound to.
zilliz acl role delete <role-id>
# Optional: --project-id <project-id>
# Confirms first; pass -y to skip.
--project-id on describe, principals, and delete is the project boundary
of a pre-defined project role, which carries none of its own. A custom role is
addressed by ID alone.
Create and update a role
zilliz acl role create --name <role-name> --project-id <project-id> \
--policy project_member:view \
--policy 'serving_cluster:view,modify=in01-a,in01-b'
# Optional: --description <text>, --policies-file <path>
zilliz acl role update <role-id> --description <text>
# Optional:
# --name <role-name>
# --project-id <project-id>
# --policy <shorthand>
# --policies-file <path>
# -y
Only project roles can be created; the API has no org-role create path.
update replaces the policy wholesale -- it never merges -- and prompts before
shrinking the statement count unless -y is passed.
Writing a policy
Three ways to supply the policy on role create and role update:
Shorthand (--policy, repeatable), validated locally before the request:
RESOURCE:ACTION[,ACTION...][=SELECTION[,SELECTION...]][@cluster=CLUSTER_ID]
--policy project_member:view
--policy 'serving_cluster:view,modify=in01-a,in01-b'
--policy 'serving_cluster_data:read=mydb/*@cluster=in01-abc'
--policy 'volume_data:read,write=*'
SELECTION picks which instances the statement covers; * means all, and
data resources also accept the db/collection form. @cluster= is an
optional trailing marker, so an @ inside a selection value is left alone.
JSON file (--policies-file <path>, - reads stdin), taking the
policies array exactly as the API defines it. Mutually exclusive with
--policy:
[
{ "resourceType": "serving_cluster", "privileges": ["view"], "resources": ["in01-a"] },
{ "resourceType": "project_member", "privileges": ["view"] }
]
Interactive builder: with neither flag on a terminal, role create
walks through resource, actions, and selection, then prints the equivalent
--policy flags so the run can be scripted next time. Off a terminal with
neither flag the command errors instead.
Members
zilliz acl member roles <email|user-id>
zilliz acl member grant <email|user-id> --role <role-id|role-name>
zilliz acl member revoke <email|user-id> --role <role-id|role-name>
# Optional on grant/revoke: --project-id <project-id>; revoke also takes -y
The member argument takes an email or a usr- user ID. An email costs one
extra lookup to resolve; a user ID goes straight through.
Groups
zilliz acl group list
# Optional: --name <text>, --page <n>, --page-size <n>, --all
zilliz acl group members <group-id>
# Optional: --page <n>, --page-size <n>, --all
zilliz acl group roles <group-id>
zilliz acl group grant <group-id> --role <role-id|role-name>
zilliz acl group revoke <group-id> --role <role-id|role-name>
# Optional on grant/revoke: --project-id <project-id>; revoke also takes -y
Groups come from SCIM provisioning; this command tree reads them and manages
their role bindings, it does not create them.
Project scoping
--project-id is prompted for only where the API genuinely requires it, and the
answer is used for that invocation alone -- it is never written to
~/.zilliz/config.
| Command |
Behavior when --project-id is absent |
role create |
prompts on a terminal; errors otherwise |
role list --type project |
prompts on a terminal; errors otherwise |
role list --type org |
not applicable -- the flag is rejected outright |
member/group grant, member/group revoke |
prompts only when the role is a pre-defined project role, which carries no boundary of its own |
the same, given a --role name |
prompts on a terminal when no org role matches the name, since the project-role listing it falls back to requires a project |
role update, role principals |
proceeds without a project |
Action catalog
Every RESOURCE:ACTION pair --policy accepts. A selectable resource
takes =SELECTION on every action except create, which must never carry
one; a resource that is not selectable takes no selection at all.
A resource can appear at both levels with different actions -- read the
Level column before composing a statement.
| Resource |
Level |
Selectable |
Actions |
org_member |
org |
no |
view, create, modify, delete |
group |
org |
no |
view, create, modify, delete |
api_key |
org |
no |
view, create, modify, delete |
org_role |
org |
no |
view, grant |
project_role |
org |
no |
view, create, modify, delete, grant |
project |
org |
no |
view, create |
billing |
org |
no |
view, manage |
authentication |
org |
no |
view, manage |
org_control_ops |
org |
no |
view, modify, delete |
recovery |
org |
no |
view, manage |
project_member |
project |
no |
view, create, modify, delete |
project_role |
project |
no |
view, create, modify, delete, grant |
project |
project |
no |
view, modify, delete |
security |
project |
no |
view, manage |
backup |
project |
no |
view, manage |
observability |
project |
no |
view, manage |
serving_cluster |
project |
yes |
create, view, modify, delete |
on_demand_cluster |
project |
yes |
create, view, modify, delete |
volume |
project |
yes |
create, view, modify, delete, usage |
storage_integration |
project |
yes |
create, view, modify, delete, usage |
model_provider_integration |
project |
yes |
create, view, modify, delete, usage |
kms_integration |
project |
yes |
create, view, modify, delete, usage |
datadog_integration |
project |
yes |
create, view, modify, delete, usage |
serving_cluster_data |
project |
yes |
read, write, all |
on_demand_compute_data |
project |
no |
read, write, all |
volume_data |
project |
yes |
read, write, all |
Guidance
- This is cloud-level RBAC, not Milvus RBAC.
zilliz acl governs who can
act on organizations, projects, clusters, and volumes in Zilliz Cloud. For
database users, roles, and privileges inside a Milvus cluster (Search,
Insert, CreateCollection, ...) use the user-role skill instead. The two
are separate systems and neither grants the other.
- Grant and revoke are not idempotent. Re-granting an existing binding and
revoking an absent one are both rejected by the backend. Check
acl member roles <member> or acl role principals <role-id> first rather
than retrying a failed call.
--role takes an ID or an exact name. A name is matched against the org
roles first and then inside one project, so granting a project role by name
needs --project-id off a terminal. An ambiguous name lists the candidates
instead of guessing -- pass the role ID to resolve it. Prefer IDs in scripts.
- Org roles are read-only here. The backend defines no
org_role
create / modify / delete actions, so role create is project-only and
updating or deleting an org role always fails. role list --type org and
role describe work normally.
- A resource can exist at both levels with different actions.
project_role
and project appear once as an org-level resource and once as a project-level
one. Read the Level column before composing a statement; a level mismatch is
reported as an unknown resource for that level.
- Selection rules are enforced locally before the request. An action on a
selectable resource needs
=SELECTION -- except create, which must never
carry one. serving_cluster:create,view=in01-a is valid: the selection binds
to view only.
role update replaces the policy wholesale. To add one statement, read
the current policy with role describe and resend the full set, including the
statements being kept.
- Deleting a role cascades to its bindings. Confirm the blast radius with
role principals <role-id> before deleting, and tell the user who loses
access.
- The action catalog above is a snapshot of what the backend seeds. It drives
local validation, so when the server rejects a policy this client accepted,
surface the server's message verbatim -- it is the authority, not the table.
- A 404 from any
zilliz acl command means the ACL routes are not enabled on
that endpoint yet. This is a rollout state, not a permissions problem: tell
the user to contact support rather than retrying or changing the command.
1---2name: acl3description: Use when the user wants to manage Zilliz Cloud access control -- custom org or project roles and their policies, granting or revoking a role for an organization member, or binding roles to a SCIM user group. This is cloud-level RBAC over organizations, projects, and clusters -- for database users and privileges inside Milvus see the user-role skill.4---56## Prerequisites781. CLI installed and logged in (see setup skill).92. No cluster context required -- these are control-plane operations.103. The `/v2/roles`, `/v2/members`, and `/v2/groups` routes must be enabled11 for the caller's endpoint. They are still rolling out: a 404 from any12 `zilliz acl` command means the API is not live there yet.1314## Commands Reference1516`zilliz acl` is a three-level tree -- `acl role`, `acl member`, and `acl group`. It is deliberately absent from `zilliz --help` and shell completion while the routes roll out, but every command below runs today and every `--help` under it works.1718### Roles1920```bash21# One project's roles: the pre-defined project roles plus that project's22# custom roles. --project-id is required; it is prompted for when omitted.23zilliz acl role list --project-id <project-id>24# Optional: --page <n>, --page-size <n>, --all2526# Org roles (--project-id is rejected here: org roles have no project boundary)27zilliz acl role list --type org2829zilliz acl role describe <role-id>30# Optional: --project-id <project-id>3132zilliz acl role principals <role-id> --all33# Optional: --project-id <project-id>, --page <n>, --page-size <n>34# Lists the members, groups, and API keys the role is bound to.3536zilliz acl role delete <role-id>37# Optional: --project-id <project-id>38# Confirms first; pass -y to skip.39```4041`--project-id` on `describe`, `principals`, and `delete` is the project boundary42of a *pre-defined* project role, which carries none of its own. A custom role is43addressed by ID alone.4445### Create and update a role4647```bash48zilliz acl role create --name <role-name> --project-id <project-id> \49 --policy project_member:view \50 --policy 'serving_cluster:view,modify=in01-a,in01-b'51# Optional: --description <text>, --policies-file <path>5253zilliz acl role update <role-id> --description <text>54# Optional:55# --name <role-name>56# --project-id <project-id>57# --policy <shorthand>58# --policies-file <path>59# -y60```6162Only **project** roles can be created; the API has no org-role create path.63`update` replaces the policy wholesale -- it never merges -- and prompts before64shrinking the statement count unless `-y` is passed.6566### Writing a policy6768Three ways to supply the policy on `role create` and `role update`:69701. **Shorthand** (`--policy`, repeatable), validated locally before the request:7172 ```73 RESOURCE:ACTION[,ACTION...][=SELECTION[,SELECTION...]][@cluster=CLUSTER_ID]74 ```7576 ```bash77 --policy project_member:view78 --policy 'serving_cluster:view,modify=in01-a,in01-b'79 --policy 'serving_cluster_data:read=mydb/*@cluster=in01-abc'80 --policy 'volume_data:read,write=*'81 ```8283 `SELECTION` picks which instances the statement covers; `*` means all, and84 data resources also accept the `db/collection` form. `@cluster=` is an85 optional trailing marker, so an `@` inside a selection value is left alone.86872. **JSON file** (`--policies-file <path>`, `-` reads stdin), taking the88 `policies` array exactly as the API defines it. Mutually exclusive with89 `--policy`:9091 ```json92 [93 { "resourceType": "serving_cluster", "privileges": ["view"], "resources": ["in01-a"] },94 { "resourceType": "project_member", "privileges": ["view"] }95 ]96 ```97983. **Interactive builder**: with neither flag on a terminal, `role create`99 walks through resource, actions, and selection, then prints the equivalent100 `--policy` flags so the run can be scripted next time. Off a terminal with101 neither flag the command errors instead.102103### Members104105```bash106zilliz acl member roles <email|user-id>107zilliz acl member grant <email|user-id> --role <role-id|role-name>108zilliz acl member revoke <email|user-id> --role <role-id|role-name>109# Optional on grant/revoke: --project-id <project-id>; revoke also takes -y110```111112The member argument takes an email or a `usr-` user ID. An email costs one113extra lookup to resolve; a user ID goes straight through.114115### Groups116117```bash118zilliz acl group list119# Optional: --name <text>, --page <n>, --page-size <n>, --all120121zilliz acl group members <group-id>122# Optional: --page <n>, --page-size <n>, --all123124zilliz acl group roles <group-id>125zilliz acl group grant <group-id> --role <role-id|role-name>126zilliz acl group revoke <group-id> --role <role-id|role-name>127# Optional on grant/revoke: --project-id <project-id>; revoke also takes -y128```129130Groups come from SCIM provisioning; this command tree reads them and manages131their role bindings, it does not create them.132133### Project scoping134135`--project-id` is prompted for only where the API genuinely requires it, and the136answer is used for that invocation alone -- it is never written to137`~/.zilliz/config`.138139| Command | Behavior when `--project-id` is absent |140|---|---|141| `role create` | prompts on a terminal; errors otherwise |142| `role list --type project` | prompts on a terminal; errors otherwise |143| `role list --type org` | not applicable -- the flag is rejected outright |144| `member/group grant`, `member/group revoke` | prompts only when the role is a *pre-defined* project role, which carries no boundary of its own |145| the same, given a `--role` *name* | prompts on a terminal when no org role matches the name, since the project-role listing it falls back to requires a project |146| `role update`, `role principals` | proceeds without a project |147148### Action catalog149150Every `RESOURCE:ACTION` pair `--policy` accepts. A **selectable** resource151takes `=SELECTION` on every action except `create`, which must never carry152one; a resource that is not selectable takes no selection at all.153154A resource can appear at both levels with different actions -- read the155Level column before composing a statement.156157| Resource | Level | Selectable | Actions |158|---|---|---|---|159| `org_member` | org | no | `view`, `create`, `modify`, `delete` |160| `group` | org | no | `view`, `create`, `modify`, `delete` |161| `api_key` | org | no | `view`, `create`, `modify`, `delete` |162| `org_role` | org | no | `view`, `grant` |163| `project_role` | org | no | `view`, `create`, `modify`, `delete`, `grant` |164| `project` | org | no | `view`, `create` |165| `billing` | org | no | `view`, `manage` |166| `authentication` | org | no | `view`, `manage` |167| `org_control_ops` | org | no | `view`, `modify`, `delete` |168| `recovery` | org | no | `view`, `manage` |169| `project_member` | project | no | `view`, `create`, `modify`, `delete` |170| `project_role` | project | no | `view`, `create`, `modify`, `delete`, `grant` |171| `project` | project | no | `view`, `modify`, `delete` |172| `security` | project | no | `view`, `manage` |173| `backup` | project | no | `view`, `manage` |174| `observability` | project | no | `view`, `manage` |175| `serving_cluster` | project | yes | `create`, `view`, `modify`, `delete` |176| `on_demand_cluster` | project | yes | `create`, `view`, `modify`, `delete` |177| `volume` | project | yes | `create`, `view`, `modify`, `delete`, `usage` |178| `storage_integration` | project | yes | `create`, `view`, `modify`, `delete`, `usage` |179| `model_provider_integration` | project | yes | `create`, `view`, `modify`, `delete`, `usage` |180| `kms_integration` | project | yes | `create`, `view`, `modify`, `delete`, `usage` |181| `datadog_integration` | project | yes | `create`, `view`, `modify`, `delete`, `usage` |182| `serving_cluster_data` | project | yes | `read`, `write`, `all` |183| `on_demand_compute_data` | project | no | `read`, `write`, `all` |184| `volume_data` | project | yes | `read`, `write`, `all` |185186## Guidance187188- **This is cloud-level RBAC, not Milvus RBAC.** `zilliz acl` governs who can189 act on organizations, projects, clusters, and volumes in Zilliz Cloud. For190 database users, roles, and privileges *inside* a Milvus cluster (`Search`,191 `Insert`, `CreateCollection`, ...) use the `user-role` skill instead. The two192 are separate systems and neither grants the other.193- **Grant and revoke are not idempotent.** Re-granting an existing binding and194 revoking an absent one are both rejected by the backend. Check195 `acl member roles <member>` or `acl role principals <role-id>` first rather196 than retrying a failed call.197- **`--role` takes an ID or an exact name.** A name is matched against the org198 roles first and then inside one project, so granting a *project* role by name199 needs `--project-id` off a terminal. An ambiguous name lists the candidates200 instead of guessing -- pass the role ID to resolve it. Prefer IDs in scripts.201- **Org roles are read-only here.** The backend defines no `org_role`202 create / modify / delete actions, so `role create` is project-only and203 updating or deleting an org role always fails. `role list --type org` and204 `role describe` work normally.205- **A resource can exist at both levels with different actions.** `project_role`206 and `project` appear once as an org-level resource and once as a project-level207 one. Read the Level column before composing a statement; a level mismatch is208 reported as an unknown resource for that level.209- **Selection rules are enforced locally before the request.** An action on a210 selectable resource needs `=SELECTION` -- except `create`, which must never211 carry one. `serving_cluster:create,view=in01-a` is valid: the selection binds212 to `view` only.213- **`role update` replaces the policy wholesale.** To add one statement, read214 the current policy with `role describe` and resend the full set, including the215 statements being kept.216- **Deleting a role cascades to its bindings.** Confirm the blast radius with217 `role principals <role-id>` before deleting, and tell the user who loses218 access.219- The action catalog above is a snapshot of what the backend seeds. It drives220 local validation, so when the server rejects a policy this client accepted,221 surface the server's message verbatim -- it is the authority, not the table.222- A 404 from any `zilliz acl` command means the ACL routes are not enabled on223 that endpoint yet. This is a rollout state, not a permissions problem: tell224 the user to contact support rather than retrying or changing the command.