第3章 认证与授权机制

3.1 认证与授权的边界

很多团队在设计 Secrets Manager 接口时,第一个搞混的就是认证和授权。这两个词看着像,干的活完全不同。

认证是问「你是谁」—— 检查调用方是不是一个合法的身份。、OAuth2.0 令牌、IAM 用户都干这个事。

授权是问「你能干什么」—— 你拿到了合法身份,但你能读哪些密钥?能写哪些?能删除吗?这些由授权机制决定。

我见过一个项目,验证通过后,所有密钥对调用方全量开放。那场景就像给了门禁卡,结果整栋楼每个房间都能进。出过事之后,他们才把授权层补上。

下面这张图可以帮你快速建立整体认知:

认证与授权机制全景图 认证与授权机制全景图 客户端请求 认证 静态令牌 · 简单直接 OAuth2.0 集成 委托授权 · 标准协议 IAM 身份验证 云原生身份体系 策略评估引擎 基于 IAM 策略 · 最小权限原则 密钥安全返回 ┃ 认证域 ┃ 授权域 三层防线:认证确定身份 → 授权管控范围 → 最小权限收紧边界

从图上你可以看到,一个请求从进来开始,先过认证关,再过授权关,最终才能拿到密钥。两个环节缺一不可。

3.2 认证

是最常见的认证方式。说白了就是一个字符串 —— 调用方拿着它来证明身份。实现简单,但坑也不少。

基本用法

Secrets Manager 通常会在创建密钥时生成一对凭证:Access Key ID 和 Secret Access Key。调用方用它们签名请求,服务端验签通过即完成认证。

# 伪代码:签名示例
import hmac
import hashlib
import base64

def sign_request(access_key, secret_key, timestamp, body):
    message = f"{access_key}:{timestamp}:{body}"
    signature = hmac.new(
        secret_key.encode(),
        message.encode(),
        hashlib.sha256
    ).hexdigest()
    return signature

避坑指南

我曾经在一个项目中,发现团队把 Secret Access Key 直接写在代码的配置文件中,还提交到了 Git 仓库。 结果被安全扫描工具扫出来,不得不紧急轮换所有密钥。那次的教训是:必须通过环境变量或 Secrets Manager 注入,不能硬编码。

个人习惯:需要定期轮换。我建议 90 天为一个周期,并且每次轮换时要保留旧密钥 24 小时的过渡期,避免正在运行的服务因为密钥更新而中断。

的适用场景

  • 内部服务间通信 —— 服务都在同一个 VPC 内,风险可控
  • CI/CD 流水线 —— 构建和部署脚本需要访问密钥,是最轻量的方案
  • 开发和测试环境 —— 快速验证,但不建议生产环境单独使用

3.3 OAuth2.0 集成

OAuth2.0 解决的是「委托授权」问题。举个例子:我有一个第三方应用,想读取你存在 Secrets Manager 里的某个密钥,但我不想把 直接给它。OAuth2.0 可以让用户授权第三方应用在限定范围内访问资源。

在 Secrets Manager 中的常见流程

  1. 客户端向授权服务器请求令牌(携带 client_id 和 client_secret)
  2. 授权服务器验证身份后,返回 access_(有时也返回 refresh_)
  3. 客户端拿着 access_ 调用 Secrets Manager 的 API
  4. Secrets Manager 验证令牌的有效性,并提取用户身份
  5. 进入授权层,判断该用户是否有权访问目标密钥

令牌请求示例

# curl 示例:获取 OAuth2.0 访问令牌
curl -X POST https://auth.example.com/oauth/ \
  -H "Content-Type: application/json" \
  -d '{
    "grant_type": "client_credentials",
    "client_id": "your-client-id",
    "client_secret": "your-client-secret",
    "scope": "secrets:read"
  }'

# 返回示例
{
  "access_": "eyJhbGciOiJSUzI1...",
  "_type": "Bearer",
  "expires_in": 3600,
  "scope": "secrets:read"
}

经验之谈

我做过一个跨云密钥同步的工具,需要从 AWS Secrets Manager 读取密钥后同步到阿里云。两边认证方式不同:AWS 用 IAM + 签名,阿里云用 OAuth2.0。最头疼的是令牌过期问题。

