管理数据库服务账号
数据库服务账号可以很简单,例如为用户单独设置一个用于身份验证的密码或证书。更进阶的用户可能希望创建这样的账户:可使用 SET ROLE 动态修改权限范围,从而无需退出登录或重新加载页面内容,即可在不同 profile 之间快速切换。
概述
SET ROLE 可用于在会话期间动态限定服务账号的权限范围。其原理是将用户的有效权限限制为仅包含已激活角色授予的权限。这种方法有几个优势:
- 服务账号可以被授予多个角色,但仅激活特定查询所需的角色。
- 如果服务账号被入侵,攻击者也只能使用当前激活角色的权限。
- 单个账户可以通过切换角色执行不同任务,而不必为每项任务分别使用不同的凭据。
- 通过修改一个角色,而不是逐个更新用户,可以为整类服务账号统一更新权限。
- 日志可以跟踪执行查询时具体激活的是哪个角色,从而为安全审计提供更清晰的上下文。
实际使用时,请按以下步骤操作:
- 设计用于定义允许边界的角色 (
read_only、maintenance等) - 将这些角色授予服务账号
- 在连接时,通过
SET ROLE(或角色参数) 选择激活的角色,从而限制该会话可执行的操作
设置服务角色
使用 SET ROLE 定义会话边界
在会话开始时,服务账号可以选择启用哪些角色:
或:
SET ROLE 会为当前用户激活角色;生效的特权是所有活动角色特权的并集,再加上直接授予该用户的任何特权。
您也可以停用所有角色:
或激活多个角色:
当前激活的角色可通过 system.current_roles 查看。
通过 HTTP / 以编程方式使用 SET ROLE
如果服务账号通过 HTTP 连接,则不能将 SET ROLE; SELECT ... 作为多语句请求发送。请改为通过查询参数传递角色:
?role=... 等同于在执行该语句前先执行 SET ROLE read_only_role。多个 role 参数的行为类似于 SET ROLE role 1, role 2。
某些驱动程序 (例如适用于 Python 的 ClickHouse Connect) 也提供 role 设置,并会随每个请求一同发送,服务器会将其用作该会话的角色。