Redis ACL 的 key pattern 为什么放行了意外键
我排查 Redis ACL 时,最容易误判的一点是:看到用户配置了 ~tenant-a:*,就以为它只能访问这一组键。实际上,Redis 会把同一个用户已有的 key pattern、命令权限和 selector 一起计算;旧规则没有清掉、通配符范围过宽,或者命令本身不带具体 key,都可能让“意外键”看起来被放行。
先执行ACL GETUSER 用户名看生效规则,再用ACL DRYRUN 用户名 命令 参数做无副作用验证。最稳妥的修复方式是以reset重建权限,明确区分根规则和 selector,而不是继续追加一个更窄的 pattern。
~pattern是 glob 风格匹配,~*或allkeys会覆盖所有键。ACL SETUSER默认是在已有规则上追加;规则和 selector 只要有一组完整匹配,就可能获得许可。- 不带 key 参数的数据库级命令不受 key pattern 限制,必须单独收紧命令权限。
先把真正生效的规则展开
不要只看部署文件里最近改的那一行。Redis 官方文档说明,ACL SETUSER 会从左到右处理规则;用户已存在时,新调用通常是在原规则上应用变更。先查根规则、键规则和 selector:
# 读取用户当前的完整 ACL,包括根权限和 Redis 7.0+ selector
ACL GETUSER app_reader
# 以 ACL 文件格式查看所有用户的有效规则,便于发现 ~* 或 allkeys
ACL LIST
# 在不真正执行命令的前提下,模拟 app_reader 访问另一租户的键
ACL DRYRUN app_reader GET tenant-b:profile:42
如果回显的 keys 同时有 ~tenant-a:* 和 ~*,答案已经很明确:后者覆盖了前者。若 selectors 里还有一组包含 ~* 或更宽 pattern 的规则,也要一并处理。ACL GETUSER 展示的是用户的有效规则,适合用来对照配置文件和变更记录。
这是Redis ACL key pattern使用通配符匹配时的常见坑:默认规则下`*`、`?`这类通配符的匹配范围比多数开发者预期更广,没有转义特殊字符、或者pattern前缀后缀遗漏边界限制,就会把原本不在权限规划内的键也放行了。排查时优先核对pattern的字符转义规则、键名的实际字符组成,就能快速定位问题根源。

为什么窄 pattern 仍会放行意外键
我通常按下面四个边界逐一排除,避免把“键名匹配”误当成“所有访问都取交集”。
| 检查点 | 常见配置 | 实际含义 |
|---|---|---|
| 通配符 | ~tenant-* | glob 匹配,范围可能包含多个租户,而非前缀的精确等值。 |
| 历史规则 | 先有 ~*,后加窄规则 | 追加窄规则不会自动删除旧的宽规则。 |
| selector | (+GET ~*) | 根权限或任一 selector 完整匹配时即可通过,不能把它理解成两者相交。 |
| 无 key 命令 | FLUSHDB、FLUSHALL | 没有具体 key 参数,key pattern 本身无法限制它们。 |
Redis 7.0 起还可以写 %R~pattern 和 %W~pattern,分别限制读、写方向。跨键命令要特别小心:例如把 tenant-b: 的数据复制到 tenant-a:,同一组权限需要分别覆盖源键的读取和目标键的写入;只给其中一个 pattern,不能得到你想要的跨键能力。
用重建而不是叠加修正权限
如果用户是专用业务账号,我更愿意明确重置后再写规则。下面是一个只允许读取和写入 tenant-a: 的示例;密码仅作占位,生产环境不要把真实密码写进脚本或日志。
# reset 先清掉旧的命令、key 和密码规则,避免历史 ~* 残留
ACL SETUSER app_writer reset on >replace-with-secret +GET +SET +DEL ~tenant-a:*
# Redis 7.0+ 可把读写边界拆开;按需选择,不要与 ~* 混用
ACL SETUSER app_reader reset on >replace-with-secret +@read %R~tenant-a:*
# 把高风险的数据库级命令显式移除,它们不靠 key pattern 约束
ACL SETUSER app_writer -FLUSHDB -FLUSHALL -SWAPDB
“最小权限”不等于只写一个 pattern。还要确认命令集合、事务或脚本使用的命令,以及应用是否需要跨键操作。若账号要执行 HGET、HSET,不要只开放一个与数据结构不匹配的命令类别;按真实调用清单逐项增加。
用 DRYRUN 验证允许、拒绝和高风险路径
ACL DRYRUN 从 Redis 7.0 提供无副作用的模拟执行,特别适合把“我以为会拒绝”变成可复查的结果。建议至少覆盖三类键和一类无 key 命令:
# 允许的键:预期返回 OK(以下是示例回显,不代表本文在你的实例执行)
ACL DRYRUN app_writer SET tenant-a:profile:42 active
# OK
# 另一租户:预期返回没有 key 权限
ACL DRYRUN app_writer GET tenant-b:profile:42
# User app_writer has no permissions to access the key
# 无 key 参数的高风险命令:检查它是否仍在命令集合中
ACL DRYRUN app_writer FLUSHALL
# User app_writer has no permissions to run the 'flushall' command
如果意外键仍然返回 OK,回到 ACL GETUSER 搜索所有根 pattern 和 selector,再检查应用实际认证的用户名:连接复用、默认用户和 AUTH/HELLO 切换都可能让你查的是 app_reader,用的却是另一个用户。

