2. 基本概念
好,我们进入第二章。说实话,讲密钥访问控制,如果连基本概念都拎不清,后面讲策略、讲模型、讲实现,统统是空中楼阁。我自己早年带团队时,就吃过这个亏——大家天天聊「粒度要细」「权限要严」,结果一落地,每个人理解都不一样。
这节课,我们就钉下四颗钉子:密钥、权限、粒度、访问控制。把这四个概念彻底对齐,后面的路才走得稳。
1. 密钥:不只是字符串,它是身份的载体
很多人觉得,密钥不就是一串随机数吗?嗯,从密码学数学定义上看没错。但在访问控制语境里,密钥承载的是「谁能做什么」的语义。
我在项目里见过一个典型的坏设计:把一个 AES 密钥直接硬编码到所有服务里,然后说「我们已经有密钥了,访问控制就是验证密钥对不对」。这其实只做了认证,根本没做授权。
关键认知:密钥是权限的「箱子」。箱子本身不决定谁可以开,但箱子里面装什么、谁有钥匙、钥匙能开几次——这些才是访问控制要管的。
按用途分,密钥至少包括这么几类:
| 密钥类型 | 控制维度 | 典型应用 |
|---|---|---|
| 加密密钥 | 谁能加密/解密 | 数据加密、传输加密 |
| 签名密钥 | 谁能签发/验证 | 代码签名、文档认证 |
| 身份密钥 | 代表谁的身份 | SSH 登录、TLS 证书 |
| 派生密钥 | 从主密钥衍生子权限 | 分层密钥系统、ABAC 策略 |
你想想看,同一份数据,用不同的密钥加密,本质上就是对不同用户「说了不」。所以密钥管理的第一步,是清楚每一个密钥的「控制边界」在哪。
2. 权限:一条规则,一个「能不能」的答案
权限是对密钥使用范围的定义。说白了,就是一条规则:什么人/什么密钥,在什么条件下,对什么资源,能做什么操作。
为什么要强调这个?因为我踩过坑。曾经有个项目,权限表里只记录了「用户-资源-操作」,完全忽略了上下文。结果某个运维人员用调试密钥在凌晨三点批量删了生产库的日志。系统没报警,因为权限检查通过了——密钥本身有删除权限。
我的经验:权限定义至少要有三个要素——主体(谁)、客体(对什么)、操作(做什么)。但现代系统往往要加第四个:环境(什么条件下)。比如「只有在内网且工作时间,才允许使用签名密钥」。这一点在细粒度控制里特别重要。
权限本身可以组合,比如「读+写」权限组、「执行+审计」权限组。但在密钥访问控制里,权限的最小原子应该能映射到单个密钥的操作上。不能出现「这个密钥可以解密所有数据」这种粗放式权限。
# 一个太粗的权限定义(不推荐)
permission = {
"key_id": "k-123",
"operations": ["decrypt_all"] # 太模糊了!到底能解密哪些数据?
}
# 一个细粒度的权限定义(推荐)
permission = {
"key_id": "k-123",
"resource_pattern": "project:alpha:dataset:*",
"operations": ["decrypt", "verify"],
"conditions": {
"time_range": ["09:00", "18:00"],
"ip_range": ["10.0.0.0/8"]
}
}
3. 粒度:精细到什么程度才算「够细」?
这是本课程的核心词之一。粒度,代表控制的最小单元。
拿文件系统举例:粗粒度可能只能控制「整个目录」的读写,细粒度可以控制到「某个文件的某个字段」能不能读。放到密钥场景里,粒度体现在:
- 密钥级别:所有用户共用一把密钥 vs 每个用户/每个会话一把密钥
- 操作级别:密钥只能「解密」vs 密钥只能「解密某类数据的某几个字段」
- 条件级别:无条件使用 vs 必须同时满足 IP、时间、设备指纹等多因子条件
- 生命周期级别:密钥永久有效 vs 密钥使用一次即失效
注意避坑:我曾经见过一个团队,追求「极细粒度」,给每个 API 请求动态生成一个密钥,结果密钥存储和分发开销直接撑爆了 KMS。粒度的「细」是有代价的——管理复杂度、性能开销、审计日志量都会指数级增长。你需要在安全性和可行性之间找平衡点。
我个人习惯把粒度分为三个层级,方便和团队对齐:
| 粒度层级 | 控制范围 | 典型管理成本 | 适用场景 |
|---|---|---|---|
| 粗粒度 | 按密钥池、应用 | 低 | 内部工具、开发环境 |
| 中粒度 | 按密钥、权限组 | 中 | 多数业务系统 |
| 细粒度 | 按资源字段、条件组合 | 高 | 合规严控、多租户数据隔离 |
你选哪个层级,取决于你的威胁模型和可用资源。没有正确的粒度,只有适合场景的粒度。
4. 访问控制:把前三者串起来的「规则引擎」
访问控制本身是一个决策过程:给定一个密钥使用请求,系统根据预先定义的权限和当前粒度,决定「同意」还是「拒绝」。它不是单纯的技术实现,而是一种策略执行机制。
我把它拆成三个动作,这样团队里每个人都能理解:
- 请求:谁(哪个主体/密钥)要做什么(操作)对什么(资源)。
- 决策:根据权限策略,检查请求是否被允许。这里可能会走缓存、策略引擎甚至人工审批。
- 执行:允许则放行密钥操作,拒绝则记录日志并返回错误。
为什么要强调这三个动作?因为很多实现只做了「决策」而忽略了「执行」的可审计性。我曾经检查过一个系统,访问控制模块只返回 allow/deny,但没有任何日志说「是依据哪条策略决策的」。出事后追查根本无从下手。
核心原则:访问控制的本质是「默认拒绝,显式允许」。密钥在未被明确授权的情况下,应该没有任何使用权限。这一点,从设计第一天就要刻在架构里。
好,我们把四个概念串联起来看。下面的图展示了我自己对它们关系的理解,也是后续课程所有设计的基础。
这张图是我每次给新团队做培训时必画的。你可以看到,四个要素不是孤立的:密钥是基础,权限附着在密钥上,粒度定义了权限的精细程度,访问控制作为执行者,决定密钥在具体场景下是否被允许使用。而且注意那个虚线箭头——访问控制反过来也会制约密钥的设计,比如要求密钥必须绑定上下文属性。
好,到这里,四个基本概念我们就扎扎实实地打牢了。后面所有章节的策略、模型、架构方案,都会围绕这四个钉子展开。
一个小提醒:在实际工作中,我建议你把这四个概念贴在团队可见板或者技术文档的首页。每次讨论密钥安全问题时,先问一句:「我们说的是哪个要素?密钥本身?权限规则?粒度级别?还是执行机制?」这个习惯能省掉大量无意义的争论。