Skip to content

Commit

Permalink
Use AWS Secrets Manager to store secrets (#213)
Browse files Browse the repository at this point in the history
Cloudformation template and CI actions adapted from CBMC viewer.
  • Loading branch information
tautschnig authored Aug 14, 2024
1 parent aa7aba0 commit 9d2265d
Show file tree
Hide file tree
Showing 6 changed files with 191 additions and 33 deletions.
3 changes: 3 additions & 0 deletions .github/cloudformation/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
These are
[AWS CloudFormation templates](https://aws.amazon.com/cloudformation/resources/templates/)
for maintaining pypi and homebrew credentials used to publish the CBMC starter kit.
23 changes: 23 additions & 0 deletions .github/cloudformation/oidc.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
Description:
Register the GitHub identity provider with the AWS security token service.

Resources:
GithubIdentityProvider:
Type: AWS::IAM::OIDCProvider
Properties:
Url:
# The GitHub identity provider supporting OIDC
https://token.actions.githubusercontent.com
ThumbprintList:
# The GitHub certification authority (the signature of its certificate)
- 6938fd4d98bab03faadb97b34396831e3780aea1
ClientIdList:
# The AWS security token service
- sts.amazonaws.com


Outputs:
GithubIdentityProvider:
Value: !Ref GithubIdentityProvider
Export:
Name: GithubIdentityProvider
77 changes: 77 additions & 0 deletions .github/cloudformation/token.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
Description: >
Enable storage of access tokens in AWS Secrets Manager and access to the PAT
from the GitHub workflows in model-checking/cbmc-starter-kit.
Parameters:
GithubRepoOrganization:
Type: String
Description: GitHub organization for the CBMC starter kit
Default: model-checking
CbmcStarterKitRepoName:
Type: String
Description: GitHub repository for CBMC starter kit
Default: cbmc-starter-kit
CbmcStarterKitPublicationTag:
Type: String
Description: GitHub tag for CBMC starter kit triggering the GitHub publication workflow
Default: starterkit-*

Resources:

BrewBotEmail:
Type: AWS::SecretsManager::Secret
Properties:
Name: BOT_EMAIL
Description: >
The email address to use with Homebrew commits.
BrewToken:
Type: AWS::SecretsManager::Secret
Properties:
Name: RELEASE_CI_ACCESS_TOKEN
Description: >
GitHub access token.
PypiToken:
Type: AWS::SecretsManager::Secret
Properties:
Name: PYPI_ACCESS_TOKEN
Description: >
Pypi access token.
PublisherTokenReader:
Type: AWS::IAM::Role
Properties:
RoleName: PublisherTokenReader
Description: >
This role can retrieve the personal access token for the model
checking publisher in the Microsoft Marketplace.
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Federated: !ImportValue GithubIdentityProvider
Action: sts:AssumeRoleWithWebIdentity
Condition:
StringEquals:
token.actions.githubusercontent.com:aud: sts.amazonaws.com
StringLike:
token.actions.githubusercontent.com:sub:
!Sub repo:${GithubRepoOrganization}/${CbmcStarterKitRepoName}:ref:refs/tags/${CbmcStarterKitPublicationTag}

Policies:
- PolicyName: PublisherTokenAccess
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action: secretsmanager:GetSecretValue
Resource: !Ref BrewBotEmail
- Effect: Allow
Action: secretsmanager:GetSecretValue
Resource: !Ref BrewToken
- Effect: Allow
Action: secretsmanager:GetSecretValue
Resource: !Ref PypiToken
74 changes: 55 additions & 19 deletions .github/workflows/release-brew.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -46,17 +46,29 @@ env:
FORMULA: cbmc-starter-kit
TAP: aws/tap
BOT_USER: cbmc-starter-kit-release-ci
BOT_EMAIL: ${{ secrets.BOT_EMAIL }}
BOT_TOKEN: ${{ secrets.RELEASE_CI_ACCESS_TOKEN }}
RELEASE_TAG: ${GITHUB_REF/refs\/tags\/} # GITHUB_REF = refs/tags/STRING-MAJOR.MINOR
VERSION: $(echo $GITHUB_REF | cut -d "/" -f 3 | cut -d "-" -f 2)
FORK_REPO: https://$BOT_TOKEN@github.com/$BOT_USER/homebrew-$(echo $TAP |cut -d "/" -f 2).git
AWS_ROLE: arn:aws:iam::${{secrets.AWS_ACCOUNT}}:role/PublisherTokenReader
AWS_REGION: us-west-2

jobs:
homebrew-pr:
name: Homebrew Bump Formula PR
runs-on: macos-latest
permissions:
id-token: write
steps:
- name: Authenticate GitHub workflow to AWS
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ env.AWS_ROLE }}
aws-region: ${{ env.AWS_REGION }}