上线前留一张小清单
- 用
ACL GETUSER确认没有遗留~*、allkeys或意外 selector。 - 用真实命令逐个跑
ACL DRYRUN,至少包含读、写、删除、跨键和无 key 参数命令。 - 把
ACL SETUSER变更写成可重复的声明式脚本,修改前优先reset,并保留回滚版本。 - 确认业务连接认证的用户名与检查时一致,再让灰度流量验证拒绝路径。
常见问题
只写了 ~tenant-a:*,为什么还能访问别的键?
最常见是旧规则仍包含 ~*,或 selector 中存在更宽的 pattern。先看 ACL GETUSER 的 keys 和 selectors。
~pattern 能限制 FLUSHALL 吗?
不能。FLUSHALL 没有具体 key 参数,需从命令权限中移除;同理检查 FLUSHDB、SWAPDB 等数据库级命令。
Redis 6 能使用 ACL DRYRUN 吗?
不能把它作为 Redis 6 的通用检查手段;官方命令文档标注 ACL DRYRUN 从 Redis 7.0 起提供。旧版本应在隔离环境用测试账号和真实命令验证。
Go TLS InsecureSkipVerify 为什么只影响客户端校验
- 上一篇
- Go TLS InsecureSkipVerify 为什么只影响客户端校验
- 下一篇
- Go compress/gzip Header.ModTime 如何控制归档可复现性
-
- 数据库 · Redis | 6小时前 | Redis · 任务队列 · 消息重试 · 幂等处理 · ZPOPMIN · Redis ZPOPMIN Redis 批量取任务 Redis 任务丢失 Redis 有序集合队列 Redis 超时重试
- Redis ZPOPMIN 批量取任务后如何避免丢失
- 369浏览 收藏
-
- 数据库 · Redis | 8小时前 |
- Redis XCLAIM 重试消息时如何设置 idle 条件
- 250浏览 收藏
-
- 数据库 · Redis | 10小时前 |
- Redis Streams XREAD 如何按多个流合并读取消息
- 205浏览 收藏
-
- 数据库 · Redis | 11小时前 | Redis · 数据遍历 · 缓存排障 · SCAN命令 · 幂等处理 · Redis SCAN Redis MATCH Redis COUNT Redis重复键 Redis游标遍历
- Redis SCAN 使用 MATCH 和 COUNT 时为什么仍会返回重复键
- 305浏览 收藏
-
- 数据库 · Redis | 12小时前 |
- Redis PUBSUB shard channels 与普通频道如何选
- 311浏览 收藏
-
- 数据库 · Redis | 13小时前 | Redis · 内存管理 · 客户端连接 · 故障排查 · redis CLIENT NO-EVICT maxmemory-clients 客户端淘汰
- Redis CLIENT NO-EVICT 如何保护关键连接不被淘汰
- 411浏览 收藏
-
- 数据库 · Redis | 14小时前 | Redis · 性能排查 · 延迟监控 · Redis LATENCY DOCTOR Redis延迟诊断 latency-monitor-threshold
- Redis LATENCY DOCTOR 报告与业务延迟不一致怎么办
- 363浏览 收藏
-
- 数据库 · Redis | 16小时前 |
- Redis SLOWLOG RESET 后如何保留外部审计记录
- 205浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 31次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 135次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 70次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 27次使用
-
- CMMLU
- 深入了解CMMLU中文评估基准,涵盖67个学科主题,提供数据集下载、Zero-shot/Five-shot评估方法及排行榜,助力优化中文语言模型性能。
- 16次使用
-
- Redis Stream XTRIM 如何避免消费组积压无限增长
- 2026-09-12 501浏览
-
- Redis AOF rewrite 期间如何判断磁盘与内存压力
- 2026-09-12 501浏览
-
- Redis RDB 和 AOF 怎么按可接受数据丢失量选择
- 2026-09-08 501浏览
-
- Redis XAUTOCLAIM 之后为什么仍有 pending:JUSTID、PEL 与消息删除边界
- 2026-08-29 501浏览
-
- Redis SET 的 GET 与 KEEPTTL 怎么一起验收:旧值返回、续期与回滚边界
- 2026-08-20 501浏览

