Source: infrastructure/establish-trust-stack.js

const { Stack, Duration } = require('aws-cdk-lib')
const {
  OpenIdConnectProvider,
  OpenIdConnectPrincipal,
  Role,
  Effect,
  PolicyDocument,
  PolicyStatement
} = require('aws-cdk-lib/aws-iam')

/**
  * @class
*/
class EstablishTrustStack extends Stack {
  /**
   * Establishes trust between GithHub and Amazon Web Services.
   * This is needed so that we can interact with Amazon Web Services through
   * GitHub Actions without having to manually provide credentials every time we
   * run a workflow
   *
   * @param {object} scope - scope
   * @param {string} id - id
   * @param {PlatformTemplate} props - PlatformTemplate
   */
  constructor(scope, id, props) {
    super(scope, id, props)

    const provider = new OpenIdConnectProvider(this, 'GitHubProvider', {
      url: 'https://token.actions.githubusercontent.com',
      clientIds: ['sts.amazonaws.com']
    })

    const GitHubPrincipal = new OpenIdConnectPrincipal(provider)
      .withConditions({
        StringLike: {
          'token.actions.githubusercontent.com:sub':
            `repo:${props.config.ciGithubActionsRepo}:*`
        }
      })

    // eslint-disable-next-line no-new
    new Role(this, 'GitHubActionsRole', {
      assumedBy: GitHubPrincipal,
      description: 'Role assumed by GitHubPrincipal for deploying from CI using aws cdk',
      roleName: props.config.awsRoleToAssume,
      maxSessionDuration: Duration.hours(1),
      inlinePolicies: {
        CdkDeploymentPolicy: new PolicyDocument({
          assignSids: true,
          statements: [
            new PolicyStatement({
              effect: Effect.ALLOW,
              actions: ['sts:AssumeRole'],
              resources: [
                `arn:aws:iam::${props.config.awsAccountId}:role/cdk-*`,
                `arn:aws:sqs:${props.config.awsRegion}:${props.config.awsAccountId}:*`
              ]
            })
          ]
        })
      }
    })
  }
}

module.exports = {
  EstablishTrustStack
}