文章

【笔记】云厂商 IAM、AK-SK 与 STS 的演进模型

【笔记】云厂商 IAM、AK-SK 与 STS 的演进模型

云厂商 IAM 的中心问题不是“怎样保存一对 AK/SK”,而是:当一个账号下的资源需要被多人、程序、云服务和外部身份访问时,怎样同时回答“谁在访问、能做什么、如何证明身份、权限能持续多久”。

AWS IAM 与阿里云 RAM 的名字不同,实现细节也不完全相同,但都可以放进同一个模型:账号拥有资源,身份代表调用者,策略描述权限,凭证证明调用者控制某个身份或会话,STS 在验证初始身份后把它兑换成短期角色会话,请求签名或 PoP 证明再把每一次 API 调用绑定到凭证持有者。

本文解释两家云产品的共同抽象和关键差异,不把相似概念写成兼容协议。AWS 的请求签名以 SigV4/SigV4a 为主;阿里云 OpenAPI 当前推荐 V3 签名,部分云产品仍有自己的认证机制。

1. 一张图看完整链路

flowchart LR
    O[账号<br/>资源与账单归属] --> I[身份<br/>User / Role / 外部主体]
    O --> R[云资源]
    P[Policy<br/>Action Resource Condition] --> I
    I --> C{凭证类型}
    C -->|长期| L[AK + SK]
    C -->|扮演角色| S[STS 角色会话]
    S --> T[临时 AK + SK + Token + Expiration]
    L --> Q[签名后的 API 请求]
    T --> Q
    Q --> A[认证<br/>验证凭证与请求完整性]
    A --> Z[授权<br/>综合身份 会话 资源与组织策略]
    Z --> R

这条链路包含六个不能混用的概念:

  1. 账号决定资源、账单和管理边界;
  2. 身份表示谁在操作;
  3. 策略表示在什么条件下可以对哪些资源执行哪些动作;
  4. 凭证是调用者向平台证明身份或会话的材料;
  5. 请求签名证明调用者持有密钥,并保护请求完整性;
  6. 授权求值在认证成功后,决定本次操作最终是否允许。

AK 不是身份本身,也不携带权限。更准确的理解是:平台通过 AK 找到对应的凭证及其关联主体,再进入策略求值。

2. IAM 为什么会出现

2.1 第一阶段:账号既是资源属主,也是操作身份

云账号首先解决资源归属、计费和合同关系。最简单的系统会让账号凭证同时承担日常操作:谁拿到账号密码或账号 AK/SK,谁就能管理账号下的所有资源。

这种模型只适合单人和低复杂度场景。一旦进入企业协作,就会同时出现三个问题:

  • 多个人或程序共享账号凭证,无法可靠区分实际操作者;
  • 所有人继承账号的全部权限,无法落实最小权限;
  • 凭证泄露后的影响范围等于整个账号,轮换还会同时影响所有调用者。

因此,账号必须从“日常操作身份”退回为资源和管理边界,日常操作交给账号内部的受限身份。

2.2 第二阶段:User、Group 与 Policy 实现分权

AWS 在账号内提供 IAM user 和 user group;阿里云在账号内提供 RAM 用户和 RAM 用户组。User 通常有稳定的身份标识,可以配置控制台登录凭证或程序访问用的长期 AccessKey。Group 只负责批量组织用户和权限,不是可登录、可签名或可被扮演的主体。

Policy 把授权从代码和凭证中抽离出来。它通常围绕以下元素表达规则:

1
2
3
4
Effect    Allow 或 Deny
Action    允许或拒绝哪些 API 操作
Resource  规则作用于哪些资源
Condition 在什么上下文条件下生效

于是长期程序访问形成了第一条完整链路:

1
2
3
4
5
长期 AK/SK
  → 请求签名
  → 平台识别 IAM user / RAM 用户
  → 汇总该身份相关策略
  → 对 Action、Resource、Condition 求值

User 和 Policy 解决了共享账号与粗粒度授权,但长期 AK/SK 仍然需要分发、保存、轮换和撤销。它适合确实需要稳定程序身份的场景,却不适合作为所有工作负载和临时协作的默认方案。

2.3 第三阶段:Role 把“身份模板”与长期凭证分开

Role 与 User 都能绑定权限策略,但 Role 不拥有密码或长期 AccessKey。它只有被可信实体扮演后才形成可调用 API 的角色会话。

