konippi/create-github-app-token-aws-kms

GitHub: konippi/create-github-app-token-aws-kms

使用 AWS KMS 安全地为 GitHub App 生成安装访问令牌,避免私钥泄露。

Stars: 13 | Forks: 0

# 创建 GitHub App 令牌(AWS KMS) [![CI](https://static.pigsec.cn/wp-content/uploads/repos/2026/04/78defc1377001316.svg)](https://github.com/konippi/create-github-app-token-aws-kms/actions/workflows/ci.yml) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) GitHub Action,用于使用 AWS KMS 对 JWT 进行签名来创建 GitHub App 安装访问令牌。 一旦导入 KMS,私钥永远不会离开 HSM 边界 —— JWT 签名被委托给 KMS 的 `Sign` API,无需在 GitHub Secrets 中存储私钥。这遵循了 [GitHub 的官方建议](https://docs.github.com/en/apps/creating-github-apps/authenticating-with-a-github-app/managing-private-keys-for-github-apps#storing-private-keys),建议将私钥存储在密钥管理服务中并在运行时进行签名。 ## 工作原理 ``` sequenceDiagram participant WF as Workflow participant STS as AWS STS participant Action as This Action participant KMS as AWS KMS participant GH as GitHub API WF->>STS: 1. configure-aws-credentials (OIDC) STS-->>WF: Temporary credentials (env vars) WF->>Action: 2. Run action Action->>KMS: 3. Sign(JWT signing input) KMS-->>Action: 4. Signature bytes Action->>Action: 5. Assemble JWT Action->>GH: 6. JWT → Installation access token GH-->>Action: 7. Scoped access token Action->>WF: 8. Output token Note over Action,GH: Post step Action->>GH: 9. Revoke token ``` ## 用法 ### 基本用法(当前仓库) ``` permissions: id-token: write contents: read steps: - uses: aws-actions/configure-aws-credentials@7474bc4690e29a8392af63c5b98e7449536d5c3a # v4.3.1 with: role-to-assume: arn:aws:iam::123456789012:role/github-app-token-signer aws-region: ap-northeast-1 role-duration-seconds: 900 # Minimum 15 min — this action only needs KMS for a few seconds - uses: konippi/create-github-app-token-aws-kms@eb864f78285e18e84befd731e09fcc6e3fb7a4db # v1 id: app-token with: app-id: ${{ vars.APP_ID }} kms-key-id: ${{ vars.KMS_KEY_ID }} permission-contents: read - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: token: ${{ steps.app-token.outputs.token }} ``` ### 针对特定仓库的令牌 ``` - uses: konippi/create-github-app-token-aws-kms@eb864f78285e18e84befd731e09fcc6e3fb7a4db # v1 id: app-token with: app-id: ${{ vars.APP_ID }} kms-key-id: ${{ vars.KMS_KEY_ID }} owner: my-org repositories: | repo-a repo-b permission-contents: read permission-pull-requests: write ``` ### 针对组织中所有仓库的令牌 ``` - uses: konippi/create-github-app-token-aws-kms@eb864f78285e18e84befd731e09fcc6e3fb7a4db # v1 id: app-token with: app-id: ${{ vars.APP_ID }} kms-key-id: ${{ vars.KMS_KEY_ID }} owner: my-org permission-contents: read ``` ## 输入参数 | 输入项 | 是否必需 | 描述 | |--------|----------|------| | `app-id` | 是 | GitHub App ID | | `kms-key-id` | 是 | AWS KMS 密钥 ID、密钥 ARN、别名名称(`alias/...`)或别名 ARN | | `owner` | 否 | GitHub App 安装所有者。默认为当前仓库所有者 | | `repositories` | 否 | 仓库列表(逗号或换行分隔)。默认为当前仓库 | | `permission-*` | **至少一个** | 权限范围(例如 `permission-contents: read`)。参见 [权限](#permissions) | | `skip-token-revoke` | 否 | 如果为 `true`,任务完成后不会吊销令牌。默认值:`false` | | `github-api-url` | 否 | GitHub REST API URL。默认值:`${{ github.api_url }}` | ### 权限 必须至少设置一个 `permission-` 输入。可用权限如下: `permission-actions`、`permission-administration`、`permission-checks`、`permission-contents`、`permission-deployments`、`permission-environments`、`permission-issues`、`permission-members`、`permission-metadata`、`permission-packages`、`permission-pages`、`permission-pull-requests`、`permission-repository-hooks`、`permission-secret-scanning-alerts`、`permission-secrets`、`permission-security-events`、`permission-statuses`、`permission-vulnerability-alerts`、`permission-workflows` 取值:`read`、`write` 或 `admin`(根据适用情况)。 ## 输出 | 输出 | 描述 | |------|------| | `token` | GitHub 安装访问令牌 | | `installation-id` | GitHub App 安装 ID | | `app-slug` | GitHub App 标识符 | ## AWS 配置 此操作需要三个 AWS 资源。如果已存在用于 GitHub Actions 的 IAM OIDC 提供程序,则只需两个。 ### 1. IAM OIDC 提供程序 如果尚未为 `token.actions.githubusercontent.com` 创建,请跳过此步骤。 ``` aws iam create-open-id-connect-provider \ --url https://token.actions.githubusercontent.com \ --client-id-list sts.amazonaws.com ``` ### 2. KMS 密钥 创建一个具有 `EXTERNAL` 起源的 RSA 2048 密钥(以便可以导入自有密钥材料): ``` aws kms create-key \ --key-spec RSA_2048 \ --key-usage SIGN_VERIFY \ --origin EXTERNAL \ --description "GitHub App JWT signing key" ``` 然后将 GitHub App 私钥导入该 KMS 密钥。密钥材料必须为 PKCS#8 DER 二进制格式: ``` # 将 GitHub App PEM 转换为 PKCS#8 DER openssl pkcs8 -topk8 -inform PEM -outform DER -in github-app-private-key.pem -out private-key.der -nocrypt ``` 接着包装并导入密钥材料。详见 [AWS 导入密钥材料文档](https://docs.aws.amazon.com/kms/latest/developerguide/importing-keys.html) 和 [将非对称密钥迁移到 AWS KMS](https://aws.amazon.com/blogs/security/how-to-migrate-asymmetric-keys-from-cloudhsm-to-aws-kms/)。 附加仅允许使用特定算法进行 `kms:Sign` 的密钥策略: ``` { "Version": "2012-10-17", "Statement": [ { "Sid": "AllowSignOnly", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::123456789012:role/github-app-token-signer" }, "Action": "kms:Sign", "Resource": "*", "Condition": { "StringEquals": { "kms:SigningAlgorithm": "RSASSA_PKCS1_V1_5_SHA_256" } } } ] } ``` ### 3. IAM 角色 + 信任策略 创建一个 IAM 角色,并使用 [提供程序特定的 OIDC 声明](https://aws.amazon.com/about-aws/whats-new/2026/01/aws-sts-supports-validation-identity-provider-claims) 配置信任策略(自 2026 年 1 月起可用): ``` { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Federated": "arn:aws:iam::123456789012:oidc-provider/token.actions.githubusercontent.com" }, "Action": "sts:AssumeRoleWithWebIdentity", "Condition": { "StringEquals": { "token.actions.githubusercontent.com:aud": "sts.amazonaws.com", "token.actions.githubusercontent.com:repository_id": "YOUR_REPO_ID", "token.actions.githubusercontent.com:job_workflow_ref": "your-org/your-repo/.github/workflows/deploy.yml@refs/heads/main" }, "StringLike": { "token.actions.githubusercontent.com:sub": "repo:your-org/your-repo:*" } } } ] } ``` ## 降级方案 如果 AWS KMS 不可用(区域故障或服务中断),可以临时切换到 [actions/create-github-app-token](https://github.com/actions/create-github-app-token),并将私钥存储在 GitHub Secrets 中。这会降低安全姿态,但可防止 CI/CD 完全中断。 ## 许可证 [MIT](LICENSE)
标签:AWS KMS, AWS STS, GitHub Action, GitHub App, GitHub官方推荐, IAM角色, JWT签名, OIDC, 安全令牌, 安装访问令牌, 密钥不落地, 密钥轮换, 密钥零暴露, 权限最小化, 硬件安全模块, 签名委托, 自动化令牌发放, 自动化攻击, 运行时签名