KingbaseES 用户权限隔离功能实现与实战
KingbaseES 提供用户权限隔离功能,通过行级安全策略(RLS)实现普通用户仅能访问授权对象。开启后,系统表自动配置 RLS 策略过滤未授权对象。支持启用/禁用命令及自定义权限扩展(如 DUMPTABLE)。需严格控制 BYPASSRLS 属性,确保数据库簇状态一致。该功能提升数据安全性,降低迁移风险。

KingbaseES 提供用户权限隔离功能,通过行级安全策略(RLS)实现普通用户仅能访问授权对象。开启后,系统表自动配置 RLS 策略过滤未授权对象。支持启用/禁用命令及自定义权限扩展(如 DUMPTABLE)。需严格控制 BYPASSRLS 属性,确保数据库簇状态一致。该功能提升数据安全性,降低迁移风险。

KingbaseES 的用户权限隔离功能,核心目标是让普通用户仅能查看和操作已获得授权的数据库对象,未授权对象对用户不可见——既无法通过查询语句获取,也无法在数据库工具中看到,从根源上杜绝越权访问风险。
这个功能主要依赖 security_utils 插件实现,开启后会对数据库中具有 ACL(访问控制列表)字段的系统表统一配置 RLS 策略,通过 RLS 筛选逻辑过滤未授权对象,确保数据访问的安全性与合规性。
针对数据库级开启或禁用用户权限隔离功能,只需两行代码即可解决。
-- 启用用户权限隔离
ALTER DATABASE database_name ENABLE OBJECT ISOLATION;
-- 禁用用户权限隔离
ALTER DATABASE database_name DISABLE OBJECT ISOLATION;
该功能实现主要依赖行级安全策略(Row-Level Security, RLS),通过修改数据库状态,为当前数据库具有 ACL 字段的系统表统一添加配置好的 RLS,通过 RLS 筛选以实现普通用户只能查看有权访问的对象(表、函数、视图、字段等)的目的。
KingbaseES 为统一管理 RLS 策略,定义了 CreateRLSForSystemTable 结构体与 CreateRLSForSystemTableList 列表,以此用于记录每条 RLS 的属性与全局策略集合:
// CreateRLSForSystemTable 结构体:记录单条 RLS 策略属性
typedef struct CreateRLSForSystemTable {
int sysTabID; // 系统表 OID
char* relName; // 系统表名称
char* policyName; // RLS 策略名称
char* funcName; // 权限判断函数
char* schemaName; // 权限判断函数所属模式
char* relColname1; // 权限判断函数参数 1
char* relColname2; // 权限判断函数参数 2
char* privType; // 支持的权限列表(如 select,insert,update)
} CreateRLSForSystemTable;
// CreateRLSForSystemTableList 列表:维护所有系统表的 RLS 策略
static const CreateRLSForSystemTable CreateRLSForSystemTableList[SYSTABLE_POLICY_MAXNUM] = {
// 为 sys_class 表(rel)创建 RLS 策略,依赖 is_object_inclass 函数
{RelationRelationId,"rel","sys_class_isolation_object_rls","is_object_inclass","security_utils","currentuser","oid","select,insert,update,delete,truncate,references,trigger,dumptable"},
// 为 sys_database 表(db)创建 RLS 策略,依赖 has_database_privilege 函数
{DatabaseRelationId,"db","sys_database_isolation_object_rls","has_database_privilege","pg_catalog","current_user","datname","connect,create,temporary,temp"},
// 为触发器表(_trigger)创建 RLS 策略,依赖 has_trigger_privilege 函数
{TriggerRelationId,"trge","sys_trigger_isolation_object_rls","has_trigger_privilege","security_utils","currentuser","oid","execute"}
};
对于不同数据库对象的权限校验,依赖专属的权限判断函数,比如:
以 has_class_privilege_name_id 为例,其核心逻辑是校验用户输入的权限是否在预设权限集合内,避免非法权限请求:
Datum has_class_privilege_name_id(KDB_FUNCTION_ARGS) {
Name username = KDB_GETARG_NAME(0); // 用户名
Oid classoid = KDB_GETARG_OID(1); // 对象 OID
text* priv_type_text = KDB_GETARG_TEXT_PP(2); // 请求权限类型
char* priv_type_string = text_to_cstring(priv_type_text);
// 预设表/序列支持的权限集合(含新增的 DUMPTABLE 权限)
char* priv_type_string_table = "select,insert,update,delete,truncate,references,trigger,dumptable";
char* priv_type_string_sequence = "select,update,usage";
char priv_type[1024] = {'0'};
// 校验请求权限是否合法
if (strstr(priv_type_string, priv_type_string_table) == NULL && strstr(priv_type_string, priv_type_string_sequence) == NULL) {
ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("unrecognized privilege type: %s", priv_type_string)));
}
// 后续权限校验逻辑(略)
KDB_RETURN_BOOL(true);
}
下面我们就以'普通用户 u1 访问表 t1'为例,演示权限隔离的启用、效果验证与权限授予流程:
-- 1. 以 system 用户连接数据库,创建测试表 t1
test=# create table t1(a int);
CREATE TABLE
-- 2. 创建普通用户 u1(密码需符合复杂度要求)
test=# create user u1 with password '12345678ab';
CREATE ROLE
-- 以 u1 身份连接数据库,查询表 t1
test=# \c -u1
您现在以用户名"u1"连接到数据库"test"
-- 查询 sys_class 系统表,可看到 t1(未隔离时无权限限制)
test=> select oid, relname from sys_class where relname = 't1';
oid | relname
-----+---------
16638| t1
(1 行记录)
-- 1. 切换回 system 用户,启用权限隔离
test=> \c -system
您现在以用户名"system"连接到数据库"test"
test=# alter database test enable object isolation;
ALTER DATABASE
-- 2. 再次切换为 u1,查询 t1(未授权,结果为空)
test=# \c -u1
您现在以用户名"u1"连接到数据库"test"
test=> select oid, relname from sys_class where relname = 't1';
oid | relname
-----+---------
(0 行记录)
-- 1. system 用户授予 u1 表 t1 的 SELECT 权限
test=> \c -system
test=# grant SELECT on TABLE t1 to u1;
GRANT
-- 2. u1 再次查询,可正常看到 t1
test=# \c -u1
test=> select oid, relname from sys_class where relname = 't1';
oid | relname
-----+---------
16638| t1
(1 行记录)
在实际应用的开发业务中经常有自定义隔离权限(如 DUMPTABLE)或新增隔离对象(如触发器 TRIGGER)等需求,对于这种情况 KingbaseES 配套了完整且成熟的开发实现流程。
需求:为表对象新增 DUMPTABLE 权限,用户需获得该权限才能查看表并执行备份操作。
// 为 sys_class 表的 RLS 策略添加 DUMPTABLE 权限
{RelationRelationId,"rel","sys_class_isolation_object_rls","is_object_inclass","security_utils","currentuser","oid","select,insert,update,delete,truncate,references,trigger,dumptable"}
-- system 授予 u1 表 t1 的 DUMPTABLE 权限
test=# grant DUMPTABLE on TABLE t1 to u1;
GRANT
-- u1 查询 t1,可正常显示
test=> \c -u1
test=> select oid, relname from sys_class where relname = 't1';
oid | relname
-----+---------
16638| t1
(1 行记录)
需求:将触发器纳入权限隔离范围,未授权用户无法查看触发器对象。
Datum has_trigger_privilege(KDB_FUNCTION_ARGS) {
Name username = KDB_GETARG_NAME(0);
Oid trigid = KDB_GETARG_OID(1);
text* priv_type_text = KDB_GETARG_TEXT_PP(2);
Relation tgrel = table_open(TriggerRelationId, LockAccessShare);
SysScanDesc tgscan;
HeapTuple ht_trig;
ScanKeyData skey[1];
// 定位触发器对象
ScanKeyInit(&skey[0], Anum__trigger_oid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(trigid));
tgscan = systable_beginscan(tgrel, TriggerOidIndexId, true, NULL, 1, skey);
ht_trig = systable_getnext(tgscan);
// 无对应触发器,返回无权限
if (!HeapTupleIsValid(ht_trig)) {
systable_endscan(tgscan);
table_close(tgrel, LockAccessShare);
KDB_RETURN_BOOL(false);
}
// 校验用户对触发器依赖表的权限(核心逻辑)
Form__trigger trigrec = (Form__trigger)GETSTRUCT(ht_trig);
if (!OidIsValid(trigrec->tgrelid) || !has_table_privilege(username, trigrec->tgrelid, "trigger")) {
systable_endscan(tgscan);
table_close(tgrel, LockAccessShare);
KDB_RETURN_BOOL(false);
}
KDB_RETURN_BOOL(true);
}
{TriggerRelationId,"trge","sys_trigger_isolation_object_rls","has_trigger_privilege","security_utils","currentuser","oid","execute"}
KingbaseES 通过权限隔离功能对权限控制进行细粒度化管理,降低企业迁移成本和技术门槛,减少因切换数据库导致业务中断的风险。该功能利用 RLS 机制实现对象级可见性控制,为企业数据安全保驾护航。

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
在线格式化和美化您的 SQL 查询(它支持各种 SQL 方言)。 在线工具,SQL 美化和格式化在线工具,online
解析 INSERT 等受限 SQL,导出为 CSV、JSON、XML、YAML、HTML 表格(见页内语法说明)。 在线工具,SQL转CSV/JSON/XML在线工具,online
CSV 与 JSON/XML/HTML/TSV/SQL 等互转,单页多 Tab。 在线工具,CSV 工具包在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online