Role 因而把两个问题拆开:

  • 谁可以扮演它:由信任策略或可信实体配置回答;
  • 扮演后能做什么:由角色的权限策略回答。

这个拆分支撑了三类以前很别扭的场景:

  1. 人员临时切换到运维或生产角色;
  2. 一个账号的主体访问另一个账号中的资源;
  3. EC2、ECS、EKS、ECS 实例、ACK Pod 等工作负载获得云权限,而不保存长期用户密钥。

Role 不是“一组临时 AK/SK”。Role 是可被承担的身份与权限模板;临时凭证只是某次角色会话的使用材料。

2.4 第四阶段:STS 把身份信任兑换成短期会话

Security Token Service 接受一个已经能够验证的调用者或外部身份断言,检查其是否可以扮演目标 Role,然后创建有明确期限的角色会话。

AssumeRole 为例,关键判断通常包含:

1
2
3
4
调用方是否通过认证
  ∩ 调用方是否允许调用 AssumeRole
  ∩ 目标 Role 是否信任调用方
  ∩ 会话策略是否落在 Role 权限以内

验证通过后,两家云都会返回类似的临时凭证:

含义AWS STS阿里云 STS
公开的凭证标识AccessKeyIdAccessKeyId
用于计算签名的秘密SecretAccessKeyAccessKeySecret
临时安全令牌SessionTokenSecurityToken
到期时间ExpirationExpiration

会话策略只能在角色已有权限内继续收窄,不能借 STS 放大角色权限。临时凭证到期后失效,应用需要重新获取;通常应交给官方 SDK 的 credential provider 自动获取、缓存和更新。

2.5 STS 必须先验证谁在换证

STS 不是无条件的凭证生成器。它只是把一种已经可验证的身份或授权断言,兑换成另一种有明确受众、权限和有效期的临时凭证。

1
2
3
4
初始身份证明
  → STS 验证身份来源
  → 检查调用方能否建立目标 Role session
  → 签发短期、有限权限的临时凭证

如果 STS 不验证第一步,任何调用者都能冒充受信主体换取权限。因此,STS 没有消除信任起点,而是将它限制在换证入口,再将日常请求所使用的凭证变短、变窄并自动过期。

初始身份可以来自不同信任域:

身份来源向 STS 如何证明主要边界
现有 AK/SK用 SK 对 STS 请求签名SK 不随请求发送,但仍要在调用端保管
OIDC / Web Identity提交 IdP 签发的 JWT,STS 验签并检查 issuer、audience 和 subject信任转移到 IdP、Role 信任策略与该短期 JWT
SAML提交企业 IdP 签发的 SAML assertion适用于企业身份联合,依赖 IdP 信任和断言校验
mTLS / SPIFFE在 TLS 握手中出示客户端证书并证明持有对应私钥私钥不上网,但证书签发、轮换和本机密钥安全仍需平台保障
运行环境身份使用 Kubernetes ServiceAccount Token、云主机或容器身份尽量避免人工分发长期密钥,但仍依赖节点和平台控制面

“不要用静态密钥换临时凭证”是安全改进方向,不是 STS 的定义。AWS AssumeRole 就允许调用方使用现有 AWS 凭证签名请求;AssumeRoleWithWebIdentity 则用外部 JWT 换取临时凭证,请求不需要 AWS 凭证签名。前者仍有长期密钥的保管面,后者可以避免先向工作负载分发一对长期云 AK/SK。

2.6 第五阶段:外部身份和工作负载不再需要先持有长期 AK/SK

如果调用者必须先持有一对长期 AK/SK 才能调用 STS,泄露面虽然缩小了,却没有消除“第一把长期钥匙”。身份联合进一步允许 STS 验证企业 IdP、OIDC issuer 或云平台为工作负载提供的身份材料,再兑换成本云的角色会话。

因此,现代工作负载链路可以变成:

1
2
3
4
5
运行环境证明工作负载身份
  → STS 验证身份来源与 Role 信任条件
  → 返回短期 AK/SK/Token
  → SDK 自动轮换
  → 工作负载用临时凭证签名云 API 请求

这里消除的是长期凭证的人工分发,不是凭证本身。工作负载最终调用普通云 API 时,仍需要使用 STS 返回的云侧临时凭证。

2.7 Kubernetes 工作负载身份是一个具体案例

