角色、临时凭证与 SigV4

开发者的 AWS 安全实践

Rahul Singh

Technical Product Manager

寿命长过任务的密钥

为提速,脚本里创建了一个密钥并存入配置文件。

文件里的它:

  • 从不轮换
  • 从不吊销
  • 从不过期

一个访问密钥扩散到六处存储位置,右侧时间轴显示到第 18 个月仍然有效

开发者的 AWS 安全实践

寿命长过任务的密钥

为提速,脚本里创建了一个密钥并存入配置文件。

文件里的它:

  • 从不轮换
  • 从不吊销
  • 从不过期

 

18 个月后,它仍然有效

一个访问密钥扩散到六处存储位置,右侧时间轴显示到第 18 个月仍然有效

开发者的 AWS 安全实践

自动过期的凭证

用 AWS STS 将过期设为默认

  1. 申请角色,获取自带时钟的凭证

  2. Security Token Service(STS):自带过期,默认 1 小时

应用调用 AWS STS 的 AssumeRole,STS 返回带内置时钟的凭证。

开发者的 AWS 安全实践

自动过期的凭证

用 AWS STS 将过期设为默认

  1. 申请角色,获取自带时钟的凭证

  2. 临时凭证以 ASIA 开头并携带会话令牌

  3. Security Token Service(STS):自带过期,默认 1 小时

应用调用 AWS STS 的 AssumeRole 并收到带内置时钟的凭证。其下方并列两种凭证:以 AKIA 开头、无会话令牌且永不过期的长期密钥,与以 ASIA 开头、带会话令牌且 1 小时后过期的临时凭证。

开发者的 AWS 安全实践

自动过期的凭证

用 AWS STS 将过期设为默认

  1. 申请角色,获取自带时钟的凭证

  2. 临时凭证以 ASIA 开头并携带会话令牌

  3. 相同调用先被接受,随后不再接受

  4. Security Token Service(STS):自带过期,默认 1 小时

应用调用 AWS STS 的 AssumeRole 并收到带内置时钟的凭证。其下方:永不过期的 AKIA 长期密钥与 1 小时后过期、带会话令牌的 ASIA 临时凭证。再下方:同一次 GetObject 调用在 10:00 返回 200 OK,在 11:05 返回 ExpiredToken。

开发者的 AWS 安全实践

代码如何找到它们

检查凭证提供程序链

  • AWS SDK(您代码中的库)负责查找
  • 固定列表,按顺序检查
  • 命中即停

凭证查找顺序:代码中传入的密钥在链上方被划掉,随后按环境变量、配置文件、容器凭证向下搜索,命中即停,永远不会到达实例元数据

开发者的 AWS 安全实践

代码如何找到它们

检查凭证提供程序链

  • AWS SDK(您代码中的库)负责查找
  • 固定列表,按顺序检查
  • 命中即停

 

硬编码的密钥最先被检查,因此需要删除

凭证查找顺序:代码中传入的密钥在链上方被划掉,随后按环境变量、配置文件、容器凭证向下搜索,命中即停,永远不会到达实例元数据

开发者的 AWS 安全实践

逐环查看这条链

1. explicit      a key passed in your code
2. environment   AWS_* variables, and on Lambda
                 that is the execution role
3. config file   ~/.aws/credentials
4. container     ECS or EKS task role
5. instance      EC2 instance profile, via IMDS
  • 先匹配者胜
  • 删除已存密钥,搜索将继续到角色
开发者的 AWS 安全实践

在 AWS 外证明身份

代码流水线常在 AWS 之外运行,无法附加凭证链

  • 运行于 GitHub 或 GitLab
  • 链上无可查找之物

一个 CI 运行器及其平台画在 AWS 边界之外,运行器标注为无可附加角色,平台签发一个 OIDC 令牌,指明一个仓库和一个工作流

开发者的 AWS 安全实践

在 AWS 外证明身份

代码流水线常在 AWS 之外运行,无法附加凭证链

  • 运行于 GitHub 或 GitLab
  • 链上无可查找之物

 

OIDC 令牌(OpenID Connect)

  • 已签名且短时有效
  • 身份声明,而非凭证

一个 CI 运行器及其平台画在 AWS 边界之外,运行器标注为无可附加角色,平台签发一个 OIDC 令牌,指明一个仓库和一个工作流

开发者的 AWS 安全实践

用规则替代存储密钥

一个指明仓库的 OIDC 令牌,通过 AssumeRoleWithWebIdentity 交换为 1 小时后过期的临时凭证,因为该角色的信任策略已事先指定该签发方与该仓库

用令牌换取凭证

开发者的 AWS 安全实践

用规则替代存储密钥

一个指明仓库的 OIDC 令牌,通过 AssumeRoleWithWebIdentity 交换为 1 小时后过期的临时凭证,因为该角色的信任策略已事先指定该签发方与该仓库

用令牌换取凭证

  • AssumeRoleWithWebIdentity:AssumeRole,但用外部令牌作证明
  • 信任策略:预先写在角色上,不存于流水线
  • Claim:令牌中的一条事实
  • 平台的 Issuer 为所有仓库共享,因此也要固定仓库

仓库密钥:已清空

开发者的 AWS 安全实践

每个请求都会被签名

签名版本 4(SigV4)

  • 证明是哪条凭证发起了请求
  • 证明请求在传输中未被篡改
  • 每次调用由 CLI 与 SDK 自动签名

签名流程:请求与您的凭证生成签名,放入 Authorization 头发送;AWS 重新计算并比较,匹配则接受,不匹配返回 SignatureDoesNotMatch

开发者的 AWS 安全实践

可转交的签名

临时凭证

  • 多种操作,由角色限定范围
  • 由您的代码持有

您的代码使用临时凭证调用四个 AWS 服务:S3、DynamoDB、SQS 和 KMS

开发者的 AWS 安全实践

可转交的签名

临时凭证

  • 多种操作,由角色限定范围
  • 由您的代码持有

预签名 URL

  • 一个对象、一个动作,持有链接者皆可用
  • 过期时间自定,其后失效
  • 承载您的权限,而非持有者的

您的代码使用临时凭证调用四个 AWS 服务:S3、DynamoDB、SQS 和 KMS

他人的浏览器通过唯一路径访问恰好一个对象,中间有一只时钟标注您设置的过期时间

开发者的 AWS 安全实践

让我们一起练习吧!

开发者的 AWS 安全实践

Preparing Video For Download...