Use DL Sentinel in CI
DL Sentinel's exit code makes it a build gate: a CI job fails when a scan finds problems at the severities you choose. On GitHub, a ready-made Action also comments on pull requests and reports only what each pull request adds.
To learn the ideas behind automated checks, see CI automation.
GitHub pull requests with the Action
The Action runs the scan on the GitHub runner. Your code is not sent anywhere. Its only network call is to the GitHub API, to post the pull-request comment.
In your repository, create
.github/workflows/dl-sentinel.ymlwith this content:yamlname: DL Sentinel on: pull_request: permissions: contents: read pull-requests: write # sticky PR comment security-events: write # SARIF upload (optional) jobs: sentinel: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 # Check out the base branch so only PR-introduced findings are reported. - uses: actions/checkout@v4 with: ref: ${{ github.event.pull_request.base.sha }} path: .sentinel-base - uses: Dhiva-Labs/dl-sentinel/apps/action@v0.1.0 with: path: . base_path: .sentinel-base fail_on: critical,high - if: always() continue-on-error: true uses: github/codeql-action/upload-sarif@v3 with: sarif_file: sentinel-results.sarifCommit the file and open a pull request.
When the check runs, the job summary shows the result, and a comment on the pull request lists the new findings. The comment is updated on each push instead of adding a new one.
The check fails when the pull request adds a finding at a fail_on severity.
TIP
Pin the Action to a release tag you have reviewed, such as @v0.1.0. The scanner reads all of your repository's source, so do not point it at a moving branch.
How "only new findings" works
The Action picks the first of these that you provide:
baseline: a committed baseline file. See Baselines.base_path: a folder holding the base branch, checked out by the secondcheckoutstep above. The Action scans it and treats its findings as already present.- Neither: every finding counts as new.
Action inputs
| Input | Default | What it does |
|---|---|---|
path | . | Folder to scan, relative to the repository root |
fail_on | critical,high | Severities that fail the check when newly introduced |
scanners | all | Comma-separated scanner ids to run |
baseline | none | A committed baseline file |
base_path | none | A folder holding the base branch |
config | auto | A sentinel.yml path. By default one in the repository is used |
comment | true | Post or update the pull-request comment |
sarif | true | Write a SARIF file of the new findings |
sarif_file | sentinel-results.sarif | Where to write the SARIF file |
token | ${{ github.token }} | Used only to post the comment. Commenting is skipped if it is empty |
Action outputs
| Output | Value |
|---|---|
findings_total | All findings in the scanned tree, before the baseline |
findings_new | Findings added by this pull request |
failed | true when new findings hit the fail_on severities |
The comment, summary and SARIF file contain only redacted fields. The comment leaves out evidence completely.
Any CI system with the command
Where the Action is not available, run the sentinel command in a job. Build it from source as on the install page, then scan:
node apps/cli/dist/main.js scan "$PROJECT_DIR" \
--format sarif --output sentinel.sarif \
--fail-on critical,high --quiet$PROJECT_DIR stands for the folder your CI checked out. The job fails when the command exits non-zero:
| Code | Meaning for the build |
|---|---|
0 | Pass |
1 | Fail: findings at a --fail-on severity |
2 | Fail: the scan itself had an error |
64 | Fail: the command or a file it was given is wrong |
Add --baseline .sentinel-baseline.json to fail only on new findings.
Publish reports
A static website cannot run DL Sentinel, but it can host its reports. Render them in CI and publish the files:
sentinel scan . --format markdown --output public/security-report.md
sentinel scan . --format sarif --output public/security.sarifWARNING
Think before you publish a report on a public site. It contains no secret values, but it is a list of weaknesses in your code.