
权限申请不能靠人工审批 Excel 表格
MySQL 本身不提供审批流,硬要靠 DBA 手动改 GRANT、记台账、回邮件,10 个开发就乱,50 个基本失控。真正卡点不是「能不能给权限」,而是「谁在什么时候以什么理由申请了什么权限,是否被复核过」。
实操建议:
- 所有权限变更必须走可审计的中间层,比如封装一个审批服务(Python/Go 都行),它连接 MySQL 并调用
GRANT/REVOKE,而不是让人直连执行 - 审批记录必须落库(单独一张
permission_requests表),字段至少含:applicant、target_db、privileges(如SELECT,INSERT)、table_name、approved_by、executed_at - 禁止审批通过后手动再执行一遍 SQL —— 审批服务生成的语句必须是唯一执行入口,否则审计链路就断了
用角色(ROLE)隔离开发环境权限边界
直接给用户授 SELECT 到 prod_orders 表?一旦人离职或转岗,权限清理就是灾难。MySQL 8.0+ 的 ROLE 是唯一能解耦「身份」和「权限」的机制。
实操建议:
- 按环境建角色:比如
dev_reader、test_writer、staging_dba,每个角色只包含对应环境最小必要权限 - 开发账号统一加到
dev_reader,需要写入时走审批流临时SET ROLE test_writer,超时自动失效(配合 MySQL 的activate_all_roles_on_login=OFF) - 避免嵌套角色(如
test_writer再GRANT给dev_reader),MySQL 角色继承不支持动态刷新,容易权限漂移
自动化回收比审批更关键:权限不是「永久有效」
90% 的权限滥用不是恶意越权,而是「当初申请了,后来忘了关」。MySQL 不会自动过期权限,必须自己埋回收逻辑。
实操建议:
- 所有审批通过的权限,必须带
expires_at字段(比如默认 7 天),审批服务在执行GRANT后,自动插入一条定时任务(如用mysql.event或外部调度器)触发REVOKE - 定期扫描
mysql.role_edges+mysql.role_routines,对比permission_requests表中已过期但未回收的记录,发告警 - 禁止使用通配符授权(如
ON *.*),哪怕只是临时测试 —— 它绕过所有基于库/表的回收逻辑
开发提申请时,必须限制可选范围而非自由填 SQL
让开发自己写 GRANT SELECT ON sales.* TO 'dev123'@'%'?等于把锁交给钥匙保管员。权限粒度必须收口。
实操建议:
- 前端审批表单里,
database下拉只允许选预设值(如dev_userdb、test_analytics),不接受自由输入 -
privileges只开放勾选:仅SELECT、SELECT+INSERT、SELECT+UPDATE三档,禁用DROP、ALTER、CREATE - 如果真需要
ALTER,强制走二级审批(DBA + 架构师双签),且只能作用于_tmp结尾的表名(防止误改线上结构)
最麻烦的从来不是怎么给权限,而是怎么证明「这个权限确实被需要、被复核、被回收」。只要漏掉其中一环,审计时翻出来的就是一整张没签名的纸。











