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

# 常见访问管理查询

> 本文介绍了定义 SQL 用户和角色的基本方法，以及如何将这些特权和权限应用到数据库、表、行和列上。

<Tip>
  **自管理**

  如果你使用的是自管理 ClickHouse，请参阅 [SQL 用户和角色](/docs/zh/concepts/features/security/access-rights)。
</Tip>

本文介绍定义 SQL 用户和角色的基础知识，以及如何将这些特权和权限应用于数据库、表、行和列。

<div id="admin-user">
  ## 管理员用户
</div>

ClickHouse Cloud 服务有一个管理员用户 `default`，会在服务创建时自动创建。密码会在创建服务时提供，并且拥有 **Admin** 角色的 ClickHouse Cloud 用户可以重置该密码。

当你为 ClickHouse Cloud 服务添加额外的 SQL 用户时，他们需要提供 SQL 用户名和密码。如果你希望他们拥有管理员级别的特权，请为这些新用户分配 `default_role` 角色。例如，添加用户 `clickhouse_admin`：

```sql theme={null}
CREATE USER IF NOT EXISTS clickhouse_admin
IDENTIFIED WITH sha256_password BY 'P!@ssword42!';
```

```sql theme={null}
GRANT default_role TO clickhouse_admin;
```

<Note>
  使用 SQL 控制台时，你的 SQL 语句不会以 `default` 用户身份执行。相反，这些语句会以名为 `sql-console:${cloud_login_email}` 的用户身份执行，其中 `cloud_login_email` 是当前运行查询的用户的电子邮件地址。

  这些自动生成的 SQL 控制台用户具有 `default` 角色。
</Note>

<div id="passwordless-authentication">
  ## 无密码身份验证
</div>

SQL 控制台提供两个角色：`sql_console_admin`，其 权限 与 `default_role` 完全一致；以及 `sql_console_read_only`，具有只读权限。

Admin 用户默认会被分配 `sql_console_admin` 角色，因此对他们来说无需做任何更改。不过，`sql_console_read_only` 角色使非 Admin 用户也可以被授予任意 instance 的只读或完全访问权限。此类访问需要由 Admin 配置。可以使用 `GRANT` 或 `REVOKE` 命令调整这些角色，以更好地满足特定 instance 的需求，并且对这些角色所做的任何修改都会被保留。

<div id="granular-access-control">
  ### 细粒度访问控制
</div>

此访问控制功能也支持手动配置到用户级粒度。为用户分配新的 `sql_console_*` 角色之前，应先创建与命名空间 `sql-console-role:<email>` 对应的 SQL 控制台用户专用数据库角色。例如：

```sql theme={null}
CREATE ROLE OR REPLACE sql-console-role:<email>;
GRANT <some grants> TO sql-console-role:<email>;
```

检测到匹配的角色后，系统会将其分配给用户，而不是默认的样板角色。这也支持更复杂的访问控制配置，例如创建 `sql_console_sa_role` 和 `sql_console_pm_role` 这类角色，并将其授予特定用户。例如：

```sql theme={null}
CREATE ROLE OR REPLACE sql_console_sa_role;
GRANT <whatever level of access> TO sql_console_sa_role;
CREATE ROLE OR REPLACE sql_console_pm_role;
GRANT <whatever level of access> TO sql_console_pm_role;
CREATE ROLE OR REPLACE `sql-console-role:christoph@clickhouse.com`;
CREATE ROLE OR REPLACE `sql-console-role:jake@clickhouse.com`;
CREATE ROLE OR REPLACE `sql-console-role:zach@clickhouse.com`;
GRANT sql_console_sa_role to `sql-console-role:christoph@clickhouse.com`;
GRANT sql_console_sa_role to `sql-console-role:jake@clickhouse.com`;
GRANT sql_console_pm_role to `sql-console-role:zach@clickhouse.com`;
```

<div id="test-admin-privileges">
  ## 测试管理员权限
</div>

退出 `default` 用户登录，然后使用 `clickhouse_admin` 用户重新登录。

以下所有操作都应成功：

```sql theme={null}
SHOW GRANTS FOR clickhouse_admin;
```

```sql theme={null}
CREATE DATABASE db1
```

```sql theme={null}
CREATE TABLE db1.table1 (id UInt64, column1 String) ENGINE = MergeTree() ORDER BY id;
```

```sql theme={null}
INSERT INTO db1.table1 (id, column1) VALUES (1, 'abc');
```

```sql theme={null}
SELECT * FROM db1.table1;
```

```sql theme={null}
DROP TABLE db1.table1;
```

```sql theme={null}
DROP DATABASE db1;
```

<div id="non-admin-users">
  ## 非管理员用户
</div>

用户应具备必要的权限，而不应全部为管理员用户。本文档其余部分将提供示例场景及所需角色。