Kubernetes Pod 通过 spec.serviceAccountName 选择一个 ServiceAccount。多个 Pod 可以使用同一个 ServiceAccount,因此这不是 Pod 与 ServiceAccount 的一对一关系。

kubelet 可以通过 TokenRequest API 取得与 Pod 绑定的短期 ServiceAccount Token,再用 projected volume 挂载给容器。这个 token 是 JWT,可以指定 audienceexpirationSeconds,并由 kubelet 负责轮换。它是 Kubernetes 工作负载的身份断言,不应因为使用 JWT 和 OIDC discovery 便笼统称为“用户登录用的 OIDC ID Token”。

云厂商支持 web identity federation 时,完整链路可以是:

1
2
3
4
5
6
Pod 选择 ServiceAccount
  → kubelet 投射短期 JWT
  → 云 STS 校验 issuer、签名、audience 和 subject
  → 信任规则将工作负载身份映射到 Role
  → STS 返回临时云凭证
  → SDK 签名普通云 API 请求

ServiceAccount Token 只是证明工作负载身份的输入,不是最终调用云 API 的 AK/SK。AWS IRSA、EKS Pod Identity 与阿里云 RRSA 的交付细节也不完全相同,具体实现必须分别核验。

3. AK/SK 究竟是什么

3.1 AK 是标识,SK 是秘密

两家云对 AccessKey 的基本拆分一致:

  • AK / AccessKey ID 可以出现在请求中,用于标识正在使用哪份访问凭证;
  • SK / Secret Access Key / AccessKey Secret 必须保密,用于计算消息认证码形式的请求签名。

服务端根据 AK 找到相应凭证信息,按协议重新计算签名。签名匹配意味着请求方持有 SK,且参与签名的请求内容没有被修改。随后平台才把凭证关联到主体或会话并执行授权。

因此,请求签名主要回答:

1
2
3
这次请求是否由持有相应 SK 的调用者生成?
参与签名的 Method、URI、Query、Header、Body 是否保持完整?
时间戳、Nonce 或签名作用域是否满足协议限制?

它不直接回答“这个主体是否有权删除某个 Bucket”。那是 IAM/RAM 的授权问题。

3.2 长期与临时凭证不是两套 IAM

长期和临时凭证都服务于同一条“认证后授权”的链路:

维度长期凭证临时凭证
组成AK + SKAK + SK + Token + Expiration
常见关联对象IAM user / RAM 用户STS 创建的角色或联合身份会话
生命周期持续有效,直到禁用、删除或轮换签发时确定,到期失效
权限来源身份及相关策略角色权限与会话限制的组合
主要风险泄露窗口长,分发和轮换成本高仍可能在有效期内被盗用,但暴露窗口较短

临时凭证没有另起一套业务 API。调用方通常仍使用相应云服务的请求签名协议,只是必须额外提交安全令牌。

3.3 Session Token 能确认什么,内部怎样实现则未知

AWS 官方说明,临时请求必须带 Session Token,AWS 用它验证临时安全凭证;阿里云也要求临时调用同时提供 Security Token。由此能确认的是:

  • Token 是整组临时凭证不可缺少的一部分;
  • 它把一次普通的 AK/SK 签名调用标记为临时安全凭证调用;
  • 平台会结合它验证临时凭证及其角色会话是否有效。

公开文档没有说明 Token 内部究竟是数据库索引、自包含结构还是其他编码,也没有说明 AWS 或阿里云当初为何选择三个字段。不能把“Token 用于索引 Session”“为了兼容旧 SDK”“阿里云为了兼容 AWS”写成已确认事实。

从协议设计角度,临时 AK 本身也可以作为会话记录的索引,因此 AK + SK + Token 不是理论上的唯一方案。但这只能说明存在其他可行设计,不能反推出真实产品的历史动机或内部数据结构。

3.4 短期凭证缩小泄露窗口,不代表无法被盗用

STS 返回的临时 AK + SK + Token 仍是完整的调用凭证。攻击者如果在有效期内同时窃取这三项,仍可以生成合法的签名请求。STS 主要通过三个维度限制损失:

  • 有效期短,凭证会自动失效;
  • session policy、Role policy 与其他权限边界限制可用操作;
  • 临时会话和签发记录改善审计与追踪。

