Earthly 构建中的 AWS OIDC 认证配置与源码原理全解
【免费下载链接】earthlySuper simple build framework with fast, repeatable builds and an instantly familiar syntax – like Dockerfile and Makefile had a baby.项目地址: https://gitcode.com/gh_mirrors/ea/earthly
Earthly 的 OpenID Connect (OIDC) 认证能力允许构建过程直接向第三方云厂商(目前支持 AWS)换取临时凭证,从而在 CI 中无需存储任何长期密钥,也无需本地环境凭据。本指南以 docs/cloud/oidc.md 为主线,完整覆盖 AWS IAM OIDC Provider 与信任策略的配置步骤、RUN --aws --oidc的实战用法,并结合当前仓库源码剖析 OIDC 规格解析、特性开关与凭证注入的底层实现,帮助读者在 CI(尤其是强制 MFA 的场景)中安全地让构建访问 AWS 资源。
为什么需要 OIDC:摆脱 CI 中的密钥存储与 MFA 困境
在常规的 CI 流水线中,要让构建访问 AWS 资源,通常有两种做法:把 AWS Access Key 作为明文 secret 存进 CI 环境,或者把本地环境的临时凭证带入构建。这两种方式都存在明显短板:
- 长期密钥一旦泄露,影响范围大且难以追踪;
- 本地凭据与 CI 环境耦合,可移植性差;
- 在强制启用 MFA(多因素认证)的团队中,CI 无法像人一样完成交互式二次认证,导致自动化受阻。
OIDC 协议恰好解决了这一问题:构建过程中由 Earthly Cloud 签发的 ID Token 直接向 AWS 换取短期临时凭证,全程无需在 CI 或本地存储任何长期凭据。这也正是该特性被设计为面向 CI 场景的主要原因,其完整说明位于 oidc.md。
当前仓库中该能力只对 AWS 提供支持(源码注释// we currently only support oidc for AWS明确此点),其他云厂商的接入属于未来扩展方向。
配置流程总览
在 Earthfile 中使用 AWS OIDC 前,需要完成两部分工作:
- AWS 侧配置(一次性):在 AWS IAM 中注册 Earthly 作为 OIDC Provider,并创建可被该 Provider 承担的 IAM Role;
- Earthfile 侧配置:开启
VERSION --run-with-aws --run-with-aws-oidc 0.8特性,并在RUN命令中使用--aws --oidc标志。
第一步:在 AWS IAM 中注册 Earthly OIDC Provider
参照 AWS IAM 官方文档创建 OIDC identity provider,关键配置如下:
| 配置项 | 值 |
|---|---|
| Provider URL | https://api.earthly.dev |
| Audience | sts.amazonaws.com |
即:Earthly Cloud 的令牌签发端点https://api.earthly.dev作为受信任的身份源,sts.amazonaws.com作为 audience(受众),表示这些令牌专门用于调用 AWS STS 服务。
第二步:创建(或复用)IAM Role 并配置信任策略
创建一个新的 IAM Role,或复用已有的 Role,并注意两点:
- 限制权限:Role 所附的策略决定了承担该角色后能执行哪些操作,务必遵循最小权限原则;
- 限制谁可以承担:通过信任策略(trust policy)精确指定允许承担的 Earthly 组织/项目成员。
一个典型的信任策略示例如下:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Federated": "<oidc-provider-name>" }, "Action": "sts:AssumeRoleWithWebIdentity", "Condition": { "StringEquals": { "api.earthly.dev:aud": "sts.amazonaws.com", "api.earthly.dev:sub": "<earthly-org>/<earthly-project>" } } } ] }其中各占位符含义如下:
<oidc-provider-name>:第一步中创建的 OIDC Provider 的 ARN;<earthly-org>:用户所属的 Earthly 组织,在 Earthfile 的PROJECT指令或构建执行参数中指定(下文详述);<earthly-project>:用户拥有读取权限的 Earthly 项目(权限等级详见 managing-permissions.md),同样在PROJECT指令或构建执行参数中指定。
信任策略的灵活组合
信任策略的Condition部分支持多种规则,可以按需混合搭配,精确控制团队内谁能承担该 Role:
允许整个组织所有成员访问(使用StringLike+ 通配符):
"Condition": { "StringLike": { "api.earthly.dev:sub": "<earthly-org>/*" } }仅允许指定用户访问(基于与 Earthly 账号绑定的邮箱):
"Condition": { "StringEquals": { "api.earthly.dev:email": "<user-email>" } }其中<user-email>是该用户 Earthly 账号对应的邮箱地址。
第三步:在 Earthfile 中使用 OIDC 访问 AWS
OIDC 配置完成后,即可在构建中访问 AWS 资源。原文档给出了一个列出 S3 对象的完整示例:
VERSION --run-with-aws --run-with-aws-oidc 0.8 PROJECT <your-org>/<your-project> aws: FROM amazon/aws-cli LET OIDC="role-arn=arn:aws:iam::1234567890:role/your-oidc-role,session-name=my-session,region=us-east-1" RUN --aws --oidc=$OIDC aws s3 ls逐行解读这个示例:
VERSION --run-with-aws --run-with-aws-oidc 0.8:同时开启两个实验特性。--run-with-aws允许RUN命令使用 AWS 凭据(features.go),--run-with-aws-oidc则允许通过 OIDC Provider 获取 AWS 凭据(features.go);PROJECT <your-org>/<your-project>:声明本次构建所属的 Earthly 组织与项目,信任策略中的api.earthly.dev:sub即与此对应;LET OIDC="...":以逗号分隔的键值对定义 OIDC 规格,支持 ARG 展开;RUN --aws --oidc=$OIDC aws s3 ls:执行命令前,Earthly 通过 OIDC 换取临时 AWS 凭据并注入命令环境。
--oidc规格详解:四个可配置键
RUN --aws --oidc=<oidc-spec>中的<oidc-spec>是一串逗号分隔的键值对,允许的键及含义见 earthfile.md:
| 键 | 说明 | 示例 |
|---|---|---|
session-name | 出现在 AWS 日志中的会话名称。若多个RUN ... --oidc命令使用相同session-name,它们将共享同一个临时令牌 | session-name=my-session |
role-arn | 要为其获取凭据的 AWS Role 的 ARN | role-arn=arn:aws:iam::123456789012:role/some-role |
region | 获取凭据时连接的 AWS 区域,同时也是后续 AWS 命令默认使用的区域(可在命令中覆盖);不指定则使用 AWS 全局端点 | region=us-east-1 |
session-duration | 临时凭据的有效时长,默认取 AWS 最小值 15 分钟 | session-duration=20m |
源码中的解析与校验规则
<oidc-spec>的解析实现在 util/oidcutil/aws.go,其行为可以作为上述表格的补充证据:
ParseAWSOIDCInfo(aws.go)首先把字符串解析为键值映射,再通过mapstructure解码为AWSOIDCInfo结构体(aws.go);role-arn与session-name是必填项,缺失会直接报错(requiredFields定义于 aws.go);- 出现未知键同样报错(
key(s) [...] are invalid); role-arn必须是iam服务且资源以role/开头的合法 ARN(aws.go);session-duration必须落在900 秒(15 分钟)到 43200 秒(12 小时)之间(aws.go),超出范围会提示duration must be between 900s and 43200s。
底层实现:从 Earthfile 到临时凭据注入
RUN --aws --oidc的完整调用链横跨解释器与转换器两个模块,理解它有助于排查问题。
解释器阶段:特性开关与前置校验
earthfile2llb/interpreter.go的handleOIDC函数(interpreter.go)负责处理该标志,依次执行:
- 若未开启
--run-with-aws-oidc特性,报错RUN --aws-oidc requires the --run-with-aws-oidc feature flag; - 若未同时使用
--aws,报错RUN --oidc also requires the --aws RUN flag; - 对
<oidc-spec>执行 ARG 展开(expandArgs),因此LET OIDC="role-arn=$ROLE_ARN,..."这类引用变量的写法是合法的; - 调用
oidcutil.ParseAWSOIDCInfo完成上节所述的解析与校验。
转换器阶段:以 Secret 形式注入 AWS 凭据
earthfile2llb/converter.go的awsSecrets函数(converter.go)负责将凭据接入构建:
- 当
OIDCInfo非空时,把 OIDC 信息编码进 secret ID 的查询参数(secretprovider.SetURLValuesFunc); - 为每个 AWS 凭据项(
secretprovider.AWSCredentials)创建 LLB secret,挂载到/run/secrets/<name>,权限0444; - 同时生成对应的环境变量赋值(如
AWS_ACCESS_KEY_ID="$(cat /run/secrets/...)")注入命令环境。
也就是说,OIDC 换取到的临时凭据最终是以构建内 secret + 环境变量的形式提供给RUN命令的,命令本身并不接触任何明文密钥。
与其他命令的联动
OIDC 信息不仅作用于普通RUN,也会传递到WITH DOCKER场景:解释器在handleOIDC后将其写入i.withDocker.OIDCInfo(interpreter.go),并在WITH DOCKER的四种执行路径(本地 registry、本地 tar、远程 registry、远程 tar)中一并传入(参见 with_docker_run_local_reg.go、with_docker_run_local_tar.go、with_docker_run_reg.go、with_docker_run_tar.go),即 Docker 容器内执行命令时同样可以拿到 AWS 临时凭据。
集成测试:仓库如何验证该能力
仓库的 tests/oidc 目录提供了完整的集成测试,可作为可复现的参考用例:
- aws.earth:以
VERSION --run-with-aws --run-with-aws-oidc 0.8开头,声明PROJECT other-service+oidc-ci-test/my-project。oidc目标先用普通RUN验证环境变量中没有任何AWS_前缀变量(基线为 0),再通过RUN --aws --oidc=$OIDC验证环境变量数量变为 4(即临时凭据已注入); oidc-with-docker目标在WITH DOCKER块内重复同样的断言,验证容器内凭据注入同样生效;- test-aws.sh 驱动测试执行;Earthfile 中
test-aws-failure目标则验证了信任策略错误时的失败行为——使用一个不存在的 Role ARN,断言输出中包含make sure the role "..." has a valid trust policy configured in AWS的提示。
注意事项与限制
- 实验特性:
RUN --aws与RUN --oidc均为 experimental 状态,必须通过VERSION --run-with-aws --run-with-aws-oidc 0.8显式开启(对应源码 features.go 中标记为 unreleased 的特性开关); - 仅支持 AWS:当前实现只覆盖 AWS,
--oidc也只能与--aws组合使用,单独使用会直接报错; - PROJECT 声明的重要性:信任策略通过
api.earthly.dev:sub(<org>/<project>)与api.earthly.dev:email进行条件匹配,因此 Earthfile 中的PROJECT指令必须与实际组织/项目一致,否则 STS 换证会失败; - 凭据为短期令牌:默认有效期 15 分钟(可通过
session-duration延长至最多 12 小时),令牌过期后需要重新换取; - 最小权限原则:Role 的权限策略与信任策略应尽量收紧,仅授予构建实际需要的 AWS 操作。
小结
Earthly 的 AWS OIDC 集成让构建可以"无密钥"地访问云资源:AWS 侧注册 Provider、配置信任策略,Earthfile 侧开启特性并声明PROJECT,再以RUN --aws --oidc换取短期临时凭据。从 oidc.md 的配置指南,到 oidcutil/aws.go 的严格校验,再到 converter.go 的 secret 注入,整条链路在仓库中均有清晰的实现与测试佐证,适合作为 CI 安全访问 AWS 的落地模板。
【免费下载链接】earthlySuper simple build framework with fast, repeatable builds and an instantly familiar syntax – like Dockerfile and Makefile had a baby.项目地址: https://gitcode.com/gh_mirrors/ea/earthly
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考