通过自建的 oidc.cipherhub.cloud 服务,利用 OIDC 协议为应用换取 AWS 临时凭证,从而安全地访问 AWS 云 API。

一、 前置准备

  1. 允许公网 HTTPS 访问
  • oidc.cipherhub.cloud 必须支持 HTTPS,且证书由受信任的 CA(如 Let’s Encrypt)签发。
  • AWS 不信任自签名证书
  1. 设置固定 Issuer 域名
  • 确保服务通过 https://oidc.cipherhub.cloud(无尾部斜杠)对外暴露。
  1. 确定受众 ID (Audience)
  • 在代码和 AWS 配置中,必须统一使用一个标识符(本示例中使用 cipherhub-client)。

QQ_1772272049545

二、 AWS 端配置步骤(控制台操作)

1. 创建 IAM 身份提供商 (Identity Provider)

这是让 AWS “认识”并“信任”您域名的关键步骤。

  1. 登录 IAM 控制台 -> 身份提供商 -> 添加提供商
  2. 类型:选择 OpenID Connect
  3. 提供商 URL:输入 https://oidc.cipherhub.cloud
  4. 受众:输入 cipherhub-client
  5. 获取指纹 (Thumbprint):点击按钮。AWS 会连接您的服务器并计算 SSL 证书的 SHA1 哈希。

QQ_1772272073449

QQ_1772272125389

2. 创建 IAM 角色并配置“信任策略”

  1. 创建一个新角色,选择 Web 身份 方案。

  2. 选择刚才创建的 oidc.cipherhub.cloud 提供商。

    Clipboard_Screenshot_1772272157

    QQ_1772272182059

  3. 编辑信任策略 (Trust Policy)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "arn:aws:iam::ACCOUNT_ID:oidc-provider/oidc.cipherhub.cloud"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "oidc.cipherhub.cloud:aud": "cipherhub-client"
        }
      }
    }
  ]
}

QQ_1772272739441

3. 为角色授予 Secrets Manager 权限

  1. 为该角色附加一个 内联策略,允许其读取特定的秘密:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "SecretsManagerFullAccess",
            "Effect": "Allow",
            "Action": [
                "secretsmanager:*"
            ],
            "Resource": "*"
        },
        {
            "Sid": "KMSFullAccess",
            "Effect": "Allow",
            "Action": [
                "kms:*"
            ],
            "Resource": "*"
        }
    ]
}

QQ_1772273213350

三、 交互架构与接口逻辑

1. 核心接口说明

  • GET /.well-known/openid-configuration

  • 作用:AWS 初始化连接时调用,获取发行者信息和公钥位置。

  • GET /keys

  • 作用:AWS 验证令牌签名时调用,下载您的 RSA 公钥参数。

  • GET /generate-token (自定义)

  • 作用:供您的应用调用,生成用于交给 AWS 的 JWT 令牌。

2. JWT 令牌声明要求

签发的令牌必须包含以下字段,否则 AWS 会拒绝换证:

  • iss: 必须完全等于 https://oidc.cipherhub.cloud
  • aud: 必须等于 cipherhub-client
  • sub: 身份标识(如用户 ID)
  • exp: 过期时间(建议 3600 秒内)

四、 运行流程演示

  1. 应用端:请求 oidc.cipherhub.cloud/generate-token 拿到 id_token

    1
    
    OIDC_TOKEN=$(curl -s "https://oidc.cipherhub.cloud/generate-token?audience=cipherhub-client" | jq -r '.id_token')
  2. 换证端:使用 AWS CLI 或 SDK 提交该令牌:

1
2
3
4
5
6
TMP_CREDENTIALS=$(aws sts assume-role-with-web-identity --role-arn arn:aws:iam::353472442111:role/IODC-CipherHUB --role-session-name oidc-cipherhub-session --web-identity-token "$OIDC_TOKEN")

export AWS_ACCESS_KEY_ID=$(echo $CREDENTIALS | jq -r '.Credentials.AccessKeyId')
export AWS_SECRET_ACCESS_KEY=$(echo $CREDENTIALS | jq -r '.Credentials.SecretAccessKey')
export AWS_SESSION_TOKEN=$(echo $CREDENTIALS | jq -r '.Credentials.SessionToken')
export AWS_DEFAULT_REGION="ap-northeast-1"

执行aws sts assume-role-with-web-identity请求时,aws向oidc.cipherhub.cloud发起请求:

QQ_1772276281727

  1. 结果:获得临时 AccessKeyId,随后即可访问 Secrets Manager 或 KMS

    QQ_1772273743130

    在调用 KMS 之前,先运行以下命令确认 AWS CLI 已经切换到了 OIDC 角色身份:

    1
    
    aws sts get-caller-identity

    QQ_1772276813874

  2. 使用 KMS 接口

    1
    2
    3
    4
    5
    
    aws kms list-keys
    
    aws kms encrypt --key-id "your-key-id-or-alias" --plaintext $(echo "hello cipherhub" | base64) --query CiphertextBlob --output text
    
    aws kms decrypt --ciphertext-blob fileb://<(echo "你的加密字符串" | base64 -d) --query Plaintext --output text | base64 -d