diff --git a/.github/workflows/security-workflow.yml b/.github/workflows/security-workflow.yml new file mode 100644 index 0000000..c19a76e --- /dev/null +++ b/.github/workflows/security-workflow.yml @@ -0,0 +1,141 @@ +name: Security Workflow + +on: [push, pull_request, workflow_dispatch] + +jobs: + + get-teams: + name: "Get repository team names" + runs-on: ubuntu-latest + outputs: + teams: ${{ steps.teams.outputs.teams }} + + if: | + github.actor != 'dependabot[bot]' && + ((github.event_name == 'push' && github.ref_name == github.event.repository.default_branch) || + github.event_name == 'pull_request' || + github.event_name == 'workflow_dispatch') + + steps: + - name: Export team names + id: teams + run: | + TEAMS=$( \ + curl -s -H "Authorization: token ${{ secrets.SECURITY_WORKFLOW_GH_PAT }}" \ + -H "Accept: application/vnd.github.v3+json" https://api.github.com/repos/$GITHUB_REPOSITORY/teams | \ + jq -c '. | [.[]? | .name ]' \ + ) + echo "::set-output name=teams::$TEAMS" + + static-analysis: + name: "Static Analysis" + runs-on: ubuntu-latest + needs: get-teams + + if: | + github.actor != 'dependabot[bot]' && + ((github.event_name == 'push' && github.ref_name == github.event.repository.default_branch) || + github.event_name == 'pull_request' || + github.event_name == 'workflow_dispatch') + + steps: + - name: Run checkout - push + if: github.event_name == 'push' + uses: actions/checkout@v2 + with: + fetch-depth: 100 + + - name: Run checkout - pull_request / workflow_dispatch + if: github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch' + uses: actions/checkout@v2 + with: + fetch-depth: 0 + + - name: Run Gitleaks + id: gitleaks + uses: olxbr/gitleaks-action@main + + - name: Submit Gitleaks metrics + run: | + ENDPOINT=$(echo "${{ secrets.GH_METRICS_SERVER_ENDPOINT }}" | awk -F/ '{print $3}') + DATA=$( \ + jq -n \ + --arg GITHUB_WORKFLOW "$GITHUB_WORKFLOW" \ + --arg GITHUB_JOB "$GITHUB_JOB" \ + --arg GITHUB_RUN_ID "$GITHUB_RUN_ID" \ + --arg GITHUB_SHA "$GITHUB_SHA" \ + --arg GITHUB_REPOSITORY "$GITHUB_REPOSITORY" \ + --arg GITLEAKS_EXIT_CODE "${{ steps.gitleaks.outputs.exit_code }}" \ + --argjson GITLEAKS_RESULT '${{ steps.gitleaks.outputs.result }}' \ + --argjson TEAMS '${{ needs.get-teams.outputs.teams }}' \ + '{ + "workflow_job": { + "name": $GITHUB_WORKFLOW, + "id": $GITHUB_JOB, + "run_id": $GITHUB_RUN_ID, + "head_sha": $GITHUB_SHA + }, + "repository": { + "full_name": $GITHUB_REPOSITORY + }, + "custom_metrics": { + "outputs.exit_code": $GITLEAKS_EXIT_CODE, + "outputs.result": $GITLEAKS_RESULT, + "outputs.repository_teams": $TEAMS + } + }' \ + ) + curl -sv "https://${ENDPOINT}/gitleaks" -d "$DATA" -H "Content-Type: application/json" --connect-timeout 15 --max-time 30 + + - name: Notify bad Gitleaks exit code + if: steps.gitleaks.outputs.exit_code != 0 + run: | + TEAMS=$(echo '${{ needs.get-teams.outputs.teams }}' | jq '.[]' | tr -d '\\"') + MESSAGE=$(printf "Summary report for is ready for review.\nAssociated teams in this repository:\n\`\`\`$TEAMS\`\`\`") + REPOSITORY_RUN="https://github.com/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID" + DATA=$( \ + jq -n \ + --arg CHANNEL "${{ secrets.SECURITY_WORKFLOW_SLACK_CHANNEL_ID }}" \ + --arg REPOSITORY_RUN "$REPOSITORY_RUN" \ + --arg MESSAGE "$MESSAGE" \ + '{ + "channel": $CHANNEL, + "blocks": [ + { + "type": "header", + "text": { + "type": "plain_text", + "text": "Gitleaks raised issues" + } + }, + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": $MESSAGE + }, + "accessory": { + "type": "button", + "text": { + "type": "plain_text", + "text": "See report" + }, + "url": $REPOSITORY_RUN + } + } + ] + }' \ + ) + curl -sv \ + -d "$DATA" \ + -H "Content-type: application/json" \ + -H "Authorization: Bearer ${{ secrets.SEC_BOT_SLACK_TOKEN }}" \ + -X POST https://slack.com/api/chat.postMessage + + - name: Evaluate Gitleaks exit code + if: steps.gitleaks.outputs.exit_code != 0 + uses: actions/github-script@v5 + with: + script: | + core.setFailed("Gitleaks encountered leaks. Please fix it in order to keep a safe work.") +