aws-actions/configure-aws-credentials は AWS の Role を assume する Actionで、 Access Key による認証もサポートしているが、GitHub の OIDC Provider が発行した JWT を用いることで認証情報を持つことなくセキュアにAPIを呼ぶことができる。
OpenID ConnectのIDトークンの内容と検証 - sambaiz-net
外部の Provider を信頼するにあたり、HTTPS通信する際のチェーン最上位の中間認証局の証明書の thumbprint を登録する必要がある。 thumbprint は次のようにして取得できる。 以前中間認証局が変更された際は併せて thumbprint も更新する必要があった。
$ openssl s_client -servername token.actions.githubusercontent.com -showcerts -connect token.actions.githubusercontent.com:443
CONNECTED(00000005)
depth=2 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Global Root CA
verify return:1
depth=1 C = US, O = DigiCert Inc, CN = DigiCert TLS RSA SHA256 2020 CA1
verify return:1
depth=0 C = US, ST = California, L = San Francisco, O = "GitHub, Inc.", CN = *.actions.githubusercontent.com
verify return:1
---
Certificate chain
0 s:/C=US/ST=California/L=San Francisco/O=GitHub, Inc./CN=*.actions.githubusercontent.com
i:/C=US/O=DigiCert Inc/CN=DigiCert TLS RSA SHA256 2020 CA1
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
1 s:/C=US/O=DigiCert Inc/CN=DigiCert TLS RSA SHA256 2020 CA1
i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Global Root CA
/* certificate.crt
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
*/
...
$ openssl x509 -in certificate.crt -fingerprint -noout
SHA1 Fingerprint=69:38:FD:4D:98:BA:B0:3F:AA:DB:97:B3:43:96:83:1E:37:80:AE:A1
trust policy の Condition で sub で渡ってくるリポジトリ名などによる制限をかける。
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as iam from 'aws-cdk-lib/aws-iam';
import * as s3 from 'aws-cdk-lib/aws-s3';
export class GitHubDeployStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const deployBucket = new s3.Bucket(this, 'DeployBucket', {
bucketName: `${this.stackName.toLowerCase()}-${this.account}-deploy-bucket`
})
const provider = new iam.OpenIdConnectProvider(this, 'Provider', {
url: 'https://token.actions.githubusercontent.com',
thumbprints: ['6938fd4d98bab03faadb97b34396831e3780aea1'],
clientIds: ['sts.amazonaws.com'],
});
const deployRole = new iam.Role(this, 'DeployRole', {
roleName: `${this.stackName}_DeployRole`,
assumedBy: new iam.WebIdentityPrincipal(provider.openIdConnectProviderArn, {
StringLike: {
['token.actions.githubusercontent.com:sub']: 'repo:<user_name>/<repository_name>:*',
},
})
})
deployRole.addToPolicy(new iam.PolicyStatement({
actions: ["s3:PutObject*"],
resources: [`${deployBucket.bucketArn}/*`],
}));
this.exportValue(deployRole.roleArn)
this.exportValue(deployBucket.bucketName)
}
}
この Role を assume することで aws s3 cp などが行えるようになる。
name: CI
on:
push:
env:
DEPLOY_ROLE_NAME: "arn:aws:iam::<AWSAccountID>:role/GitHubDeployStack_DeployRole"
DEPLOY_BUCKET_NAME: "githubdeploystack-<AWSAccountID>-deploy-bucket"
AWS_REGION: "ap-northeast-1"
permissions:
id-token: write # This is required for requesting the JWT
contents: read # This is required for actions/checkout
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v1
with:
role-to-assume: ${{ env.DEPLOY_ROLE_NAME }}
aws-region: ${{ env.AWS_REGION }}
参考
AWS CDKで Github ActionsのOIDC連携用のIAM Roleを作成する | DevelopersIO