它没有自动防止“有效期内的重放”。要进一步让偷到 Token 的人也无法使用,需要 sender-constrained token:除了提交 Token,调用者还要证明自己持有 Token 绑定的私钥。PoP 是这类机制的总称,DPoP 和 mTLS 证书绑定是两种具体方案。

DPoP:在 HTTP 应用层证明持有私钥

OAuth DPoP 的 Access Token 可在 cnf.jkt 中携带客户端公钥的 JWK SHA-256 Thumbprint,即公钥指纹:

1
2
3
4
5
6
7
8
{
  "sub": "svc-order",
  "aud": "svc-inventory",
  "scope": "inventory:read",
  "cnf": {
    "jkt": "<DPoP 公钥的 SHA-256 指纹>"
  }
}

调用受保护资源时,客户端同时提交 Access Token 与一个对当前请求签名的 DPoP Proof JWT:

1
2
3
4
GET /inventory/42 HTTP/1.1
Host: inventory.example.com
Authorization: DPoP <access-token>
DPoP: <proof-jwt>

Proof 的 JOSE Header 中携带客户端公钥 jwk,Payload 至少用 jtihtmhtuiat 将证明绑定到某次 HTTP 请求。访问受保护资源时还必须用 ath 携带 Access Token 的哈希,将 Proof 与当前 Token 绑定。客户端用对应私钥签名 Proof。

1
2
3
4
Access Token.cnf.jkt == Hash(Proof Header 中的公钥)
Proof 签名可由该公钥验证
Proof.ath == Hash(当前 Access Token)
Proof.htm / htu == 当前请求的 Method / URI

公钥可以公开,它只能验证签名,不能生成签名。因此攻击者即使拿到 Access Token 和 Proof 中的公钥,没有私钥也无法为新请求生成合法 Proof。

证书绑定:在 mTLS 层证明持有私钥

OAuth mTLS Certificate-Bound Access Token 使用 cnf["x5t#S256"] 携带客户端 X.509 证书的 SHA-256 指纹。调用者在 TLS 握手中出示同一张客户端证书,并用私钥完成握手证明;资源服务再比较 TLS 客户端证书指纹与 Token 中的绑定值。

1
2
3
HTTP 层:Access Token
TLS 层:客户端证书 + 对应私钥的持有证明
Token.cnf["x5t#S256"] == Hash(TLS 客户端证书)

DPoP 与证书绑定解决的都是 Bearer Token “谁拿到谁就能用”的问题。它们不代替 Token:密钥持有证明回答“我控制这把私钥”,Token 仍负责表达 issuer、subject、audience、scope 和 expiration 等授权上下文。

PoP 是一个通用安全模型,不是 AWS STS 或阿里云 STS 临时 AK/SK 的默认协议层。本节用 OAuth DPoP 和 mTLS Token Binding 说明“临时”与“防盗用”是两个独立维度,不表示云厂商的 STS Token 默认带有 cnf

4. STS 与 IAM/RAM 怎样分工

IAM/RAM 与 STS 不是两个互相替代的权限系统:

组件核心职责
IAM / RAM管理身份、角色、信任关系和权限策略
STS根据既有信任与授权创建有限期会话并签发临时凭证
请求签名协议验证每次 API 请求对密钥的持有和请求完整性
云服务授权器将请求上下文与所有适用策略放在一起求值

STS 不凭空创造权限。以角色会话为例:

1
2
3
4
5
目标 Role 的基础权限
  ∩ Session Policy 等会话限制
  ∩ Permissions Boundary / SCP 等权限上限(若适用)
  ∩ 资源策略及其显式 Deny
  = 本次请求的有效权限

具体求值规则必须回到相应云厂商和云产品。AWS 与阿里云都存在显式拒绝优先等相似规则,但策略类型、组织级边界、资源策略支持范围和上下文键并非逐项等价。

5. 云 API 如何进入 IAM 授权模型

IAM Policy 描述的是 ActionResourceCondition,客户端发出的却是 HTTP 请求。两者之间还需要一层语义映射:服务端先按目标 API 的协议解析请求,再把请求转换成授权引擎能够求值的主体、动作、资源和上下文。

