只让应用读一张表:KES 对象权限最小化实操

只让应用读一张表:KES 对象权限最小化实操

“先给大权限,等上线稳定了再收”是权限失控最常见的起点。应用本来只需要读取biz.order_summary,最后却拿到整个模式的增删改查,甚至被授予管理权限。短期看省了排错时间,长期却把误操作、注入和账号泄露的影响面一起放大。

最小权限不是把账号限制到不能工作,而是先把业务动作翻译成对象和操作:读哪张表、是否写入、是否调用函数、是否使用序列。答案明确后,授权语句通常并不复杂。

— 从业务动作出发,而不是从“给哪个大角色最省事”出发。

先建无登录权限角色

把权限装进角色,再把角色授给登录用户,便于多人复用和集中回收:

CREATEROLE order_reader NOLOGIN;CREATEUSERapp_report LOGIN;GRANTorder_readerTOapp_report;

然后只授权目标对象:

GRANTUSAGEONSCHEMAbizTOorder_reader;GRANTSELECTONTABLEbiz.order_summaryTOorder_reader;

这里经常漏掉模式访问。表的SELECT权限和模式的访问能力不是一回事;对象名能在文档里看到,也不代表账号已经具备完整访问路径。授权时要把数据库连接、模式访问、对象操作分层检查。

如果应用只读取部分敏感度较低的列,还可以评估列级授权或通过受控视图暴露数据。不要为了避开列级设计,直接把整张含敏感字段的表开放出去。使用视图时,还要检查视图所有者、底层对象权限和业务过滤条件,确保它真的形成边界。

先撤掉历史遗留权限

新授权看起来很小,但账号可能早已从别处继承了更大权限。测试前先梳理直接授权、角色成员关系和 PUBLIC 权限。必要时撤销历史权限:

REVOKEALLONTABLEbiz.order_summaryFROMapp_report;REVOKEINSERT,UPDATE,DELETEONTABLEbiz.order_summaryFROMorder_reader;

撤销动作要谨慎评估依赖,不要在生产环境直接试错。先查询权限现状,确认授权来源,再形成可回滚变更单。尤其是共享账号,不能因为一个应用要收权,意外影响另一个仍在使用它的系统。

验收必须包含“应该失败”

使用真实应用账号建立新会话,验证允许动作:

SELECT*FROMbiz.order_summaryFETCHFIRST1ROWONLY;

然后验证禁止动作:

INSERTINTObiz.order_summary(order_id)SELECT'probe'WHERE1=0;UPDATEbiz.order_summarySETorder_id=order_idWHERE1=0;DELETEFROMbiz.order_summaryWHERE1=0;

这些零行语句应在执行前因权限不足而失败,即使意外获得权限也不写入真实行。仍应在隔离环境优先验证,并使用专门测试对象确认驱动与兼容形态的实际行为。若禁止动作成功,优先排查账号是否继承了其他角色、对象是否授给 PUBLIC、连接时是否使用了错误账号。仅凭管理员查询授权视图得出“应该没权限”,不如实际用目标账号验证来得直接。

— 正向成功加越权失败,才能证明权限边界真的落地。

写权限要继续拆

需要写入时,也不要习惯性授予ALL。只新增数据就给INSERT;需要修改状态再给指定表或列的UPDATE;删除往往风险更高,应确认业务是否真的需要。若写入依赖序列、函数或过程,再对相应对象追加必要权限。

应用升级新增接口时,应把权限需求和数据库脚本一起评审。上线后若发现权限不足,先确认需求遗漏,补最小授权并记录原因,不要临时把账号抬成管理员。权限设计真正的价值,是让一个账号出问题时,损失范围仍被限定在它必须完成的工作内。

参考资料

  • KES 官方安全指南:权限管理