Skip to content

Secrets Rotation Reminder #418

Secrets Rotation Reminder

Secrets Rotation Reminder #418

---
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