- name: Fetch secrets
run: |
echo "BOT_EMAIL=$(aws secretsmanager get-secret-value --secret-id BOT_EMAIL | jq -r '.SecretString')" >> $GITHUB_ENV
echo "HOMEBREW_GITHUB_API_TOKEN=$(aws secretsmanager get-secret-value --secret-id RELEASE_CI_ACCESS_TOKEN | jq -r '.SecretString')" >> $GITHUB_ENV
- name: Configure git user name and email
run: |
git config --global user.name ${{ env.BOT_USER }}
Expand All @@ -66,21 +78,33 @@ jobs:
run: |
brew tap ${{ env.TAP }}
brew update-reset
brew bump-formula-pr --tag "${{ env.RELEASE_TAG }}" --revision "$GITHUB_SHA" ${{ env.TAP }}/${{ env.FORMULA }} --force
env:
HOMEBREW_GITHUB_API_TOKEN: ${{ env.BOT_TOKEN }}
brew bump-formula-pr --tag "${{ env.RELEASE_TAG }}" --revision "${{ github.sha }}" ${{ env.TAP }}/${{ env.FORMULA }} --force
build-bottle:
needs: homebrew-pr
strategy:
matrix:
os: [ubuntu-latest, macos-latest]
runs-on: ${{ matrix.os }}
permissions:
id-token: write
contents: write
steps:
- name: Set up Homebrew
id: set-up-homebrew
uses: Homebrew/actions/setup-homebrew@master

- name: Authenticate GitHub workflow to AWS
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ env.AWS_ROLE }}
aws-region: ${{ env.AWS_REGION }}

- name: Fetch secrets
run: |
echo "FORK_REPO=https://$(aws secretsmanager get-secret-value --secret-id RELEASE_CI_ACCESS_TOKEN | jq -r '.SecretString')@github.com/${{ env.BOT_USER }}/homebrew-$(echo ${{ env.TAP }} |cut -d / -f 2).git" >> $GITHUB_ENV
echo "GITHUB_TOKEN=$(aws secretsmanager get-secret-value --secret-id RELEASE_CI_ACCESS_TOKEN | jq -r '.SecretString')" >> $GITHUB_ENV
- name: Set up Python
# The GitHub action actions/setup-python@v4 installs CPython 3.10
run: |
Expand All @@ -102,43 +126,55 @@ jobs:
- name: Build bottle
run: |
brew test-bot --tap ${{ env.TAP }} --testing-formulae ${{ env.TAP }}/${{ env.FORMULA }} --only-formulae --root-url=https://github.com/$GITHUB_REPOSITORY/releases/download/${{ env.RELEASE_TAG }}
brew test-bot --tap ${{ env.TAP }} --testing-formulae ${{ env.TAP }}/${{ env.FORMULA }} --only-formulae --root-url=https://github.com/${{ github.repository }}/releases/download/${{ env.RELEASE_TAG }}
- name: Get Package Path
id: get_package_path
run: |
echo "bottle=$(ls *.tar.gz)" >> $GITHUB_ENV
echo "bottle_name=$(ls *.tar.gz)" >> $GITHUB_OUTPUT
- name: Get File Name
id: get_file_name
run: |
brew install jq
echo "file_name=$(jq -r '."${{ env.TAP }}/${{ env.FORMULA }}".bottle.tags[].filename' *.json)" >> $GITHUB_ENV
file_name="$(cat *.json | jq -r '."${{ env.TAP }}/${{ env.FORMULA }}".bottle.tags[].filename')"
echo "file_name=$file_name" >> $GITHUB_OUTPUT
- name: Upload bottles as artifact
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: bottles
name: bottle-${{ matrix.os }}
path: '*.bottle.*'

- name: Upload release binary
# this github action is deprecated, but there is no obvious replacement
uses: actions/upload-release-asset@v1.0.2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ github.event.release.upload_url }}
asset_path: ${{ env.bottle }}
asset_name: ${{ env.file_name }}
asset_path: ${{ steps.get_package_path.outputs.bottle_name }}
asset_name: ${{ steps.get_file_name.outputs.file_name }}
asset_content_type: application/x-gzip

update-pr:
needs: build-bottle
runs-on: macos-latest
permissions:
id-token: write
contents: write
steps:
- uses: actions/download-artifact@v3
- uses: actions/download-artifact@v4
with:
pattern: bottle-*

- name: Authenticate GitHub workflow to AWS
uses: aws-actions/configure-aws-credentials@v4
with:
name: bottles
role-to-assume: ${{ env.AWS_ROLE }}
aws-region: ${{ env.AWS_REGION }}

