redis的publish/subscribe本身不支持租户隔离,必须通过应用层强制频道前缀tenant:{tenant_id}:、服务端校验当前上下文租户id、acl按前缀授权+subscribe/+publish三重防护协同实现,缺一不可。

Redis 的 PUBLISH/SUBSCRIBE 本身完全不隔离租户,必须靠应用层强制加前缀 + 服务端校验 + ACL 三重兜底,缺一不可。
频道名必须带 tenant:{tenant_id}: 前缀
这是隔离的起点,不是可选项。Redis 把所有频道当字符串处理,tenant:abc123:order_updated 和 tenant:def456:order_updated 在协议层毫无区别,也不会自动拒绝跨租户操作。
- ✅ 必须用
tenant:开头,避免和系统频道(如health:check)冲突 - ⚠️ 若
tenant_id含/、:、空格等,必须做 URL-safe 编码(如encodeURIComponent或 Base64),否则 Redis 可能报ERR invalid channel name - ❌ 禁止用
{user_id}:或裸{tenant_id}:—— 用户 ID 可跨租户重复,且粒度太细;缺少语义前缀易导致命名空间污染
每次 SUBSCRIBE 和 PUBLISH 前必须校验频道合法性
只靠命名约定等于没隔离。前端传参、调试脚本、内部工具都可能绕过“自觉”,校验必须在服务端入口处硬拦截。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 校验依据只能是可信上下文中的
tenant_id(如 JWT payload、网关注入的 context 值),不能直接取请求 body 或 query 参数 - 收到
SUBSCRIBE tenant:def456:log但当前租户是abc123?立即返回 HTTP 403 或自定义错误,不转发给 Redis - 同理,
PUBLISH到非所属租户频道也要拦截——否则就是租户 A 主动向租户 B “投毒” - 校验逻辑建议统一收口在 API 网关或消息 SDK 中,避免业务模块各自实现、漏判
禁用 PSUBSCRIBE,ACL 配合 ~tenant:{tenant_id}: 模式加固
PSUBSCRIBE 支持通配符(如 tenant:*:*),极易越权匹配其他租户频道,生产环境应默认禁止,仅限租户管理员级调用。
- Redis 6.0+ 的 ACL 是兜底手段,不能替代应用层校验,但能防直连绕过(如运维脚本、Redis CLI 调试)
- 为每个租户建独立用户:例如
ACL SETUSER tenant_abc123 on >pass123 ~tenant:abc123:* +subscribe +publish -
~tenant:abc123:*中的波浪号~表示 key pattern,它对 Pub/Sub 频道同样生效——这点常被忽略 - ACL 不支持正则,
~tenant:*:*是非法写法;必须按租户逐条配置,或用脚本批量生成
真正容易出问题的地方不在 Redis 配置,而在于租户上下文如何可信传递、校验逻辑是否覆盖所有入口(包括后台任务、定时 Job、Webhook 回调),以及 ACL 用户密码是否轮换、失效后是否同步清理权限。这些环节一旦松动,前缀和校验就形同虚设。










