diff --git a/.github/workflows/ci-health.yml b/.github/workflows/ci-health.yml new file mode 100644 index 0000000000..92c753f4db --- /dev/null +++ b/.github/workflows/ci-health.yml @@ -0,0 +1,36 @@ +name: CI Health +on: + schedule: + - cron: "0 */3 * * *" + workflow_dispatch: + +permissions: + id-token: write # This is required for requesting the JWT + +jobs: + canaries-v3: + runs-on: ubuntu-latest + steps: + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ secrets.CI_AWS_ROLE_ARN }} + aws-region: us-west-2 + role-duration-seconds: 10800 + - name: Run Canaries V3 + uses: aws-actions/aws-codebuild-run-build@v1 + with: + project-name: canaries-v3 + canaries-v2: + runs-on: ubuntu-latest + steps: + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ secrets.CI_AWS_ROLE_ARN }} + aws-region: us-west-2 + role-duration-seconds: 10800 + - name: Run Canaries V2 + uses: aws-actions/aws-codebuild-run-build@v1 + with: + project-name: canaries-v2 \ No newline at end of file diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 0000000000..c6df60d630 --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,35 @@ +name: "CodeQL" +on: + push: + branches: [ "master" ] + pull_request: + branches: [ "master" ] + schedule: + - cron: '30 15 * * *' +jobs: + analyze: + name: Analyze (${{ matrix.language }}) + runs-on: ${{ 'ubuntu-latest' }} + permissions: + security-events: write + packages: read + + strategy: + matrix: + include: + - language: python + build-mode: none + - language: java-kotlin + build-mode: none + steps: + - name: Checkout repository + uses: actions/checkout@6ccd57f4c5d15bdc2fef309bd9fb6cc9db2ef1c6 + - name: Initialize CodeQL + uses: github/codeql-action/init@4b1d7da102ff94aca014c0245062b1a463356d72 + with: + languages: ${{ matrix.language }} + build-mode: ${{ matrix.build-mode }} + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@4b1d7da102ff94aca014c0245062b1a463356d72 + with: + category: "/language:${{matrix.language}}" \ No newline at end of file diff --git a/.github/workflows/security-monitoring.yml b/.github/workflows/security-monitoring.yml new file mode 100644 index 0000000000..8e44b426c2 --- /dev/null +++ b/.github/workflows/security-monitoring.yml @@ -0,0 +1,121 @@ +name: Security Monitoring + +on: + schedule: + - cron: '0 16 * * *' + +concurrency: + group: ${{ github.workflow }}-${{ github.run_id }} + cancel-in-progress: true + +permissions: + id-token: write + +jobs: + check-code-scanning-alerts: + runs-on: ubuntu-latest + outputs: + code_scanning_alert_status: ${{ steps.check-code-scanning-alerts.outputs.code_scanning_alert_status }} + steps: + - name: Check for security alerts + id: check-code-scanning-alerts + uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea + with: + github-token: ${{ secrets.GH_PAT }} + script: | + async function checkAlerts() { + const owner = '${{ github.repository_owner }}'; + const repo = '${{ github.event.repository.name }}'; + const ref = 'refs/heads/master'; + + const codeScanningAlerts = await github.rest.codeScanning.listAlertsForRepo({ + owner, + repo, + ref: ref + }); + const activeCodeScanningAlerts = codeScanningAlerts.data.filter(alert => alert.state === 'open'); + core.setOutput('code_scanning_alert_status', activeCodeScanningAlerts.length > 0 ? '1': '0'); + } + await checkAlerts(); + + check-dependabot-alerts: + runs-on: ubuntu-latest + outputs: + dependabot_alert_status: ${{ steps.check-dependabot-alerts.outputs.dependabot_alert_status }} + steps: + - name: Check for dependabot alerts + id: check-dependabot-alerts + uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea + with: + github-token: ${{ secrets.GH_PAT }} + script: | + async function checkAlerts() { + const owner = '${{ github.repository_owner }}'; + const repo = '${{ github.event.repository.name }}'; + + const dependabotAlerts = await github.rest.dependabot.listAlertsForRepo({ + owner, + repo, + headers: { + 'accept': 'applications/vnd.github+json' + } + }); + const activeDependabotAlerts = dependabotAlerts.data.filter(alert => alert.state === 'open'); + core.setOutput('dependabot_alert_status', activeDependabotAlerts.length > 0 ? '1': '0'); + } + await checkAlerts(); + + check-secret-scanning-alerts: + runs-on: ubuntu-latest + outputs: + secret_scanning_alert_status: ${{ steps.check-secret-scanning-alerts.outputs.secret_scanning_alert_status }} + steps: + - name: Check for secret scanning alerts + id: check-secret-scanning-alerts + uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea + with: + github-token: ${{ secrets.GH_PAT }} + script: | + async function checkAlerts() { + const owner = '${{ github.repository_owner }}'; + const repo = '${{ github.event.repository.name }}'; + + const secretScanningAlerts = await github.rest.secretScanning.listAlertsForRepo({ + owner, + repo, + }); + const activeSecretScanningAlerts = secretScanningAlerts.data.filter(alert => alert.state === 'open'); + core.setOutput('secret_scanning_alert_status', activeSecretScanningAlerts.length > 0 ? '1': '0'); + } + await checkAlerts(); + + put-metric-data: + runs-on: ubuntu-latest + needs: [check-code-scanning-alerts, check-dependabot-alerts, check-secret-scanning-alerts] + steps: + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@12e3392609eaaceb7ae6191b3f54bbcb85b5002b + with: + role-to-assume: ${{ secrets.MONITORING_ROLE_ARN }} + aws-region: us-west-2 + - name: Put Code Scanning Alert Metric Data + run: | + if [ "${{ needs.check-code-scanning-alerts.outputs.code_scanning_alert_status }}" == "1" ]; then + aws cloudwatch put-metric-data --metric-name CodeScanningAlert --namespace SecurityMonitoringMetrics --value 1 --unit Count --dimensions ProjectName=sagemaker-python-sdk + else + aws cloudwatch put-metric-data --metric-name CodeScanningAlert --namespace SecurityMonitoringMetrics --value 0 --unit Count --dimensions ProjectName=sagemaker-python-sdk + fi + - name: Put Dependabot Alert Metric Data + run: | + if [ "${{ needs.check-dependabot-alerts.outputs.dependabot_alert_status }}" == "1" ]; then + aws cloudwatch put-metric-data --metric-name DependabotAlert --namespace SecurityMonitoringMetrics --value 1 --unit Count --dimensions ProjectName=sagemaker-python-sdk + else + aws cloudwatch put-metric-data --metric-name DependabotAlert --namespace SecurityMonitoringMetrics --value 0 --unit Count --dimensions ProjectName=sagemaker-python-sdk + fi + - name: Put Secret Scanning Alert Metric Data + run: | + if [ "${{ needs.check-secret-scanning-alerts.outputs.secret_scanning_alert_status }}" == "1" ]; then + aws cloudwatch put-metric-data --metric-name SecretScanningAlert --namespace SecurityMonitoringMetrics --value 1 --unit Count --dimensions ProjectName=sagemaker-python-sdk + else + aws cloudwatch put-metric-data --metric-name SecretScanningAlert --namespace SecurityMonitoringMetrics --value 0 --unit Count --dimensions ProjectName=sagemaker-python-sdk + fi \ No newline at end of file