Documentation menu
GitHub Action
Run Settlens checks on every pull request or on a schedule, fail the job at your severity threshold and keep the reports as build artifacts.
In short
The Settlens composite GitHub Action runs settlens check against a configuration file, fails the job when a failing check reaches the fail-on severity (default high) and leaves JSON, HTML and SARIF reports for later steps. It runs passive checks only, from a checkout of the private Settlens repository.
On this page
The repository includes a composite GitHub Action (action.yml at its root). It installs Node.js 24, installs Settlens' production dependencies from the lockfile, then runs settlens check against your configuration file. The job fails when a failing check reaches the fail-on severity, and the JSON, HTML and SARIF reports are left in the output directory for later steps.
The Action is not on the GitHub Marketplace: Settlens lives in a private repository that pilot participants receive, so workflows run the Action from a copy of that repository. It runs passive checks only; it has no input for the active probe.
Inputs
Read from action.yml. Every input is optional.
| Input | Default | Passed to the CLI as | Description |
|---|---|---|---|
| config | settlens.config.json | --config | Path to a Settlens JSON configuration file. |
| output | reports | --out | Directory for JSON, HTML and SARIF evidence reports. |
| formats | json,html,sarif | --format | Comma-separated report formats. |
| fail-on | high | --fail-on | Minimum failing severity that blocks CI. |
| allowed-hosts | (empty) | SETTLENS_ALLOWED_HOSTS | Comma-separated exact hostnames allowed to receive custom headers. |
- fail-on takes
low,medium,high,criticalornone. Only failing checks count; warnings never fail the job. - allowed-hosts is the allowlist for custom headers in the config. It is deliberately separate from the config file: a pull request that edits the config cannot add a new destination for your secrets without also changing the workflow.
- config and output are paths relative to the workspace root.
Outputs
| Output | Description |
|---|---|
| report-directory | Directory containing the generated evidence. |
report-directory is set on every run, including when the gate fails: the step records the exit status of settlens check, writes the output, then exits with that status. The workflows below pass the literal output path to their upload steps.
Workflow in your own repository
Check out the Settlens repository next to your code, pinned to a commit you reviewed, and run the Action from that path. SETTLENS_REPO_TOKEN is a token with read access to the Settlens repository only, such as a fine-grained personal access token or a GitHub App token; the default GITHUB_TOKEN cannot read another private repository.
name: Settlens
on:
pull_request:
schedule:
- cron: "17 6 * * 1-5" # weekdays, 06:17 UTC
workflow_dispatch:
permissions:
contents: read
jobs:
x402-assessment:
runs-on: ubuntu-latest
steps:
- name: Check out this repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
- name: Check out Settlens
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
repository: OWNER/SETTLENS-REPOSITORY # the repository shared with your pilot
ref: FULL-40-CHARACTER-COMMIT-SHA # a Settlens commit you reviewed
path: .settlens
token: ${{ secrets.SETTLENS_REPO_TOKEN }} # read-only access to that repository
persist-credentials: false
- name: Assess x402 endpoints
uses: ./.settlens
with:
config: settlens.config.json
output: reports
fail-on: high
allowed-hosts: staging.merchant.example
env:
ASSESSMENT_TOKEN: ${{ secrets.ASSESSMENT_TOKEN }} # read by ${ASSESSMENT_TOKEN} in the config
- name: Upload evidence
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a
with:
name: settlens-reports
path: reports/
if-no-files-found: error
retention-days: 30
The schedule turns the same job into a recurring check of production endpoints. To compare each run with the previous one and alert only on changes, use Monitor instead.
Workflow in the Settlens repository
When the workflow lives in the repository that contains Settlens at its root, the Action is simply uses: ./. This is the shape of the example shipped in the repository (examples/github-workflow.yml), where the allowlist comes from a repository variable:
name: Settlens
on:
pull_request:
workflow_dispatch:
permissions:
contents: read
jobs:
x402-assessment:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
- name: Assess x402 endpoints
uses: ./
with:
config: settlens.config.json
fail-on: high
allowed-hosts: ${{ vars.SETTLENS_ALLOWED_HOSTS }}
- name: Upload evidence
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a
with:
name: settlens-reports
path: reports/
if-no-files-found: error
retention-days: 30
Secrets and custom headers
When a target needs authentication, reference the secret from the config as ${NAME}, provide it to the step as an environment variable, and list the target's hostname in allowed-hosts. Settlens refuses to send any custom header to a host that is not on that list, and it never writes header values to reports. See Headers and secrets.
Workflows triggered by pull_request from a fork do not receive repository secrets, so targets that need them cannot be assessed on fork pull requests.
SARIF and code scanning
The SARIF file lists failing and warning checks, one rule per check id (format details in Reports).
Settlens findings concern a URL, not a line of code, but code scanning only displays results that have a location. Each result is therefore anchored at line 1 of the file named by the config input, so the alerts appear on your configuration file, with the target URL in the message. Each target gets its own fingerprint, so the same check failing on two endpoints stays two alerts.
Code scanning on private repositories
On private repositories, code scanning requires GitHub Code Security; without it the upload fails. The findings are also in the job status, the console summary and the uploaded JSON and HTML reports.
To upload the file, the job needs the security-events: write permission, and the condition below skips fork pull requests, whose token cannot write security events:
# Add to the job: permissions: { contents: read, security-events: write }
- name: Upload SARIF
if: >-
always() &&
hashFiles('reports/**/*.sarif') != '' &&
(github.event_name != 'pull_request' ||
github.event.pull_request.head.repo.full_name == github.repository)
uses: github/codeql-action/upload-sarif@7188fc363630916deb702c7fdcf4e481b751f97a
with:
sarif_file: reports
Permissions
contents: readis enough to run the Action and upload artifacts.- Add
security-events: writeonly to the job that uploads SARIF. - The Action needs no wallet, no private key and no write access. Settlens itself contacts only the targets and facilitators in your config; installing its dependencies contacts the npm registry.
Pinning
- Pin the Settlens checkout to a full commit SHA (
ref:), never a branch, so a change to the repository cannot change what runs in your CI without a review. - Pin every third-party action to a full 40-character commit SHA.
action.ymlitself pinsactions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041eand Node.js 24. - Dependencies come from the lockfile with
npm ci --prefix "$GITHUB_ACTION_PATH" --omit=dev --ignore-scripts: exact versions, no development dependencies and no install scripts. - Keep
allowed-hostsin the workflow or in a repository variable, never in the config file it protects.
Next: tune the configuration, look up findings in the check catalog, or request a pilot to get access to the repository.
Sources
Last updated