flowchart LR
    H[HTTP Request] --> P[按 API 风格解析请求]
    H --> S[验证请求签名]
    S --> I[识别 Principal]
    P --> A[识别 Action]
    P --> R[识别 Resource]
    P --> C[收集 Context]
    I --> E[IAM / RAM 策略求值]
    A --> E
    R --> E
    C --> E
    E -->|Allow| B[调用后端服务]
    E -->|Deny| D[拒绝请求]

这是一种理解云 API 横切链路的通用模型,不表示两家云公开确认了相同的内部网关架构。具体产品可以有独立前端、自建网关和不同的授权接入方式。

5.1 RPC 风格显式表达操作

阿里云官方把 OpenAPI 分为 RPC 和 ROA 两种风格。RPC 风格以操作为中心,请求通常使用固定的产品 Endpoint 和根路径,再用 API 名称、版本及业务参数表达调用意图。

在旧版 V2 请求中,API 名称和版本表现为 ActionVersion 公共参数:

1
2
3
4
5
POST / HTTP/1.1
Host: ecs.cn-hangzhou.aliyuncs.com
Content-Type: application/x-www-form-urlencoded

Action=DescribeInstances&Version=2014-05-26&RegionId=cn-hangzhou

在当前推荐的 V3 请求中,同类信息位于 x-acs-actionx-acs-version 请求头。表达位置变了,“以操作名识别 API”的 RPC 模型没有改变。

5.2 ROA 风格从 Method 与 Path 识别操作对象

ROA 是 Resource-Oriented Architecture。它把资源身份放进 URI Path,并结合 HTTP Method 表达操作:

1
2
GET /api/v1/clusters/<cluster-id> HTTP/1.1
Host: cs.aliyuncs.com

这类请求没有必要让客户端额外提交一个最终的 RAM Action 或完整资源 ARN。服务前端知道当前 API 的 Method、Path 模板和参数语义,可以据此识别正在调用的 API operation 以及请求指向的业务资源。

RPC 与 ROA 的边界也不能简化成“RPC 只用 GET/POST,ROA 就等于严格 REST”。实际 Method、Path、参数位于 Query 还是 Body,都应以具体 API 的 OpenAPI 元数据和产品文档为准。

5.3 请求参数不等于 IAM Resource

客户端通常只提交产品领域中的资源标识,例如实例 ID、Bucket 名称或对象 Key。Policy 中使用的 Resource 则是授权系统定义的规范资源标识:

1
2
3
请求参数或 Path 中的资源标识
  + 当前账号、Region、服务和 API 定义
  → 授权模型中的 Resource

同理,外部请求的 API 名称也需要与 Policy 语言中的 Action 对齐。AWS 的 Service Authorization Reference、阿里云各产品的 RAM 授权文档会分别定义可用 Action、Resource 类型和 Condition Key。

公开资料可以确认“请求结构由 API 元数据描述”和“策略按 Action、Resource、Condition 求值”。至于某个云产品内部由网关、业务前端还是独立鉴权组件完成映射,不能仅凭外部协议反推。

5.4 两种归一化服务于不同目标

这里容易把两个都带有“规范化”意味的过程混在一起:

过程输入输出目的
请求规范化Method、URI、Query、Headers、BodyCanonical Request让客户端和服务端对同一请求计算出相同签名输入
授权语义映射已解析请求、Principal、API 定义和运行上下文Principal、Action、Resource、Context让策略引擎判断本次操作是否允许

Canonical Request 不是 IAM 请求,也不会自动生成 Policy。它先解决“请求是否由密钥持有者生成、内容是否完整”;认证成功后,服务端才使用 API 语义进入授权求值。

阿里云 V3 签名把两种 API 风格收敛进同一个签名框架。二者的主要签名差异是:RPC 风格的 CanonicalURI 使用 /,ROA 风格使用 OpenAPI 元数据中的 path。这说明“签名规范统一”不等于“业务 API 风格消失”。

5.5 SDK 隐藏协议差异,不取消协议差异

OpenAPI 元数据描述 HTTP Method、Path、参数名称、类型和位置。SDK 可以据此构造请求、放置参数并完成签名;Darabonba 还可以描述不同网关和不同风格的 OpenAPI,并生成多语言 SDK。

因此,使用官方 SDK 时,调用方通常只面对 Client + Request 形式的接口。只有在手写 HTTP 请求、实现通用代理、排查签名错误或进行 SDK 泛化调用时,RPC/ROA、参数位置、Canonical URI 和产品专属认证机制才重新显露出来。

6. AWS IAM 的具体映射