我的建议:OAuth2.0 的 access_ 通常只有 1 小时的有效期。一定要实现自动刷新机制,否则半夜掉令牌就是事故。另外,client_secret 也要托管在 Secrets Manager 里,别写死在代码里。

3.4 IAM 角色与策略

IAM 是云原生的身份与访问管理体系。比起 ,IAM 更强调「角色」和「策略」的分离。你创建一个角色,给角色附加策略,然后把角色赋给服务或用户。这样权限管理就变成了策略的编排,而不是密钥的分发。

策略的结构

一个标准的 IAM 策略包含四个部分:Effect(允许/拒绝)、Action(操作列表)、Resource(资源列表)和 Condition(条件约束)。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "secretsmanager:GetSecretValue",
                "secretsmanager:DescribeSecret"
            ],
            "Resource": "arn:aws:secretsmanager:us-east-1:123456789012:secret:my-app-*",
            "Condition": {
                "IpAddress": {
                    "aws:SourceIp": "10.0.0.0/16"
                }
            }
        }
    ]
}

这个策略的意思是:允许在 10.0.0.0/16 网段内的服务,读取 my-app- 开头的密钥。其他网段来请求,直接拒绝。

IAM 角色 vs

对比维度 IAM 角色
凭证管理 由云平台自动轮换 需要手动轮换
使用场景 云原生服务、EC2、Lambda 外部服务、CI/CD、传统应用
安全等级 高(临时凭证) 中等(长期凭证)
配置复杂度 中等 低

你想想看,IAM 角色用的是临时凭证,每隔几个小时自动换一次。就算泄露了,窗口期也短得多。而 一旦泄露,除非你手动轮换,不然坏人能一直用。

能上 IAM 角色就别用 —— 这是我做了多年安全管理后最深的体会。只有那些无法使用 IAM 的外部场景,才考虑 。

3.5 最小权限原则

最小权限原则,用大白话说就是:只给刚刚好的权限,多一点都不给。这在 Secrets Manager 的上下文中尤其重要,因为密钥是最高敏感度的资产。

三个落地要点

  1. 按资源粒度划分 —— 不要让一个策略覆盖所有密钥。比如 web-app 只能访问 web-app/ 路径下的密钥,支付服务只能访问 payment/ 下的。
  2. 区分读写权限 —— 大部分服务只需要读取密钥,只有 DevOps 工具才需要写入和删除。分开管控。
  3. 使用条件约束 —— 加上 IP 限制、VPC 限制、时间限制。多一层约束就多一层安全。

反面案例

我曾经处理过一次线上事故:运维团队为了图省事,给一个 CI 脚本赋予了 secretsmanager:* 的权限。结果脚本里有个 bug,在循环中误删了二十多个密钥,导致多个服务同时宕机。恢复花了一整夜。事后分析,如果当时只给 GetSecretValue 和 PutSecretValue 两个操作,删除操作根本不会发生。

最小权限清单核对表

  • 每个角色/用户只分配必要的 Action ✅
  • Resource 限定到具体路径或前缀 ✅
  • 添加 Condition 约束(IP / VPC /时间) ✅
  • 定期审计策略,移除未使用的权限 ✅
  • 避免使用通配符 Action(如 secretsmanager:*) ✅

我的做法:每次写完 IAM 策略,我都会反问自己三个问题:这个调用方真的需要删除权限吗?真的需要访问所有密钥吗?真的不需要加 IP 限制吗?三问之后,策略往往还能再收紧一圈。

四种机制怎么选?

机制 适用场景 安全等级 我个人推荐度
内部服务、CI/CD、测试 中等 ⭐⭐⭐
OAuth2.0 第三方集成、跨组织访问 高 ⭐⭐⭐⭐
IAM 角色 + 策略 云原生服务、生产环境 最高 ⭐⭐⭐⭐⭐
最小权限原则 所有场景(必选) — 🔴 不遵守会出大事

说白了,四种机制不是互斥的,而是配合使用的。我在实际项目中通常这样组合:

  • 云内服务用 IAM 角色 + 策略,策略按最小权限写
  • 外部系统用 或 OAuth2.0,但密钥托管在 Secrets Manager 里,并且严格限定资源范围
  • 所有场景都过一遍最小权限审查,谁也别想走捷径

记住一个原则:认证只是入场券,授权才是守门员,最小权限是把门缝调到最窄。三层都做到位,密钥才能睡得安稳。