GitHub Actions
Scorecards
Scorecards from the Open Source Security Foundation is a good starting point to learn about security best practices for GitHub Actions.
Permissions and environments
Use the permissions
key in workflows to specify least privilege permissions for GITHUB_TOKEN
. You can find a lot of examples at GitHub. For example:
Continuous delivery jobs (for example running Terraform) should run isolated in its own job with scoped permissions and environments to reduce the risk of supply-chain attacks and adheres to the principle of least privilege.
🔴 In the example below, both hashicorp/setup-terraform
and terraform-linters/setup-tflint
will be able to assume the same AWS IAM role because they originate from a job that has an environment named production
. This trust condition is checked by the IAM policy.1
jobs:
terraform:
name: Lint and apply Terraform configuration
permissions:
id-token: write
contents: read
environment: production
steps:
- uses: aws-actions/configure-aws-credentials@sha-1
- uses: terraform-linters/setup-tflint@sha-1
- uses: hashicorp/setup-terraform@sha-1
🟢 Only aws-actions/configure-aws-credentials
and hashicorp/setup-terraform
can use the IAM role:
jobs:
tflint:
name: Lint Terraform configuration
permissions:
contents: read
environment: production
steps:
- uses: terraform-linters/setup-tflint@sha-1
tflint:
name: Lint and Terraform configuration
permissions:
id-token: write
contents: read
steps:
- uses: aws-actions/configure-aws-credentials@sha-1
- uses: hashicorp/setup-terraform@sha-1
Pin actions
GitHub Actions should be pinned to a commit hash. This is because Git tags are mutable in practice.[^1] There's no need to fork an action for security purposes as long as you follow this recommendation. Use Dependabot to keep on top of security updates. When pinning to a SHA-1 hash it's good practice to comment with the corresponding version number:
Use fine-grained personal access tokens for cross-repository access
🟢 Set up fine-grained personal access tokens (PAT) on a machine user (such as okctl-bot
). Consider making the token available as a organization-level secret, which reduces the need to create duplicate secrets.
🔴 Avoid using PATs attached to private GitHub accounts.
SSH deploy keys for cross-repository access
🔴 Don't use SSH deploy keys unless you have a special reason. Use fine-grained personal access tokens instead. This eliminates the need of using a third-party action.
If there is no other option, use webfactory/ssh-agent
to load
SSH deploy keys in a GitHub Actions workflow.
- name: Load golden-path-iac SSH deploy key
uses: webfactory/ssh-agent@fc49353b67b2b7c1e0e6a600572d01a69f2672dd # v0.5.4
with:
ssh-private-key: ${{ secrets.GOLDEN_PATH_IAC_PRIVATE_DEPLOY_KEY }}
Signing commits in workflows with GnuPG
Use
crazy-max/ghaction-import-gpg
to sign commits in a GitHub Actions workflow.
- name: Import GPG key
uses: crazy-max/ghaction-import-gpg@111c56156bcc6918c056dbef52164cfa583dc549 # v5.2.0
with:
gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
passphrase: ${{ secrets.GPG_PASSPHRASE }}
# Username and email is inferred from GPG key metadata
git_user_signingkey: true
git_commit_gpgsign: true
git_config_global: true