6.1 身份与角色

  • AWS account 是资源和管理边界,root user 是创建账号时产生的特殊登录身份;
  • IAM user 是账号内的长期身份;
  • IAM user group 只聚合用户权限;
  • IAM role 没有标准长期凭证,被承担后产生 assumed-role session;
  • Role trust policy 定义可信 Principal,permissions policy 定义角色能访问的 Action 和 Resource。

跨账号 AssumeRole 通常需要双边条件:目标账号的 Role 信任调用方,调用方所在账号还要允许其执行 sts:AssumeRole。仅在 trust policy 中出现并不总是完整授权。

6.2 STS 与临时凭证

AWS STS 的多个 API 面向不同来源创建临时会话,例如 AssumeRoleAssumeRoleWithWebIdentityAssumeRoleWithSAMLGetSessionToken。它们的调用条件和会话权限并不完全相同,不能把所有 STS 调用都等同于角色扮演。

AssumeRole 可以附带 session policy 和 session tags。最终会话权限是 Role 的 identity-based policy 与 session policy 的交集,同时仍受其他适用策略约束。

6.3 SigV4

AWS Signature Version 4 的主线是:

1
2
3
4
5
6
HTTP Request
  → Canonical Request
  → Hash(Canonical Request)
  → String to Sign
  → 使用由 SK 派生的 signing key 计算签名
  → Authorization Header 或预签名 Query

Canonical Request 统一 Method、URI、Query、Headers 和 Payload hash,避免不同客户端对同一个请求产生不同表示。Credential scope 将签名绑定到日期、Region 和 Service;SigV4a 则以 Region Set 表达多 Region 作用域。

使用 STS 临时凭证时必须携带 X-Amz-Security-Token。它是否需要进入 canonical request 取决于具体服务,不能笼统断言 Session Token 永远不参与签名输入。

6.4 Policy 求值不是只看 Role 上的一张策略

AWS 的授权边界可能同时包含 identity-based policy、resource-based policy、permissions boundary、Organizations SCP 和 session policy。它们不是简单相加:适用的 Allow 只是起点,任一相关层的显式 Deny 都会拒绝请求;boundary、SCP 和 session policy 通常只负责限制上限,不能补出基础策略没有授予的权限。

Role 上尤其要区分两类策略:

  • trust policy 回答谁可以建立 Role session;
  • permissions policy 回答 session 建立后可以执行哪些业务操作。

跨账号 AssumeRole 因而通常有两次不同授权:先判断调用方能否建立目标 Role session,再判断这个 assumed-role session 能否访问业务资源。排障时不能因为信任策略已经允许,就跳过业务权限、资源策略和组织级边界。

6.5 Role、Session 与凭证是三个对象

Role 是长期存在的 IAM 配置实体;STS 成功处理 AssumeRole 后创建的是一次 assumed-role session;AccessKeyId + SecretAccessKey + SessionToken + Expiration 只是调用方使用该 session 的临时凭证。

1
2
3
4
5
IAM Role
  → STS AssumeRole
    → Assumed-role session
      → Temporary credentials
        → SigV4 signed request

session name 会进入 assumed-role ARN 和审计日志,用来区分多次角色会话,但它不是秘密,也不是授权凭证。原调用方身份不会被修改;后续使用临时凭证发出的请求代表新的 assumed-role session。

6.6 计算凭证交付与授权是两层问题

EC2 instance profile、ECS task role、EKS web identity 等机制都在解决“工作负载从哪里取得短期凭证”。SDK credential provider chain 可以从环境变量、共享配置、web identity、容器端点或 instance metadata 等来源寻找凭证。

这些机制不负责授予业务权限。最终权限仍取决于凭证关联的主体或 session,以及适用的 Role policy、session policy、资源策略和组织级边界。计算资源也不应被笼统理解为一个 IAM User;云 API 最终识别的是相应的 Role session 或其他受支持主体。

6.7 ARN 标识对象,不是凭证

ARN 用于在策略、API 和审计日志中标识资源或主体。IAM Role ARN 与 STS assumed-role ARN 分属不同命名空间:前者标识配置实体,后者标识一次具体会话。

  • ARN 回答“是谁或是什么”;
  • AccessKeyId 帮助定位凭证记录;
  • SecretAccessKey 用于证明密钥控制权;
  • SessionToken 绑定临时会话上下文。