- name: Fetch secrets
run: |
echo "BOT_EMAIL=$(aws secretsmanager get-secret-value --secret-id BOT_EMAIL | jq -r '.SecretString')" >> $GITHUB_ENV
echo "FORK_REPO=https://$(aws secretsmanager get-secret-value --secret-id RELEASE_CI_ACCESS_TOKEN | jq -r '.SecretString')@github.com/${{ env.BOT_USER }}/homebrew-$(echo ${{ env.TAP }} |cut -d / -f 2).git" >> $GITHUB_ENV
- name: Configure git user name and email
run: |
Expand All @@ -156,6 +192,6 @@ jobs:
- name: Generate and merge bottle DSL
run: |
brew bottle --merge --write $(ls *.json)
brew bottle --merge --write $(ls bottle-*/*.json)
cd $(brew --repo ${{ env.TAP }})
git push fork-repo bump-${{ env.FORMULA }}-${{ env.VERSION }}
25 changes: 19 additions & 6 deletions .github/workflows/release-pypi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,32 +3,45 @@ on:
release:
types: [created]

env:
AWS_ROLE: arn:aws:iam::${{secrets.AWS_ACCOUNT}}:role/PublisherTokenReader
AWS_REGION: us-west-2

jobs:
upload-to-pypi:
name: Upload to PyPi
runs-on: ubuntu-20.04
permissions:
id-token: write
contents: write
steps:
- uses: actions/checkout@v3
- name: Install dependencies
run: python3 -m pip install --upgrade pip build setuptools wheel twine
- name: Build pip package
run: python3 -m build
- name: Authenticate GitHub workflow to AWS
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ env.AWS_ROLE }}
aws-region: ${{ env.AWS_REGION }}
- name: Fetch secrets
run: |
echo "GITHUB_TOKEN=$(aws secretsmanager get-secret-value --secret-id RELEASE_CI_ACCESS_TOKEN | jq -r '.SecretString')" >> $GITHUB_ENV
echo "TWINE_PASSWORD=$(aws secretsmanager get-secret-value --secret-id PYPI_ACCESS_TOKEN | jq -r '.SecretString')" >> $GITHUB_ENV
- name: Get Package Name
id: get_package_name
run: |
echo "package_name=$(ls dist/*.whl | cut -d "/" -f 2)" >> $GITHUB_ENV
echo "package_name=$(ls dist/*.whl | cut -d / -f 2)" >> $GITHUB_OUTPUT
- name: Upload release binary
# this github action is deprecated, but there is no obvious replacement
uses: actions/upload-release-asset@v1.0.2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ github.event.release.upload_url }}
asset_path: dist/${{ env.package_name }}
asset_name: ${{ env.package_name }}
asset_path: dist/${{ steps.get_package_name.outputs.package_name }}
asset_name: ${{ steps.get_package_name.outputs.package_name }}
asset_content_type: application/zip
- name: Upload to PyPi
env:
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.PYPI_ACCESS_TOKEN }}
run: python3 -m twine upload dist/*
22 changes: 14 additions & 8 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,17 @@ on:
push:
tags:
- starterkit-*
env:
AWS_ROLE: arn:aws:iam::${{secrets.AWS_ACCOUNT}}:role/PublisherTokenReader
AWS_REGION: us-west-2

jobs:
Release:
name: CBMC starter kit release
runs-on: ubuntu-20.04
env:
GITHUB_TOKEN: ${{ secrets.RELEASE_CI_ACCESS_TOKEN }}
permissions:
id-token: write
contents: write
steps:
- name: Checkout code
uses: actions/checkout@v3
Expand All @@ -25,13 +29,15 @@ jobs:
echo "Setup and source versions ${{env.SETUP_VERSION}} and ${{env.SOURCE_VERSION}} did not match tag version ${{env.TAG_VERSION}}"
exit 1
fi
- name: Authenticate GitHub workflow to AWS
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ env.AWS_ROLE }}
aws-region: ${{ env.AWS_REGION }}
- name: Fetch secrets
run: |
echo "GITHUB_TOKEN=$(aws secretsmanager get-secret-value --secret-id RELEASE_CI_ACCESS_TOKEN | jq -r '.SecretString')" >> $GITHUB_ENV
- name: Create release
# The GitHub action actions/create-release is deprecated:
# https://github.com/actions/create-release
# GitHub recommends ncipollo/release-action@v1, but that
# action fails to trigger the release workflows for brew and
# pypi, perhaps because it does not trigger the expected kind
# of release event.
uses: actions/create-release@v1
with:
tag_name: starterkit-${{ env.TAG_VERSION }}
Expand Down

0 comments on commit 9d2265d

Please sign in to comment.