Posture gate in CI: the GitHub Action
The posture gate fails a build when your security posture has gone backward. It checks three things against your live CMDash data:
- Score drop. A maturity score fell by more than your threshold since its previous snapshot.
- Control regression. A control moved backward in status (for example Implemented to At risk) inside the lookback window.
- Expired exception. An active exception is past its expiry date.
Every failure names the specific data behind it (which model and score, which control, which exception), never a bare "fail". The same check runs from a GitHub Action, a command-line tool, a GitLab CI/CD component and a Bitbucket pipe, and all of them use the same exit codes.
Before you start
Create an API key with the gate:read permission in Settings, API Keys. Store it as a repository or organization secret (this page calls it CMDASH_API_KEY) and never commit it.
Set your thresholds once in Settings, Posture Gate. They are saved per organization, so every repository that uses one of your organization's keys is checked against the same policy. Any input below overrides the saved value for that one run only.
Get the action
The action is available to customers on request and is not listed on the GitHub Marketplace. Ask for access and we will give your organization access to it. Once you have access, reference it from the CMDash repository, which GitHub Actions supports for any action that lives in a subdirectory at a branch, tag or commit. No v1 tag exists, so pin to main, then to a specific commit once you have reviewed what you are running.
name: cmdash posture gate
on:
pull_request:
push:
branches: [main]
jobs:
posture-gate:
runs-on: ubuntu-latest
steps:
- uses: bgovanlu/cmdash/integrations/github-action@main
id: gate
with:
api-key: ${{ secrets.CMDASH_API_KEY }}
fail-on: '5'
- if: always()
run: |
echo "passed=${{ steps.gate.outputs.passed }}"
echo "score=${{ steps.gate.outputs.score }}"
echo "report=${{ steps.gate.outputs.report-url }}"
Inputs
| Input | What it does |
|---|---|
api-key | Required. The API key with gate:read. |
api-url | Base URL of the CMDash API. Defaults to https://app.cmdash.com/api. |
gate | Limit the score-drop check to one adopted maturity model, by its slug. Leave empty to check every adopted model. |
fail-on | Points a score may drop before the gate fails. |
block-on-control-regression | true or false. |
control-regression-window-days | Lookback window, in days, for the control-regression check. |
block-on-expired-exception | true or false. |
Outputs
| Output | Meaning |
|---|---|
passed | "true" or "false". |
score | The score behind a cited score-drop failure, when there was one. |
report-url | A link back to your Posture Gate settings page. |
Exit codes
| Code | Meaning |
|---|---|
0 | The gate passed. |
1 | The gate failed: a real posture regression, cited in the output. This blocks the pipeline. |
2 | The check itself could not run: a missing or wrong API key, a network error, or a rate limit. Kept apart from 1 so you can tell a regression from a setup problem. |
To keep a failed gate from blocking the whole pipeline, mark the job as not required and read the passed output in a later step (if: always()), as in the example above.
What CMDash sees
Only your organization's own CMDash data. The action calls the CMDash API with your key. It never reads your repository's code, commits or pull request contents.
Other CI systems
- Command line. The
@cmdash/gate-clipackage is not published to npm, so there is nothing to install withnpm install. - GitLab and Bitbucket. The same check is available as a GitLab CI/CD include and a Bitbucket pipe, referenced from the repository the same way.
See limits for the API rate limits that apply to the key.