把 ARN、AccessKeyId 和权限策略混成一个“身份字段”,会同时混淆标识、认证和授权。

7. 阿里云 RAM 的具体映射

7.1 RAM 不是 AWS Resource Access Manager

阿里云 RAM 的全称是 Resource Access Management,中文产品名为访问控制。它对应的是身份和访问控制系统。

AWS 也有一个缩写为 RAM 的独立服务,但其全称是 Resource Access Manager,用于跨账号共享受支持的 AWS 资源。讨论阿里云 RAM 与 AWS 对应关系时,AWS 侧产品应是 IAM,而不是 AWS RAM。

7.2 身份、资源属主与角色

  • 阿里云账号是资源属主和计费主体;RAM 身份创建的资源仍归所属阿里云账号;
  • RAM 用户是账号内有确定 ID、可配置密码或 AccessKey 的长期身份;
  • RAM 用户组用于批量组织 RAM 用户和权限;
  • RAM 角色没有登录密码或长期 AccessKey,需要被阿里云账号、RAM 身份、云服务或身份提供商等可信实体扮演;
  • 角色信任策略决定谁能扮演,角色权限策略决定扮演后能做什么。

阿里云权限策略分为系统策略和自定义策略。系统策略由阿里云维护,用户只能使用;自定义策略由用户创建和维护。新建 RAM 身份默认没有操作权限,需要显式授权。

7.3 阿里云 STS

阿里云 STS 是临时访问权限管理服务。RAM 用户或 RAM 角色可以在获得 sts:AssumeRole 权限且被目标角色信任后调用 AssumeRole;阿里云账号本身不能直接调用该接口。

调用成功后返回 AccessKeyIdAccessKeySecretSecurityTokenExpiration。请求中的 Policy 参数可以进一步收窄会话权限;指定时,有效权限是该 Policy 与目标 RAM 角色权限的交集。

阿里云文档常把整组临时凭证统称为“STS Token”或“安全令牌”。阅读时要结合上下文判断它指整组临时凭证,还是其中单独的 SecurityToken 字段,避免把二者混为一谈。

7.4 请求签名不是 SigV4 的同名复制

阿里云 OpenAPI 当前推荐 V3 签名。它也会构造 Canonical Request、计算请求摘要,并使用 AccessKey Secret 和 HMAC-SHA256 生成签名,但 Authorization 的算法标识和结构是阿里云自己的:

1
2
3
4
Authorization: ACS3-HMAC-SHA256
Credential=<AccessKeyId>,
SignedHeaders=<headers>,
Signature=<signature>

这一模型与 SigV4 有明显的共同思想,却不是 AWS SigV4。部分云产品使用自建网关和产品专属认证方式,手工签名时必须以目标产品的 API 文档为准。

8. 两家云哪里相同,哪里不能硬对齐

心智模型AWS阿里云能否直接等价
资源与账单边界AWS account阿里云账号抽象相近,账号治理细节不同
长期身份IAM userRAM 用户高度相近
用户集合IAM user groupRAM 用户组高度相近,均不是可扮演身份
无长期凭证的身份模板IAM roleRAM 角色高度相近
角色入口控制Role trust policyRAM 角色信任策略高度相近,语法和边界不同
临时凭证服务AWS STS阿里云 STS高度相近,API 约束不同
临时凭证AK/SK/SessionTokenAK/SK/SecurityToken结构相近,不是跨云通用凭证
API 请求签名SigV4/SigV4aOpenAPI V3 或产品专属机制思想相近,协议不兼容
资源标识ARNARN,前缀通常为 acs结构相似,命名空间不同

两家产品相似,首先说明它们面对同一组问题:账号内分权、跨账号委托、工作负载身份、短期授权和可审计调用。公开资料不足以证明相似设计具体来自历史兼容、生态模仿还是独立演进,因此更稳妥的结论是“问题和抽象趋同”,而不是替厂商补写设计史。

9. 一次角色访问的统一排障顺序