<div id="preparation">
  ### 准备工作
</div>

创建以下表和用户，供后续示例使用。

<div id="creating-a-sample-database-table-and-rows">
  #### 创建示例数据库、表和数据行
</div>

<Steps>
  <Step title="创建测试数据库" id="create-a-test-database">
    ```sql theme={null}
    CREATE DATABASE db1;
    ```
  </Step>

  <Step title="创建表" id="create-a-table">
    ```sql theme={null}
    CREATE TABLE db1.table1 (
       id UInt64,
       column1 String,
       column2 String
    )
    ENGINE MergeTree
    ORDER BY id;
    ```
  </Step>

  <Step title="向表中插入示例行" id="populate">
    ```sql theme={null}
    INSERT INTO db1.table1
       (id, column1, column2)
    VALUES
       (1, 'A', 'abc'),
       (2, 'A', 'def'),
       (3, 'B', 'abc'),
       (4, 'B', 'def');
    ```
  </Step>

  <Step title="验证表" id="verify">
    ```sql title="查询" theme={null}
    SELECT *
    FROM db1.table1
    ```

    ```response title="响应" theme={null}
    Query id: 475015cc-6f51-4b20-bda2-3c9c41404e49

    ┌─id─┬─column1─┬─column2─┐
    │  1 │ A       │ abc     │
    │  2 │ A       │ def     │
    │  3 │ B       │ abc     │
    │  4 │ B       │ def     │
    └────┴─────────┴─────────┘
    ```
  </Step>

  <Step title={<>创建 <code>column_user</code></>} id="create-a-user-with-restricted-access-to-columns">
    创建一个普通用户，用于演示如何限制对某些列的访问：

    ```sql theme={null}
    CREATE USER column_user IDENTIFIED BY 'password';
    ```
  </Step>

  <Step title={<>创建 <code>row_user</code></>} id="create-a-user-with-restricted-access-to-rows-with-certain-values">
    创建一个普通用户，用于演示如何限制对具有特定值的行的访问：

    ```sql theme={null}
    CREATE USER row_user IDENTIFIED BY 'password';
    ```
  </Step>
</Steps>

<div id="creating-roles">
  #### 创建角色
</div>

通过这组示例，您将了解如何：

* 创建具有不同权限的角色，例如针对列和行的角色
* 为角色授予权限
* 将用户分配给各个角色

角色用于为特定权限定义用户组，而不是逐个管理用户。

<Steps>
  <Step title={<>创建一个角色，将该角色的用户限制为只能查看数据库 <code>db1</code> 中 <code>table1</code> 表的 <code>column1</code>：</>} id="create-column-role">
    ```sql theme={null}
    CREATE ROLE column1_users;
    ```
  </Step>

  <Step title={<>设置权限，允许查看 <code>column1</code></>} id="set-column-privileges">
    ```sql theme={null}
    GRANT SELECT(id, column1) ON db1.table1 TO column1_users;
    ```
  </Step>

  <Step title={<>将用户 <code>column_user</code> 添加到角色 <code>column1_users</code></>} id="add-column-user-to-role">
    ```sql theme={null}
    GRANT column1_users TO column_user;
    ```
  </Step>

  <Step title={<>创建一个角色，将该角色的用户限制为只能查看选定的行；在本例中，仅能查看 <code>column1</code> 中包含 <code>A</code> 的行</>} id="create-row-role">
    ```sql theme={null}
    CREATE ROLE A_rows_users;
    ```
  </Step>

  <Step title={<>将 <code>row_user</code> 添加到角色 <code>A_rows_users</code></>} id="add-row-user-to-role">
    ```sql theme={null}
    GRANT A_rows_users TO row_user;
    ```
  </Step>

  <Step title={<>创建一条策略，仅允许查看 <code>column1</code> 值为 <code>A</code> 的行</>} id="create-row-policy">
    ```sql theme={null}
    CREATE ROW POLICY A_row_filter ON db1.table1 FOR SELECT USING column1 = 'A' TO A_rows_users;
    ```
  </Step>

  <Step title="为数据库和表设置权限" id="set-db-table-privileges">
    ```sql theme={null}
    GRANT SELECT(id, column1, column2) ON db1.table1 TO A_rows_users;
    ```
  </Step>

  <Step title="为其他角色授予显式权限，使其仍可访问所有行" id="grant-other-roles-access">
    ```sql theme={null}
    CREATE ROW POLICY allow_other_users_filter 
    ON db1.table1 FOR SELECT USING 1 TO clickhouse_admin, column1_users;
    ```

    <Note>
      将策略附加到表后，系统会应用该策略，只有策略中定义的用户和角色才能对该表执行操作，其他所有用户和角色都将被拒绝执行任何操作。为了避免将这种限制性的行策略应用到其他用户，必须另外定义一条策略，以允许其他用户和角色保留常规访问权限或其他类型的访问权限。
    </Note>
  </Step>
