-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Create GitHub Action for validating CodeQL usage
Signed-off-by: Brett Logan <lindluni@github.com>
- Loading branch information
Showing
4 changed files
with
151 additions
and
0 deletions.
There are no files selected for viewing
23 changes: 23 additions & 0 deletions
23
.github/workflows/required-workflow-ghas-vulnerability-enforcement.yml
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
name: Enforce | ||
on: | ||
pull_request: {} | ||
permissions: | ||
contents: read | ||
pull-requests: write | ||
security-events: read | ||
jobs: | ||
verify: | ||
name: Verify CodeQL Usage | ||
runs-on: ubuntu-latest | ||
steps: | ||
- name: Validate CodeQL Usage | ||
uses: department-of-veterans-affairs/codeql-tools/verify-codeql-usage@main | ||
with: | ||
message_violation: | | ||
Your repository is not in compliance with OIS requirements for CodeQL usage. | ||
Your repository contains **{highAlerts} high severity** vulnerabilities and **{criticalAlerts} critical severity** vulnerabilities. | ||
Per OIS policy, your repository must remediate critical and high vulnerabilities before you may merge additional source code changes. If this Pull Request remediates vulnerabilities, after your Pull Requests CodeQL scan completes, please re-trigger validation by clicking the `Re-run all jobs` button in the top-right corner at this link: <place link here>. Once validation reruns, you will be able to merge your Pull Request. | ||
For additional information about OIS policy, please refer to the OIS SWA Wiki: https://department-of-veterans-affairs.github.io/ois-swa-wiki/docs/ghas/codeql-usage |
File renamed without changes.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
name: Enforce GHAS Policy | ||
description: Validates that repository is remediating GHAS vulnerability alerts | ||
author: GitHub Expert Services | ||
inputs: | ||
org: | ||
description: The slug of the organization | ||
required: true | ||
default: ${{ github.repository_owner }} | ||
message_violation: | ||
description: The message to use when CodeQL is missing | ||
required: true | ||
pull_request_number: | ||
description: The ID of the pull request | ||
required: true | ||
default: ${{ github.event.pull_request.number }} | ||
ref: | ||
description: The ref to use for the pull request | ||
required: true | ||
default: ${{ github.ref }} | ||
repo: | ||
description: The slug of the repository | ||
required: true | ||
default: ${{ github.event.repository.name }} | ||
token: | ||
description: The token to use for authentication | ||
required: true | ||
default: ${{ github.token }} | ||
runs: | ||
using: node16 | ||
main: dist/index.js |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
const core = require('@actions/core') | ||
const {Octokit} = require('@octokit/rest') | ||
const {retry} = require('@octokit/plugin-retry') | ||
const {throttling} = require('@octokit/plugin-throttling') | ||
|
||
const org = core.getInput('ORG', {required: true, trimWhitespace: true}) | ||
const repo = core.getInput('REPO', {required: true, trimWhitespace: true}) | ||
const ref = core.getInput('REF', {required: true, trimWhitespace: true}) | ||
const messageViolation = core.getInput('MESSAGE_VIOLATION', {required: true, trimWhitespace: true}) | ||
const pullRequestNumber = core.getInput('PULL_REQUEST_NUMBER', {required: true, trimWhitespace: true}) | ||
const token = core.getInput('TOKEN', {required: true, trimWhitespace: true}) | ||
|
||
const _Octokit = Octokit.plugin(retry, throttling) | ||
const client = new _Octokit({ | ||
auth: token, | ||
throttle: { | ||
onRateLimit: (retryAfter, options, octokit) => { | ||
octokit.log.warn(`Request quota exhausted for request ${options.method} ${options.url}`); | ||
if (options.request.retryCount === 0) { | ||
octokit.log.info(`Retrying after ${retryAfter} seconds!`); | ||
return true; | ||
} | ||
}, | ||
onSecondaryRateLimit: (retryAfter, options, octokit) => { | ||
octokit.log.warn(`Abuse detected for request ${options.method} ${options.url}`); | ||
}, | ||
} | ||
|
||
}) | ||
|
||
const comment = async (org, repo, number, message) => { | ||
try { | ||
core.info(`Commenting on PR #${number}`) | ||
await client.issues.createComment({ | ||
owner: org, | ||
repo: repo, | ||
issue_number: number, | ||
body: message | ||
}) | ||
} catch (e) { | ||
core.setFailed(`Error commenting on PR #${number}: ${e.message}`) | ||
process.exit(0) | ||
} | ||
} | ||
|
||
const main = async () => { | ||
try { | ||
core.info('Checking if repository ignored') | ||
await client.repos.getContent({ | ||
owner: org, | ||
repo: repo, | ||
path: '.github/.emass-repo-ignore' | ||
}) | ||
core.info(`Repository is ignored, skipping CodeQL usage check`) | ||
process.exit(0) | ||
} catch (e) { | ||
if (e.status !== 404) { | ||
core.setFailed(`Error checking if repository is ignored: ${e.message}`) | ||
process.exit(0) | ||
} | ||
} | ||
|
||
try { | ||
core.info('Retrieving CodeQL Code Scanning alerts') | ||
const highAlerts = await client.paginate(client.codeScanning.listAlertsForRepo, { | ||
owner: org, | ||
repo: repo, | ||
ref: ref, | ||
severity: 'high', | ||
state: 'open', | ||
tool_name: 'CodeQL', | ||
}) | ||
const criticalAlerts = await client.paginate(client.codeScanning.listAlertsForRepo, { | ||
owner: org, | ||
repo: repo, | ||
ref: ref, | ||
severity: 'high', | ||
state: 'open', | ||
tool_name: 'CodeQL', | ||
}) | ||
if (highAlerts.length > 0 || criticalAlerts.length > 0) { | ||
core.info(`Found ${highAlerts.length} high and ${criticalAlerts.length} critical alerts`) | ||
const message = messageViolation.replace('{highAlerts}', String(highAlerts.length)).replace('{criticalAlerts}', String(criticalAlerts.length)) | ||
await comment(org, repo, pullRequestNumber, message) | ||
core.setFailed(`GHAS security policy violation found, please open a ticket here https://github.com/department-of-veterans-affairs/github-user-requests/issues/new/choose for additional help.`) | ||
process.exit(1) | ||
} | ||
} catch (e) { | ||
core.setFailed(`Error checking for GHAS usage, please open a ticket here https://github.com/department-of-veterans-affairs/github-user-requests/issues/new/choose for additional help: ${e.message}`) | ||
process.exit(0) | ||
} | ||
core.info(`GHAS security policy check complete`) | ||
} | ||
|
||
main().catch(e => { | ||
core.setFailed(e.message) | ||
process.exit(0) | ||
}) |