遇到权限错误时,不要先扩大 Policy。按链路逐层确认:

  1. 应用当前实际取得的是长期凭证还是 STS 临时凭证;
  2. 临时凭证是否同时包含 AK、SK、Token,是否已经到期;
  3. 当前凭证最终关联到哪个 User、Role session 或联合身份;
  4. 调用方是否允许执行 AssumeRole,目标 Role 是否信任它;
  5. Session policy 是否意外收窄权限;
  6. 身份策略、资源策略、权限边界和组织级策略是否存在显式 Deny 或缺少 Allow;
  7. 请求失败发生在签名认证阶段,还是认证成功后的业务授权阶段;
  8. Region、Service、时间、Nonce、Canonical URI、Query、Headers 和 Body hash 是否符合目标产品的签名规则。
  9. 如果使用 PoP,是 Token 本身失效,还是 Proof 签名、公钥指纹、ath、Method、URI、时间窗口或防重放校验失败。

AccessDenied 不一定说明 AK/SK 错误,SignatureDoesNotMatch 也不应该通过授予更大业务权限解决。先识别失败层次,再检查对应配置。

10. 复习索引

  1. IAM/RAM 管身份与权限,STS 创建短期会话,请求签名验证每一次 API 调用;
  2. 账号拥有资源,User 是长期身份,Group 只聚合用户,Role 是无长期凭证、可被承担的身份模板;
  3. AK 标识凭证,SK 生成签名;AK 不等于权限,也不是主体本身;
  4. 长期凭证是 AK/SK,STS 临时凭证还必须包含 Token 和到期时间;
  5. Session Token 的产品内部编码和设计动机没有公开,不把推测写成事实;
  6. Role 信任策略回答谁能扮演,权限策略回答扮演后能做什么;
  7. STS 不创造额外权限,session policy 只能收窄角色会话;
  8. AWS SigV4 与阿里云 V3 都采用规范化请求和 HMAC 思路,但不是同一协议;
  9. RPC 请求通常显式给出 API operation,ROA 请求则结合 Method、Path 和 API 元数据识别操作与资源;
  10. Canonical Request 服务于签名认证,Action/Resource/Context 映射服务于授权,不是同一个归一化过程;
  11. 现代工作负载优先通过运行环境身份换取短期凭证,避免人工分发长期 AK/SK;
  12. AWS IAM 与阿里云 RAM 的抽象相近,但策略求值、接口约束和产品能力必须分别查官方文档。
  13. STS 不消除初始身份;它在验证初始身份后,把日常使用的凭证变成短期、有限权限的会话凭证。
  14. 用现有 AK/SK 签名 AssumeRole 是有效模式;用 OIDC、SAML、mTLS 或平台工作负载身份,才能进一步避免人工分发长期云密钥。
  15. 短期凭证仍可在有效期内被盗用;PoP 再用私钥持有证明将 Token 限定给特定持有者。
  16. DPoP 通常使用 cnf.jkt 绑定公钥指纹,mTLS 证书绑定使用 cnf["x5t#S256"] 绑定证书指纹;cnf 不是云厂商 STS 临时凭证的默认字段。

11. 核验入口

AWS

  • AWS IAM User Guide:What is IAM、IAM roles、Policies and permissions;
  • AWS IAM User Guide:Request temporary security credentials、Use temporary credentials with AWS resources;
  • AWS IAM User Guide:Create a signed AWS API request、Authentication methods;
  • AWS STS API Reference:AssumeRoleGetSessionToken 等具体接口。
  • AWS IAM User Guide:Request temporary security credentials,用于区分需现有 AWS 凭证的 AssumeRole 与无需 AWS 凭证签名的 AssumeRoleWithWebIdentity

阿里云

  • 访问控制 RAM:什么是访问控制(RAM)、RAM 用户概览、RAM 角色概览;
  • 访问控制 RAM:权限策略概览、扮演 RAM 角色、什么是 STS;
  • STS OpenAPI:AssumeRole
  • 阿里云 SDK:OpenAPI 接口风格与请求结构;
  • 阿里云 SDK:V3 版本请求体与签名机制;
  • 阿里云 OpenAPI:Darabonba 与 SDK 泛化调用文档;
  • 具体云产品的请求签名文档:用于确认产品专属差异。

PoP 与工作负载身份

  • RFC 9449:OAuth 2.0 Demonstrating Proof of Possession(DPoP);
  • RFC 8705:OAuth 2.0 Mutual-TLS Client Authentication and Certificate-Bound Access Tokens;
  • Kubernetes Documentation:Service Accounts 与 TokenRequest 签发的短期 bound ServiceAccount Token。
本文由作者按照 CC BY 4.0 进行授权