</Steps>

<div id="verification">
  ## 验证
</div>

<div id="testing-role-privileges-with-column-restricted-user">
  ### 使用列受限用户测试角色权限
</div>

<Steps>
  <Step title={<>使用 <code>clickhouse_admin</code> 用户登录 ClickHouse 客户端</>} id="login-admin-user">
    ```bash theme={null}
    clickhouse-client --user clickhouse_admin --password password
    ```
  </Step>

  <Step title="验证管理员用户对数据库、表和所有行的访问权限。" id="verify-admin-access">
    ```sql theme={null}
    SELECT *
    FROM db1.table1
    ```

    ```response theme={null}
    Query id: f5e906ea-10c6-45b0-b649-36334902d31d

    ┌─id─┬─column1─┬─column2─┐
    │  1 │ A       │ abc     │
    │  2 │ A       │ def     │
    │  3 │ B       │ abc     │
    │  4 │ B       │ def     │
    └────┴─────────┴─────────┘
    ```
  </Step>

  <Step title={<>使用 <code>column_user</code> 用户登录 ClickHouse 客户端</>} id="login-column-user">
    ```bash theme={null}
    clickhouse-client --user column_user --password password
    ```
  </Step>

  <Step title={<>测试使用所有列执行 <code>SELECT</code></>} id="test-select-all-columns">
    ```sql theme={null}
    SELECT *
    FROM db1.table1
    ```

    ```response theme={null}
    Query id: 5576f4eb-7450-435c-a2d6-d6b49b7c4a23

    0 rows in set. Elapsed: 0.006 sec.

    Received exception from server (version 22.3.2):
    Code: 497. DB::Exception: Received from localhost:9000. 
    DB::Exception: column_user: Not enough privileges. 
    To execute this query it's necessary to have grant 
    SELECT(id, column1, column2) ON db1.table1. (ACCESS_DENIED)
    ```

    <Note>
      由于查询指定了所有列，而该用户仅有对 `id` 和 `column1` 的访问权限，因此访问被拒绝。
    </Note>
  </Step>

  <Step title={<>验证仅查询已指定且允许访问的列的 <code>SELECT</code> 查询：</>} id="verify-allowed-columns">
    ```sql theme={null}
    SELECT
        id,
        column1
    FROM db1.table1
    ```

    ```response theme={null}
    Query id: cef9a083-d5ce-42ff-9678-f08dc60d4bb9

    ┌─id─┬─column1─┐
    │  1 │ A       │
    │  2 │ A       │
    │  3 │ B       │
    │  4 │ B       │
    └────┴─────────┘
    ```
  </Step>
</Steps>

<div id="testing-role-privileges-with-row-restricted-user">
  ### 使用行级受限用户测试角色权限
</div>

<Steps>
  <Step title={<>使用 <code>row_user</code> 登录 ClickHouse 客户端</>} id="login-row-user">
    ```bash theme={null}
    clickhouse-client --user row_user --password password
    ```
  </Step>

  <Step title="查看可访问的行" id="view-available-rows">
    ```sql theme={null}
    SELECT *
    FROM db1.table1
    ```

    ```response theme={null}
    Query id: a79a113c-1eca-4c3f-be6e-d034f9a220fb

    ┌─id─┬─column1─┬─column2─┐
    │  1 │ A       │ abc     │
    │  2 │ A       │ def     │
    └────┴─────────┴─────────┘
    ```

    <Note>
      确认只返回上述两行，`column1` 中值为 `B` 的行应被排除。
    </Note>
  </Step>
</Steps>

<div id="modifying-users-and-roles">
  ## 修改用户和角色
</div>

可以为用户分配多个角色，以组合获得所需的权限。使用多个角色时，系统会将这些角色合并后再判定权限，最终效果是各角色的权限会累加生效。

例如，如果 `role1` 只允许查询 `column1`，而 `role2` 允许查询 `column1` 和 `column2`，那么该用户将有权访问这两列。

