From e9fdbcca622af8b92023bc94ef0115c76137942a Mon Sep 17 00:00:00 2001 From: per1234 Date: Thu, 22 Oct 2020 08:31:48 -0700 Subject: [PATCH] [skip changelog] Add workflow to check for problems with certificates If the certificates fail verification, a notification will be posted on the #team_tooling Slack channel. If the certificates expire in less than 30 days, a notification will be posted on the #team_tooling Slack channel. --- .github/workflows/check-certificates.yml | 121 +++++++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 .github/workflows/check-certificates.yml diff --git a/.github/workflows/check-certificates.yml b/.github/workflows/check-certificates.yml new file mode 100644 index 00000000000..cd43caf71db --- /dev/null +++ b/.github/workflows/check-certificates.yml @@ -0,0 +1,121 @@ +name: Check for issues with signing certificates + +on: + schedule: + # run every 10 hours + - cron: "0 */10 * * *" + # workflow_dispatch event allows the workflow to be triggered manually. + # This could be used to run an immediate check after updating certificate secrets. + # See: https://docs.github.com/en/actions/reference/events-that-trigger-workflows#workflow_dispatch + workflow_dispatch: + +env: + # Begin notifications when there are less than this many days remaining before expiration + EXPIRATION_WARNING_PERIOD: 30 + +jobs: + check-certificates: + # This workflow would fail in forks that don't have the certificate secrets defined + if: github.repository == 'arduino/arduino-cli' + runs-on: ubuntu-latest + + strategy: + fail-fast: false + + matrix: + certificate: + - identifier: macOS signing certificate # Text used to identify the certificate in notifications + certificate-secret: INSTALLER_CERT_MAC_P12 # The name of the secret that contains the certificate + password-secret: INSTALLER_CERT_MAC_PASSWORD # The name of the secret that contains the certificate password + + steps: + - name: Set certificate path environment variable + run: | + # See: https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-commands-for-github-actions#setting-an-environment-variable + echo "CERTIFICATE_PATH=${{ runner.temp }}/certificate.p12" >> "$GITHUB_ENV" + + - name: Decode certificate + env: + CERTIFICATE: ${{ secrets[matrix.certificate.certificate-secret] }} + run: | + echo "${{ env.CERTIFICATE }}" | base64 --decode > "${{ env.CERTIFICATE_PATH }}" + + - name: Verify certificate + env: + CERTIFICATE_PASSWORD: ${{ secrets[matrix.certificate.password-secret] }} + run: | + ( + openssl pkcs12 \ + -in "${{ env.CERTIFICATE_PATH }}" \ + -noout -passin env:CERTIFICATE_PASSWORD + ) || ( + echo "::error::Verification of ${{ matrix.certificate.identifier }} failed!!!" + exit 1 + ) + + # See: https://github.com/rtCamp/action-slack-notify + - name: Slack notification of certificate verification failure + if: failure() + uses: rtCamp/action-slack-notify@v2.1.0 + env: + SLACK_WEBHOOK: ${{ secrets.TEAM_TOOLING_CHANNEL_SLACK_WEBHOOK }} + SLACK_MESSAGE: | + :warning::warning::warning::warning: + WARNING: ${{ github.repository }} ${{ matrix.certificate.identifier }} verification failed!!! + :warning::warning::warning::warning: + SLACK_COLOR: danger + MSG_MINIMAL: true + + - name: Get days remaining before certificate expiration date + env: + CERTIFICATE_PASSWORD: ${{ secrets[matrix.certificate.password-secret] }} + id: get-days-before-expiration + run: | + EXPIRATION_DATE="$( + ( + openssl pkcs12 \ + -in "${{ env.CERTIFICATE_PATH }}" \ + -clcerts \ + -nodes \ + -passin env:CERTIFICATE_PASSWORD + ) | ( + openssl x509 \ + -noout \ + -enddate + ) | ( + grep \ + --max-count=1 \ + --only-matching \ + --perl-regexp \ + 'notAfter=(\K.*)' + ) + )" + + DAYS_BEFORE_EXPIRATION="$((($(date --utc --date="$EXPIRATION_DATE" +%s) - $(date --utc +%s)) / 60 / 60 / 24))" + + # Display the expiration information in the log + echo "Certificate expiration date: $EXPIRATION_DATE" + echo "Days remaining before expiration: $DAYS_BEFORE_EXPIRATION" + + echo "::set-output name=days::$DAYS_BEFORE_EXPIRATION" + + - name: Check if expiration notification period has been reached + id: check-expiration + run: | + if [[ ${{ steps.get-days-before-expiration.outputs.days }} -lt ${{ env.EXPIRATION_WARNING_PERIOD }} ]]; then + echo "::error::${{ matrix.certificate.identifier }} will expire in ${{ steps.get-days-before-expiration.outputs.days }} days!!!" + exit 1 + fi + + - name: Slack notification of pending certificate expiration + # Don't send spurious expiration notification if verification fails + if: failure() && steps.check-expiration.outcome == 'failure' + uses: rtCamp/action-slack-notify@v2.1.0 + env: + SLACK_WEBHOOK: ${{ secrets.TEAM_TOOLING_CHANNEL_SLACK_WEBHOOK }} + SLACK_MESSAGE: | + :warning::warning::warning::warning: + WARNING: ${{ github.repository }} ${{ matrix.certificate.identifier }} will expire in ${{ steps.get-days-before-expiration.outputs.days }} days!!! + :warning::warning::warning::warning: + SLACK_COLOR: danger + MSG_MINIMAL: true