安全加固设计(Redis ACL / TLS / 密钥与配置内容)
本文供评审,不含代码改动。目标:框架当前对 Redis 的接入是"单机 + 密码可选"的最小形态,生产化所需的 ACL 用户名、TLS、密钥管理、配置内容保护都缺位。本设计给出分阶段方案。
现状(事实盘点)
- 唯一的 main 侧
Redisson.create:spring-boot-starterRedisStreamingAutoConfiguration,useSingleServer()只设 address/database/超时/连接池 + 可选setPassword(带@SuppressWarnings("deprecation"),注释说明 Redisson 4.x 推荐CredentialsResolver)。 - ACL 用户名(v1 已落地 2026-10-11):
RedisStreamingProperties.RedisProperties.username已支持(空/空白不设),${env:VAR}惰性凭证解析同批落地。 - TLS 无一等支持:没有
rediss://文档与示例,没有 truststore/peer 验证相关配置暴露;用户唯一路径是自带redisson-spring-boot-starter(javadoc 里提了,但没有 TLS 具体指引)。 - 集群/哨兵同样只靠"用官方 starter"一句话:框架自身配置模型只有单机。
- 配置中心内容明文:
config模块把配置内容原样存 Redis(String/Hash),无加密、无敏感项标记。 - 日志脱敏护栏(已落地 2026-10-13):连接初始化打 address(可接受);
LogRedaction提供按键名(secret.*前缀 +password/token/credential/...片段)分类的脱敏,JobSpec.toString()经它渲染,config 映射与自由文本日志均不再泄漏凭证字面量。 - 各模块(mq/registry/config/cdc/sink...)不自行创建 Redisson,统一复用注入的 client——这一点是好的,加固只需集中在 client 构造与配置边界。
可选方案
方案 A:ACL 用户名 + ConfigCustomizer SPI(推荐 v1)
改动最小、覆盖面最大,且不重复造 Redisson 已有的轮子:
RedisProperties补username:非空则setUsername(...)(或走 Redisson 4.x 的CredentialsResolver,同时把 password 读取改为惰性解析,支持${env:VAR}形式从环境取,避免明文落配置文件)。- 暴露
ConfigCustomizerSPI:starter 增加@ConditionalOnMissingBean(ConfigCustomizer.class)的钩子接口void customize(Config config),在Redisson.create之前调用。TLS(truststore/hostname verification)、哨兵、集群、读写分离等一切高级形态都由用户在这个钩子里一行接入——框架不逐项暴露配置项(暴露项永远追不上 Redisson 的配置面)。 - 文档:
rediss://+ ACL + ConfigCustomizer 三条生产接入路径写成 Deployment 指南章节(配最小 Redis ACL 规则示例:仅放行框架用到的 key 前缀与命令组)。
方案 B:框架内置全套 TLS/集群/哨兵配置项
把 Redisson 的配置面镜像到 RedisStreamingProperties。可控性好,但配置面巨大且与官方 starter 重复——不推荐(与方案 A 的 Customizer 二选一,选 A)。
方案 C:密钥与配置内容保护(v2,独立增量)
- 配置中心内容加密:
config模块加可插拔ContentCipher(接口encrypt/decrypt,默认 noop 保持兼容),按 key 前缀(如secure.*)启用;密钥来源走环境/JVM 参数,不入 Redis。已落地 2026-10-12(见 docs/config.md「内容加密(at-rest)」)。 - JobSpec 敏感项:约定
secret.*前缀的 config 值存引用而非明文(env:NAME/sys:NAME),执行侧(RedisJobLauncher)解析,工厂拿到已解析副本;specHash输入对 secret 字面量脱敏(引用是指针,原样参与以保住漂移检测);审计流固定字段不含 config。已落地 2026-10-12(约定细节与轮换语义见 docs/Control-Plane-Design.md「secret 引用约定」)。 - 日志脱敏护栏(已落地 2026-10-13):
runtime.redis.control.LogRedaction——按键名分类(secret.*前缀 +password/passwd/secret/token/credential/apikey/accesskey/privatekey/auth片段,大小写不敏感),redact(Map)/redact(String)/renderSpec(JobSpec)三种出口;引用(env:/sys:)是指针不脱敏,字面量一律换***。JobSpec.toString()改走renderSpec(Lombok@Data的生成版会原样嵌 config),任何log("{}", spec)不再泄漏。约定仍成立:凭证只进惰性解析路径,任何模块不得把password/token/secret字段打进日志。ArchUnit 规则(机械强制,替代 code review 约定)尚未引入,需新增外部依赖,留待评审。
迁移路径
- v1(一个小版本可完成):
username+${env:}惰性凭证 +ConfigCustomizerSPI + TLS/ACL 文档;补 starter 单测(ApplicationContextRunner 验证 customizer 被调用、username 生效)。 - v2:配置中心
ContentCipher+ JobSpecsecret.*引用约定 + 脱敏审计。
非目标
- 不做框架自有认证体系(控制面授权器维持可插拔,见控制面设计)。
- 不内置 Vault/KMS 客户端(
CredentialsResolver/ContentCipher接口留给接入方实现)。 - 不做 Redis 服务端的 ACL 规则管理(文档给推荐规则,不代管)。