<Steps>
  <Step title="使用管理员账户，创建一个按行和列限制且带默认角色的新用户" id="create-restricted-user">
    ```sql theme={null}
    CREATE USER row_and_column_user IDENTIFIED BY 'password' DEFAULT ROLE A_rows_users;
    ```
  </Step>

  <Step title={<>移除 <code>A_rows_users</code> 角色先前的权限</>} id="remove-prior-privileges">
    ```sql theme={null}
    REVOKE SELECT(id, column1, column2) ON db1.table1 FROM A_rows_users;
    ```
  </Step>

  <Step title={<>仅允许 <code>A_row_users</code> 角色查询 <code>column1</code></>} id="allow-column1-select">
    ```sql theme={null}
    GRANT SELECT(id, column1) ON db1.table1 TO A_rows_users;
    ```
  </Step>

  <Step title={<>使用 <code>row_and_column_user</code> 登录 ClickHouse 客户端</>} id="login-restricted-user">
    ```bash theme={null}
    clickhouse-client --user row_and_column_user --password password;
    ```
  </Step>

  <Step title="使用所有列进行测试：" id="test-all-columns-restricted">
    ```sql theme={null}
    SELECT *
    FROM db1.table1
    ```

    ```response theme={null}
    Query id: 8cdf0ff5-e711-4cbe-bd28-3c02e52e8bc4

    0 rows in set. Elapsed: 0.005 sec.

    Received exception from server (version 22.3.2):
    Code: 497. DB::Exception: Received from localhost:9000. 
    DB::Exception: row_and_column_user: Not enough privileges. 
    To execute this query it's necessary to have grant 
    SELECT(id, column1, column2) ON db1.table1. (ACCESS_DENIED)
    ```
  </Step>

  <Step title="使用受限的允许列进行测试：" id="test-limited-columns">
    ```sql theme={null}
    SELECT
        id,
        column1
    FROM db1.table1
    ```

    ```response theme={null}
    Query id: 5e30b490-507a-49e9-9778-8159799a6ed0

    ┌─id─┬─column1─┐
    │  1 │ A       │
    │  2 │ A       │
    └────┴─────────┘
    ```
  </Step>
</Steps>

<div id="troubleshooting">
  ## 故障排查
</div>

在某些情况下，权限之间会相互叠加或组合，导致出现意料之外的结果。以下命令可用于通过管理员账户缩小排查范围

<div id="listing-the-grants-and-roles-for-a-user">
  ### 列出用户的授权和角色
</div>

```sql theme={null}
SHOW GRANTS FOR row_and_column_user
```

```response theme={null}
Query id: 6a73a3fe-2659-4aca-95c5-d012c138097b

┌─GRANTS FOR row_and_column_user───────────────────────────┐
│ GRANT A_rows_users, column1_users TO row_and_column_user │
└──────────────────────────────────────────────────────────┘
```

<div id="list-roles-in-clickhouse">
  ### 查看 ClickHouse 中的角色
</div>

```sql theme={null}
SHOW ROLES
```

```response theme={null}
Query id: 1e21440a-18d9-4e75-8f0e-66ec9b36470a

┌─name────────────┐
│ A_rows_users    │
│ column1_users   │
└─────────────────┘
```

<div id="display-the-policies">
  ### 查看策略
</div>

```sql theme={null}
SHOW ROW POLICIES
```

```response theme={null}
Query id: f2c636e9-f955-4d79-8e80-af40ea227ebc

┌─name───────────────────────────────────┐
│ A_row_filter ON db1.table1             │
│ allow_other_users_filter ON db1.table1 │
└────────────────────────────────────────┘
```

<div id="view-how-a-policy-was-defined-and-current-privileges">
  ### 查看策略定义及当前权限
</div>

```sql theme={null}
SHOW CREATE ROW POLICY A_row_filter ON db1.table1
```

```response theme={null}
Query id: 0d3b5846-95c7-4e62-9cdd-91d82b14b80b

┌─CREATE ROW POLICY A_row_filter ON db1.table1────────────────────────────────────────────────┐
│ CREATE ROW POLICY A_row_filter ON db1.table1 FOR SELECT USING column1 = 'A' TO A_rows_users │
└─────────────────────────────────────────────────────────────────────────────────────────────┘
```

<div id="example-commands-to-manage-roles-policies-and-users">
  ## 管理角色、策略和用户的示例命令
</div>

以下命令可用于：

* 删除权限
* 删除策略
* 将用户从角色中移除
* 删除用户和角色
  <br />

<Tip>
  请以管理员用户或 `default` 用户身份运行这些命令
</Tip>

<div id="remove-privilege-from-a-role">
  ### 撤销角色权限
</div>

```sql theme={null}
REVOKE SELECT(column1, id) ON db1.table1 FROM A_rows_users;
```

<div id="delete-a-policy">
  ### 删除策略
</div>

```sql theme={null}
DROP ROW POLICY A_row_filter ON db1.table1;
```

<div id="unassign-a-user-from-a-role">
  ### 取消向用户分配角色
</div>

```sql theme={null}
REVOKE A_rows_users FROM row_user;
```

<div id="delete-a-role">
  ### 删除角色
</div>

```sql theme={null}
DROP ROLE A_rows_users;
```

<div id="delete-a-user">
  ### 删除用户
</div>

```sql theme={null}
DROP USER row_user;
```

<div id="summary">
  ## 总结
</div>

本文介绍了创建 SQL 用户和角色的基础知识，并说明了如何为用户和角色设置及修改权限。有关各项内容的更多信息，请参阅我们的用户指南和参考文档。
