ALTER USER <current user> ADD IDENTIFIED WITH sha256_password BY '<random secret>' 的简写形式,
并带有相同的 VALID UNTIL 和
GRANTS 子句,因此标记的行为与当前用户的普通密码一致:
- 它与用户绑定——在
system.query_log和system.processes中显示为该用户,用户被删除后它随之失效, 用户失去访问权限时它也会一并失去; - 可以通过
VALID UNTIL或VALID FOR限制其有效期,通过GRANTS限制其特权; - 可用于任何接受密码的身份验证机制,例如 HTTP 接口的
password参数或 ClickHouse 客户端的--password选项。
CREATE TOKEN 特权,或对当前用户拥有 ALTER USER 特权。
之所以将其设为单独的特权,是因为标记会降低其所属账户的安全级别:使用硬件密钥或证书
完成身份验证的用户,可以借此为同一账户创建一个长期有效的密码。该特权同样授权执行等价的
ALTER USER <current user> ADD IDENTIFIED ... 语句。
结果
该查询返回一行,包含两列:
若要获取不带任何格式的密钥,请使用
FORMAT TSVRaw 进行查询:
VALID UNTIL 与 VALID FOR 子句
用于限制标记的有效期。它们的作用与CREATE USER 中身份验证方法的同名子句完全一致:VALID UNTIL 接受一个绝对的日期和时间,VALID FOR 接受一个时间间隔,该间隔会与查询执行时的当前时间相加。
若两个子句均未指定,标记的有效期取
create_token_default_ttl_seconds 的值,默认为
30 分钟,因此未显式延长有效期的标记均为短期标记。将该设置设为 0,或
写作 VALID UNTIL 'infinity',即可创建永不过期的标记。
示例:
CREATE TOKEN VALID UNTIL '2026-12-31'CREATE TOKEN VALID FOR INTERVAL 30 DAYCREATE TOKEN VALID UNTIL 'infinity'
GRANTS 子句
将使用该标记完成身份验证的会话的访问权限限制为与所列特权的交集。其工作方式与CREATE USER 的 GRANTS 子句完全一致,包括其各项限制——尤其需要注意的是,该限制仅在接收查询的节点上生效,不会传播到集群中的其他节点。该子句绝不会新增任何访问权限:未授予该用户的特权对标记而言同样不可用。若不使用该子句,标记将拥有该用户的全部访问权限。
示例:
CREATE TOKEN GRANTS (SELECT ON db.table)CREATE TOKEN VALID FOR INTERVAL 90 DAY GRANTS (SELECT ON db.table, INSERT ON db.table)
管理标记
标记是用户的一种身份验证方法,因此它会在SHOW CREATE USER 的输出中列出 (含其 VALID UNTIL 和 GRANTS 子句,
但不含密钥) ,也会出现在 system.users 表的 auth_type、auth_params 和 auth_grants 列中。
没有可用于删除单个标记的语句。若要吊销某个用户的全部标记,可替换其
身份验证方法,例如执行 ALTER USER <name> IDENTIFIED WITH ...,或执行
ALTER USER <name> RESET AUTHENTICATION METHODS TO NEW 以仅保留最近添加的那一个。用户同时可拥有的
身份验证方法数量受 max_authentication_methods_per_user 服务器设置的限制。
密钥由查询本身生成并存储,因此,若某个 CREATE TOKEN 的结果始终未能送达
客户端——例如在发送该行时连接中断,或客户端无法打开 INTO OUTFILE 指定的文件——
就会遗留一个无人能用、却仍计入上述上限的身份验证方法。没有任何人持有这样的密钥:它只在查询运行期间存在。
而在开始运行前就被拒绝的查询 (包括 FORMAT 子句指定了不可用格式的查询) 则不会新增任何内容。
CREATE TOKEN 不支持 ON CLUSTER 子句。若集群的访问实体存储在本地,请使用复制式访问存储 (或在每个
节点上执行等效的 ALTER USER ... ADD IDENTIFIED WITH sha256_hash 语句) ,以使标记在整个集群范围内生效。
安全方面的考虑
VALID UNTIL 和 GRANTS 约束的是使用该 标记 进行身份验证的 会话,但并不约束这些 会话 所遗留下来的东西:
- 截止时间仅在 会话 使用该 标记 进行身份验证时检查。对于已经建立的 会话 以及正在运行的查询,标记 过期时并不会将其中断。
- 会话 创建的一切都会比 标记 存活得更久,而能够自行运转的对象会一直运转下去:
可刷新materialized view 会持续刷新,
挂载在流式表引擎 (例如
Kafka、RabbitMQ、NATS或S3Queue) 上的 materialized view 会持续消费, 带有LIFETIME的字典也会持续重新加载,即便 标记 早已过期。 VIEW 是以其DEFINER的权限来完成这些工作的,该 DEFINER 默认就是创建该 VIEW 的用户 —— 用的是该用户的全部权限,而不是 标记 的GRANTS子句为其保留的那部分权限。
SELECT 和 INSERT —— 若希望这些限制真正生效,就不要把 CREATE TABLE、CREATE VIEW、CREATE DICTIONARY 以及 ACCESS MANAGEMENT 特权写进它的 GRANTS 子句。
使用带有 GRANTS 子句的 标记 完成身份验证的 会话 根本无法签发 标记:此类 会话 被禁止为现有用户添加身份验证方法。新身份验证方法的 GRANTS 子句在登录时是与该用户的访问权限取交集,而非与创建该方法的 会话 的权限取交集,否则这就会成为一条扩大限制范围的途径。