Pipelines takes a defense in depth approach to securing workflows. This document provides an overview of the controls that Pipelines employs to ensure that only infrastructure that has been written in code and approved by a reviewer can be deployed in your AWS accounts.
Pipelines dual-repository approach separates infrastructure definitions from infrastructure deployment mechanisms. Pipelines requires two repositories —
infrastructure-pipelines, where deployment workflows are defined and
infrastructure-live, where infrastructure is defined as code. Each repository should have branch protection rules to prevent un-reviewed code from being deployed. Refer to Recommended Settings in Branch Protection to learn more.
To control access to these repositories we recommend creating GitHub teams. Write access to the
infrastructure-pipelines repository should be limited to individuals that already have administrative access to your AWS accounts (see accessing AWS resources). Read and write access to the
infrastructure-live repository should be granted to any individual who needs to define infrastructure as code. See repository access for more details.
Pipelines uses GitHub Actions in both repositories to define workflows. Workflows running in
infrastructure-pipelines deploy infrastructure changes, workflows running in
infrastructure-live determine what infrastructure needs to be deployed and dispatch deployment jobs to the
infrastructure-live call workflows that are defined on the
main branch of
infrastructure-pipelines. This means that any change to the workflow must go through normal pull request approval processes. Further, the IAM role that Pipelines uses has a trust policy that specifies it can only be assumed from workflows running on the
main branch. If workflows are run from another branch, retrieving short lived tokens will fail.
Gruntwork Pipelines uses a series of GitHub Personal Access Tokens (PAT) to allow cross repository code and workflow access. This approach ensures that each token has the minimal required permissions to perform it's tasks. The full list of tokens and required permissions are listed below.
GRUNTWORK_CODE_ACCESS_TOKEN- A classic PAT with repository access to your
infrastructure-modulesrepositories, as well as Gruntwork Library modules.
INFRA_LIVE_ACCESS_TOKEN- A fine-grained PAT that has read and write access to your
infrastructure-liverepository. This token is used in Pipelines to create pull requests after code generation and add pull request comments.
PIPELINES_DISPATCH_TOKEN- A fine-grained PAT that can run Workflows in your
Steps to create a PAT can be found in the official documentation. Refer to creating a personal access token classic and creating a fine-grained personal access token, respectively. We recommend using machine users for this use case.
To learn more about GitHub PATs, refer to their documentation on managing personal access tokens.
Pipelines employs guards to prevent unapproved code from being deployed to or destroyed in your AWS Accounts. As with other aspects of pipelines, this guard is performed in two places. First, Pipelines jobs are automatically generated by branch. After dispatch, Pipelines performs additional checks to ensure that the information in the request matches code that exists on the
Pipelines has guards in place for
destroy actions. In order for these actions to run, the newly created or deleted code must be present (or not present) on main.
Pipelines requires the use of an IAM Role configured with a trust policy to allow GitHub Actions to use OpenId Connect (OIDC) with to run actions in your AWS accounts. This prevents the requirement of creating long lived AWS credentials and storing them as secrets in GitHub Actions. At execution time, Pipelines exchanges the GitHub OIDC token for short-lived AWS credentials generated using AWS STS to run actions in your AWS accounts.
These credentials, although temporary, should still be treated as secrets. The Pipelines role has administrative permissions to many AWS resources to allow you to deploy many resources without needing to update the policy.
Pipelines provisions an OpenId Connect identity provider in AWS IAM, setting up GitHub as the provider and setting the audience to AWS STS and your GitHub organization. To learn more about provisioning OpenId Connect providers in AWS, refer to the official documentation.
The Pipelines IAM role uses a trust policy to limit access to assume the role to a single repository and branch in your GitHub Organization. The OpenID Connect provider is set as the principal, then a condition is added to the limit access to the
infrastructure-pipelines repository in your GitHub organization, to the ref
main. An example of the trust policy can be found below.
Refer to Configuring OpenId Connect in Amazon Web Services to learn more.
Accessing AWS resources
Access to AWS is only available to workflows running on
main in the
infrastructure-pipelines repository. The
infrastructure-live repository does not have access to AWS directly. Pipelines runs workflows in
infrastructure-live that call workflows in
infrastructure-pipelines where the workflow runs on
main, which grants the workflow in
infrastructure-pipelines temporary access to run
terragrunt apply, or
terragrunt destroy actions.
As highlighted in dual-repository approach, because the workflows in
infrastructure-pipelines can get temporary access to access resources in AWS, write access to this repository should be limited to a trusted set of administrators who likely already have administrative privileges in AWS.