ApsaraDB for SelectDB uses a MySQL-compatible permission model to enforce fine-grained access control at the table level. Permissions can be granted directly to users or through roles, and access can be restricted by IP address or domain using whitelists.
Key concepts
| Concept | Parameter | Description |
|---|---|---|
| User identity | user_identity | Identifies a user by a combination of username and host address. Supported formats: username@'userhost' (a specific IP address) and username@['domain'] (a domain name that DNS resolves to one or more IP addresses). |
| Permission | privilege | The right to perform a specific operation on a node, catalog, database, or table. |
| Role | role | A named group of permissions. Assign a role to a user to grant all permissions in that role at once. Changing a role's permissions immediately affects all users assigned to that role. Custom roles are supported. |
| User property | user_property | A set of attributes attached to a username, not a user identity. For example, cmy@'192.%' and cmy@['domain'] share the same user properties because both belong to the user cmy. User properties include connection limits and default import cluster settings. |
User properties belong to the username, not to a specific user identity. Multiple identities sharing the same username share one set of user properties.
Built-in roles
When a SelectDB instance is initialized, two roles and their corresponding users are created automatically.
| Role | Default user | Permissions | Use when |
|---|---|---|---|
operator | root@'%' | NODE_PRIV + ADMIN_PRIV; can log in from any node | Full cluster control, including node management |
admin | admin@'%' | ADMIN_PRIV; all permissions except node changes | Day-to-day administration without node-level access |
You cannot revoke or modify the permissions of automatically created roles or users.
If you forget the password of the admin user and cannot log in to the instance, reset it from the SelectDB console. For more information, see Reset the password of an admin user for an instance.
Permission types
After you create a user, use a privileged account to grant the user permissions to access clusters, databases, and tables. For information about granting cluster access permissions, see Grant a user the permissions to access clusters.
The following table describes the available permission types and the levels at which each can be applied.
| Permission | Applicable levels | Description |
|---|---|---|
| GRANT_PRIV | Global, Catalog, Database, Table | Grants or revokes permissions on users and roles. Also allows creating, deleting, and modifying users and roles. |
| SELECT_PRIV | Global, Catalog, Database, Table | Read-only access to databases and tables. |
| LOAD_PRIV | Global, Catalog, Database, Table | Write access to databases and tables, including LOAD, INSERT, and DELETE operations. |
| ALTER_PRIV | Global, Catalog, Database, Table | Modify databases and tables: rename, create or drop columns, and manage partitions. |
| CREATE_PRIV | Global, Catalog, Database, Table | Create databases, tables, and views. |
| DROP_PRIV | Global, Catalog, Database, Table | Drop databases, tables, and views. |
| USAGE_PRIV | Resource | Use resources. |
Permission levels
Permissions apply to data objects at four levels of scope.
| Level | Notation | Scope |
|---|---|---|
| Global | *.*.* | All tables in all databases across all catalogs |
| Catalog | ctl.*.* | All databases and tables in the specified catalog |
| Database | ctl.db.* | All tables in the specified database |
| Table | ctl.db.tbl | The specified table in the specified database |
Resource permissions use a separate scope (RESOURCE resource_name) and do not map to data levels.
SQL syntax reference
User and role management
| Operation | Keyword | Syntax |
|---|---|---|
| Create a user | CREATE USER | CREATE USER [IF EXISTS] user_identity [IDENTIFIED BY 'password'] [DEFAULT ROLE 'role_name'] [password_policy] |
| Delete a user | DROP USER | DROP USER 'user_identity' |
| Grant permissions | GRANT | GRANT privilege_list ON priv_level TO user_identity [ROLE role_name]<br>GRANT privilege_list ON RESOURCE resource_name TO user_identity [ROLE role_name] |
| Revoke permissions | REVOKE | REVOKE privilege_list ON db_name[.tbl_name] FROM user_identity [ROLE role_name]<br>REVOKE privilege_list ON RESOURCE resource_name FROM user_identity [ROLE role_name] |
| Create a role | CREATE ROLE | CREATE ROLE rol_name; |
| Delete a role | DROP ROLE | DROP ROLE rol_name; |
| Query permissions for a user | SHOW GRANTS | SHOW [ALL] GRANTS [FOR user_identity]; |
| Query all roles | SHOW ROLES | SHOW ROLES |
| Query user properties | SHOW PROPERTY | SHOW PROPERTY [FOR user] [LIKE key] |
| Set user properties | SET PROPERTY | SET PROPERTY [FOR 'user'] 'key' = 'value' [, 'key' = 'value'] |
Password policy options
Use the [password_policy] clause in CREATE USER to configure authentication constraints.
| Policy | Valid values | Default | Description |
|---|---|---|---|
| PASSWORD_HISTORY | n | DEFAULT | 0 (disabled) | Number of previous passwords that cannot be reused. 0 means any historical password is allowed. |
| PASSWORD_EXPIRE | DEFAULT | NEVER | INTERVAL n DAY/HOUR/SECOND | NEVER | How long the password remains valid before expiring. |
| FAILED_LOGIN_ATTEMPTS | n | DEFAULT | No limit | Maximum consecutive failed login attempts before the account is locked. |
| PASSWORD_LOCK_TIME | n DAY/HOUR/SECOND | UNBOUNDED | — | Duration for which the account remains locked after reaching the failed attempt limit. |
ADMIN_PRIV and GRANT_PRIV permissions
Both ADMIN_PRIV and GRANT_PRIV allow granting permissions to other users. Their scope differs.
ADMIN_PRIV: Can only be granted or revoked at the global level. GRANT_PRIV at the global level is equivalent to ADMIN_PRIV—use both with caution.
GRANT_PRIV: Can be scoped to global, catalog, database, or table level. A user with GRANT_PRIV at a given level can only grant permissions within that scope.
The table below shows which permission is required for each administrative operation.
| Operation | Required permission |
|---|---|
| CREATE USER | ADMIN_PRIV, or GRANT_PRIV at global or database level |
| DROP USER | ADMIN_PRIV, or GRANT_PRIV at global level |
| CREATE/DROP ROLE | ADMIN_PRIV, or GRANT_PRIV at global level |
| GRANT/REVOKE (global scope) | ADMIN_PRIV, or GRANT_PRIV at global level |
| GRANT/REVOKE (catalog scope) | GRANT_PRIV at catalog level |
| GRANT/REVOKE (database scope) | GRANT_PRIV at database level |
| GRANT/REVOKE (table scope) | GRANT_PRIV at table level |
| SET PASSWORD (any user) | ADMIN_PRIV, or GRANT_PRIV at global level |
| SET PASSWORD (own identity) | No special permission required |
Users with GRANT_PRIV at a non-global level cannot change the password of an existing user. They can set a password only when creating a new user.
To query your current authenticated user identity, run:
SELECT current_user();To query your actual login identity, run:
SELECT user();All permissions are enforced against current_user, the identity that passed authentication.
For example, if you create a user whose user identity is user1@'192.%' and user1 logs on from the CIDR block 192.168.0.0/16, then current_user is user1@'192.%' and user is user1@'192.168.%'. All permissions apply to the current_user identity.
User properties
User properties control resource limits and behavior for a given username. Set them with SET PROPERTY and query them with SHOW PROPERTY.
| Property | Description |
|---|---|
cpu_resource_limit | Maximum CPU resources for queries. -1 means unlimited. See also: the cpu_resource_limit session variable. |
default_load_cluster | Default cluster for data import. |
exec_mem_limit | Maximum memory for queries. -1 means unlimited. See also: the exec_mem_limit session variable. |
insert_timeout | Timeout period for INSERT operations. |
max_query_instances | Maximum number of query instances the user can run at one time. |
max_user_connections | Maximum number of concurrent connections. |
query_timeout | Timeout period for queries. |
resource_tags | Resource tags. |
sql_block_rules | SQL block rules. Queries matching these rules are rejected. |
When the same setting exists at multiple levels, the system resolves it in this order:
session variable > user property > global variable > default valueExamples
Grant read-only access to a single table
Create a user and grant read-only access to test_db.test_table.
-- Create the user, allowing login from the 172.10.0.0/16 CIDR block
CREATE USER test_user@'172.10.%' IDENTIFIED BY '123456';
-- Grant read, modify, and import permissions on the table
GRANT SELECT_PRIV, ALTER_PRIV, LOAD_PRIV ON test_db.test_table TO 'test_user'@'172.10.%';Revoke permissions from a user
REVOKE SELECT_PRIV ON test_db.* FROM 'test_user'@'172.10.%';Delegate permissions through a role
Create a role, grant it permissions, then assign it to a user.
-- Create the role
CREATE ROLE test_role;
-- Grant import permissions on all tables in test_db to the role
GRANT LOAD_PRIV ON test_db.* TO ROLE 'test_role';
-- Assign the role to a user
GRANT "test_role" TO test_user@'172.10.%';Query and update user properties
-- Query all properties of a user
SHOW PROPERTY FOR 'test_user';
-- Filter by property name
SHOW PROPERTY FOR 'test_user' LIKE '%max_user_connections%';
-- Set a property
SET PROPERTY FOR 'test_user' 'max_user_connections' = '1000';Delete a user or role
DROP USER 'test_user'@'172.10.%';
DROP ROLE test_role;Query permissions for a user
SHOW GRANTS FOR test_user@'%';Best practices
Map user types to permissions
A common pattern for multi-tenant clusters:
| User type | Recommended permissions | Notes |
|---|---|---|
| Cluster administrator | ADMIN_PRIV or GRANT_PRIV (global) | Full control, including node management via operator role |
| R&D engineer | CREATE_PRIV, DROP_PRIV, ALTER_PRIV, LOAD_PRIV, SELECT_PRIV at database level | Manage schema and data for assigned databases |
| Regular user | SELECT_PRIV at database or table level | Read-only access to assigned data |
Use roles to simplify permission management when multiple users share the same permission set.
Delegate grant rights without full admin access
If each database is owned by a different team, create one user per database with GRANT_PRIV scoped to that database. That user can grant permissions on their database to others, without being able to affect other databases.
Simulate a blacklist using priority matching
SelectDB supports whitelists only. To block access from a specific IP range within a broader range, create a more specific user identity with a different password.
For example, test_user1@'192.%' allows login from 192.*. To block the 192.168.0.0/16 range, create test_user2@'192.168.%' with a different password. Because 192.168.% is more specific, it takes priority—users from that range must use the new password and cannot use the original one.
Usage notes
ADMIN_PRIV can only be granted and revoked at the global level.
GRANT_PRIV at the global level is equivalent to ADMIN_PRIV because it allows granting all permissions. Apply it with caution.
All permissions are enforced against
current_user(the authenticated identity), not the actual login identity (user).
FAQ
What do I do if a domain name conflicts with an IP address when I create a user?
Delete the conflicting user with DROP USER, then recreate with the correct identity.
For a domain-vs-IP conflict, create the user with the domain identity first, then grant the domain-level permissions:
CREATE USER test_user@['domain'];
GRANT SELECT_PRIV ON *.* TO test_user@['domain'];If DNS resolves the domain to IP1 and IP2, and you later grant a different permission to test_user@'IP1', that identity gets its own permission set—changing test_user@['domain'] does not affect test_user@'IP1'.
What do I do if two user identities with overlapping IP ranges conflict?
Create the more specific identity. The more specific host pattern takes priority.
CREATE USER test_user@'%' IDENTIFIED BY "12345";
CREATE USER test_user@'192.%' IDENTIFIED BY "abcde";A login attempt from the 192.168.0.0/16 range matches 192.% (higher priority). Using the password 12345 from that range is rejected; use abcde instead.