Secrets Rotation Reminder #412
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- | |
name: Secrets Rotation Reminder | |
on: | |
pull_request: | |
branches: | |
- "main" | |
paths: | |
- ".github/workflows/secrets-rotation-reminder.yaml" | |
schedule: | |
- cron: '30 11 * * *' # run at 11:30 daily | |
workflow_dispatch: | |
env: | |
AWS_REGION: "eu-west-2" | |
ENVIRONMENT_MANAGEMENT: ${{ secrets.MODERNISATION_PLATFORM_ENVIRONMENTS }} | |
SECRET: ${{ secrets.GITHUB_TOKEN }} | |
GITHUB_REPOSITORY: ${{ secrets.GITHUB_REPOSITORY }} | |
GH_TOKEN: ${{ secrets.MODERNISATION_PAT_MULTIREPO }} | |
permissions: | |
id-token: write # This is required for requesting the JWT | |
contents: read # This is required for actions/checkout | |
issues: write # This is required to create issues | |
defaults: | |
run: | |
shell: bash | |
jobs: | |
secrets-rotation-reminder: | |
runs-on: ubuntu-latest | |
steps: | |
- name: Checkout Repository | |
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 | |
- name: Set Account Number | |
run: | | |
ACCOUNT_NUMBER=$(jq -r -e '.modernisation_platform_account_id' <<< $ENVIRONMENT_MANAGEMENT) | |
echo "::add-mask::$ACCOUNT_NUMBER" | |
echo ACCOUNT_NUMBER=$ACCOUNT_NUMBER >> $GITHUB_ENV | |
- name: Configure AWS Credentials | |
uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502 # v4.0.2 | |
with: | |
role-to-assume: "arn:aws:iam::${{ env.ACCOUNT_NUMBER }}:role/github-actions-apply" | |
role-session-name: githubactionsrolesession | |
aws-region: ${{ env.AWS_REGION }} | |
- name: Run Secrets Rotation Reminder Script | |
run: | | |
# Get the list of secret names from AWS Secrets Manager | |
secrets=$(aws secretsmanager list-secrets --region $AWS_REGION --query "SecretList[].Name" --output text) | |
# Remove secrets from list that are exempt from rotation | |
delete=("environment_management" "nuke_account_ids" "nuke_account_blocklist" "mod-platform-circleci" "pagerduty_integration_keys") | |
for del in ${delete[@]} | |
do | |
secrets=("${secrets[@]/$del}") | |
done | |
# Define the threshold in seconds (180 days) | |
threshold=$((180 * 24 * 60 * 60)) | |
# Get the current timestamp in seconds | |
current_timestamp=$(date +%s) | |
# Loop through each secret, check its last changed date and raise issue if required | |
for secret in $secrets; do | |
last_changed=$(aws secretsmanager list-secret-version-ids --secret-id $secret --region $AWS_REGION --query "Versions[?contains(VersionStages,'AWSCURRENT')].CreatedDate" --output text | sort -r | head -n 1) | |
# If the secret has never been changed, set the last_changed date to 0 | |
if [ -z "$last_changed" ]; then | |
last_changed=0 | |
fi | |
# Calculate the age of the secret in seconds | |
age=$((current_timestamp - $(date -d "$last_changed" +%s))) | |
# Check if there is an existing open issue to rotate the secret | |
open_issue=$(gh issue list -R ministryofjustice/modernisation-platform --search "Rotate $secret in:title" --state open) | |
# Check if the secret is older than the threshold and if there is an existing open issue to rotate it, if required raise a new issue | |
if [ $age -gt $threshold ] && [ -z "$open_issue" ]; then | |
echo "$secret secret is older than 180 days (age: $((age / (24 * 60 * 60))) days)" | |
echo "Creating GitHub Issue to rotate $secret" | |
gh issue create --title "Rotate $secret Credential" --label security --project "Modernisation Platform" --body "The [secrets-rotation-reminder workflow](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) has identified that the $secret credential requires rotation as it is close to or exceeding the threshold of 180 days. | |
Consult [this documentation](https://user-guide.modernisation-platform.service.justice.gov.uk/runbooks/rotating-secrets.html#how-to-rotate-secrets) which describes the process for rotation." | |
else | |
echo "The $secret secret has not been identified for rotation (age: $((age / (24 * 60 * 60))) days)" | |
fi | |
done |