Repository navigation
Tuner CI
Run Tuner on a schedule or on every deploy, show its findings in GitHub's Security tab and fail a pipeline when something serious appears. This page covers GitHub Actions in detail; the same commands work in any CI.
Tuner writes SARIF, which GitHub turns into code scanning alerts: each finding appears in the repository's Security → Code scanning list, with its severity, the fix and history across runs.
# .github/workflows/tuner.yml
name: tuner
on:
schedule: [{cron: "0 6 * * 1"}] # Mondays 06:00 UTC
workflow_dispatch:
permissions:
contents: read
security-events: write # upload SARIF
jobs:
scan:
runs-on: ubuntu-latest
steps:
- name: Install Tuner
run: |
curl -fsSL https://rythm.sh/install | sh
echo "$HOME/.local/bin" >> "$GITHUB_PATH"
- name: Scan
run: rhythm tuner scan https://staging.yoursite.com --sarif -o tuner.sarif
- uses: github/codeql-action/upload-sarif@v3
if: always() # upload what was found even if the scan step failed
with:
sarif_file: tuner.sarifTip
On GitHub Actions, uses: RhythmShahriar/rhythm/setup@v0.7.0 with tools: tuner installs rhythm and Tuner with signatures checked, caches the downloads and puts them on PATH; it can also install the versions a rhythm.lock pins. See CI setup.
Note
Code scanning is free for public repositories. For private ones it needs GitHub Advanced Security; without it, keep the report as an artifact instead (see Keeping reports).
--fail-on <severity> makes the scan exit with code 1 when any finding is at or above that severity:
rhythm tuner scan https://staging.yoursite.com --fail-on high| Exit code | Meaning |
|---|---|
| 0 | done; no finding at or above --fail-on (or --fail-on not set) |
| 1 | a finding at or above --fail-on
|
| 2 | usage error (a bad flag or target) |
| 3 | a site couldn't be scanned, e.g. it was unreachable |
| 130 | interrupted |
When several sites are scanned, findings are checked first: if any report meets --fail-on, the exit code is 1 even if another site was unreachable.
Tip
--fail-on counts every finding, including ones marked likely (low confidence, e.g. a server version a distribution may have patched). Accept the ones you've verified with a baseline, or leave a whole check out with --exclude-id.
A typical deploy gate scans staging after the deploy step and blocks promotion on high or critical findings:
- name: Security gate
run: rhythm tuner scan https://staging.yoursite.com --fail-on high --md -o tuner.mdSome findings you'll accept, at least for now: a header you can't change on shared hosting, a likely finding you've confirmed is patched. Save a report once and pass it as a baseline; only findings that aren't in it are reported and counted for --fail-on.
rhythm tuner scan https://staging.yoursite.com -o tuner-baseline.json
rhythm tuner scan https://staging.yoursite.com --baseline tuner-baseline.json --fail-on mediumFindings are matched by check ID and URL. Commit the baseline to the repository so accepting a finding is a reviewed change. The summary line shows how many were hidden ("3 baselined"). A finding that changes (for example a plugin gets a new vulnerability) keeps the same ID and URL, so review the baseline when you update it.
Every format can be written to a file and kept as a build artifact:
- run: rhythm tuner scan https://staging.yoursite.com -o tuner.md --fail-on high
- uses: actions/upload-artifact@v4
if: always()
with:
name: tuner-report
path: tuner.md-o picks the format from the extension (.json, .jsonl, .sarif, .md) and still prints the live view to the log. See Output and reports.
Cache the vulnerability data between runs. Tuner refreshes it once it's a day old either way; the cache just saves the lookups:
- uses: actions/cache@v4
with:
path: ~/.cache/rhythm
key: rhythm-cache-${{ github.run_id }}
restore-keys: rhythm-cache-Pin the version when a pipeline must not change behavior on its own. The installer always fetches the newest Tuner (RHYTHM_VERSION pins rhythm only), so for a pinned Tuner download the release directly and check it against the release checksums:
- name: Install Tuner 0.3.2 (pinned)
run: |
v=0.3.2
base=https://github.com/RhythmShahriar/tuner/releases/download/v$v
curl -fsSLO "$base/rhythm-tuner_linux_amd64.tar.gz"
curl -fsSLO "$base/checksums.txt"
sha256sum --ignore-missing -c checksums.txt
tar -xzf rhythm-tuner_linux_amd64.tar.gz rhythm-tuner
sudo install rhythm-tuner /usr/local/bin/rhythm-tuner is the tool itself; rhythm tuner … only forwards to it, so rhythm-tuner scan … works without installing rhythm. New checks still arrive through check packs; add --no-check-updates to freeze those too.
In CI, Tuner never prints the "new release" notice: it's off whenever the CI environment variable is set, which GitHub Actions and most CI systems do.
Nothing above is GitHub-specific except the SARIF upload. In GitLab CI, Jenkins or a cron job, install with the same one-liner, run the scan with --fail-on and keep -o report.md or -o report.json as an artifact. For many sites at once, see Batch scans.
Important
Point CI at sites you own or are authorized to test, ideally staging. Scheduled scans of production are fine at Tuner's default rate (5 requests a second); see Requests and politeness.
← PHP advisories · Home · Writing checks →
rhythm · Useful ideas. Working systems. · Check only sites you own or have permission to test. Keep staging sealed (responsible use) · This wiki is published from wiki/ in the rhythm repository; suggest changes there with a pull request.
Get started
rhythm in depth
Tuner
- Overview
- Your first scan
- Reading results
- Choosing checks
- Requests and politeness
- Output and reports
- Batch scans
- Local scans
Tuner in depth
- Known vulnerabilities
- PHP advisories
- CI and code scanning
- Writing checks
- Check packs
- Finding reference
- CLI reference
- FAQ and troubleshooting
Soundcheck
- Overview
- Your first check
- Reading results
- Discovery
- Page health
- Visual changes
- Interactions
- Forms and flows
- Cache
- Speed
Soundcheck in depth
Echo
- Overview
- Your first run
- Connectors
- Sealing staging
- Messages and checks
- Actions and compare
- With Soundcheck
- Replay
- Deliverability
Echo in depth
Project