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/groupsroutes must be enabled for the caller's endpoint. They are still rolling out: a 404 from anyzilliz aclcommand 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
Optional: --project-idzilliz acl role principals --all
Optional: --project-id , --page , --page-size Lists the members, groups, and API keys the role is bound to.zilliz acl role delete
Optional: --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
```bash
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=*'SELECTIONpicks which instances the statement covers;*means all, and data resources also accept thedb/collectionform.@cluster=is an optional trailing marker, so an@inside a selection value is left alone. -
JSON file (
--policies-file <path>,-reads stdin), taking thepoliciesarray 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 createwalks through resource, actions, and selection, then prints the equivalent--policyflags 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 aclgoverns 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 theuser-roleskill 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>oracl role principals <role-id>first rather than retrying a failed call. --roletakes 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-idoff 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_rolecreate / modify / delete actions, sorole createis project-only and updating or deleting an org role always fails.role list --type organdrole describework normally. - A resource can exist at both levels with different actions.
project_roleandprojectappear 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-- exceptcreate, which must never carry one.serving_cluster:create,view=in01-ais valid: the selection binds toviewonly. role updatereplaces the policy wholesale. To add one statement, read the current policy withrole describeand 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 aclcommand 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.