Repository navigation
Tuner Config
A .tuner.yml next to your code keeps scan settings out of the command line and gives accepted risk a reviewed home: each ignore entry says why and until when. This page covers every key, how flags and the file combine and the rules that stop a file you didn't write from misusing your secrets.
# .tuner.yml
fail_on: high
min_confidence: confirmed
headers:
X-Scan-Token: ${TUNER_SCAN_TOKEN} # read from the environment, never printed
ignore:
- id: hdr-csp-missing
reason: the theme needs inline scripts; tracked in issue 42
until: 2026-12-31 # after this day the finding shows again
- id: wp-xmlrpc
reason: Jetpack needs it
until: 2026-09-30A scan reads .tuner.yml from the current folder only; it doesn't walk up to parent folders. --config <file> reads another file instead and --no-config reads none. The two don't go together. The checks command doesn't read the file.
Every scan that reads one says so on stderr, also under -q, --json and the other machine formats:
$ TUNER_SCAN_TOKEN=abc123 rhythm tuner scan http://127.0.0.1:20400 --plain
rhythm tuner scan: using .tuner.yml
rhythm tuner scan: ignore for wp-xmlrpc expired 2026-09-30: Jetpack needs it
rhythm tuner 0.4.0 - scanning http://127.0.0.1:20400 (config: .tuner.yml; local address: 50 req/s)
…
Score 0/100 after ignores (1 hidden) - 3 critical, 3 high, 1 medium, 6 low, 1 info - 77 checks, 179 requests, 3.6s
note: vulnerability data: WPVulnerability (wpvulnerability.com, CC0)
run rhythm tuner explain <id> for the full fix
rhythm tuner scan: .tuner.yml: 1 ignore entry hid 1 finding
The hdr-csp-missing entry hid its finding; the wp-xmlrpc entry had expired, so XML-RPC is reported again with a note naming the entry.
All keys are optional. An unknown key is an error that names its line, so a typo can't silently do nothing.
| Key | Same as | Notes |
|---|---|---|
targets |
targets on the command line | a list. Used only when no target comes from the command line, -l or --stdin. Folder targets are relative to the file's folder |
profile |
--profile |
quick or default, any case |
rate |
--rate |
0 means no limit |
concurrency |
-c |
|
fail_on |
--fail-on |
any case |
min_confidence |
--min-confidence |
confirmed or likely
|
baseline |
--baseline |
relative to the file's folder |
headers |
-H |
a map of name to value. ${TUNER_NAME} reads an environment variable (see below) |
tags, exclude_tags, ids, exclude_ids
|
--tags, --exclude-tags, --id, --exclude-id
|
lists |
ignore |
entries with id and/or path, a reason and an optional until (below) |
Not in the file (use flags): severity, timeout, retries, parallel, user agent, cookie, proxy and output format.
Flags win. A flag on the command line always overrides the file. A header from -H replaces the file's header of the same name (case-insensitive); the file's other headers are still sent. When the file sets rate or concurrency and the command line doesn't, the config note says so: rhythm tuner scan: using .tuner.yml; it sets --rate 2.
| Field | |
|---|---|
id |
a check or finding ID; globs work (hdr-*) |
path |
a finding path glob; the leading / is optional and * doesn't cross /
|
reason |
required, so the next person knows why the finding is accepted |
until |
optional, YYYY-MM-DD, inclusive: the entry applies through that day, local time |
An entry needs an id or a path (or both). A matched finding is hidden from the live view, every report format and the --fail-on and --fail-on-new gates. The score line says what hid it: after ignores (8 hidden), after baseline (1 hidden) or after baseline and ignores (9 hidden). After until, the entry hides nothing and each scan prints ignore for <id> <path> expired <date>: <reason>, also under -q.
Prefer ignore entries over a baseline for accepted risk you want reviewed: they're short, readable in a pull request and expire on their own. A baseline is better for a long list of findings at once. See CI and code scanning.
Header values can read the environment with ${NAME} (only that form; $NAME stays literal). Only variables whose names start with TUNER_ can be read, so a file can't pull an unrelated secret out of your CI environment:
$ rhythm tuner scan 127.0.0.1:20400 -q
rhythm tuner scan: .tuner.yml: headers: X-Leak uses ${SECRET_TOKEN}; only variables that start with TUNER_ can be used, so set TUNER_SECRET_TOKEN and name that
An unset or empty variable is an error too, because CI passes a missing secret as an empty string:
rhythm tuner scan: .tuner.yml: headers: X-Scan-Token uses ${TUNER_SCAN_TOKEN}, which is not set
Header values never appear in messages. In GitHub Actions, pass the secret under the TUNER_ name the file uses:
- run: rhythm tuner scan https://staging.yoursite.com --sarif -o tuner.sarif
env:
TUNER_SCAN_TOKEN: ${{ secrets.SCAN_TOKEN }}A scan reads .tuner.yml from the current folder, so a cloned repository or a pull request can bring its own. These rules keep such a file from turning your secrets or your scan against you. Each refusal is a usage error (exit 2) before any request.
-
A file that chooses the targets can't receive your secrets. When the targets come from the file,
-H,--cookieand file headers that read a${TUNER_...}variable are refused, so a pull request can't edittargets:to a host it controls and collect them. Name the targets on the command line, or use--no-config:$ rhythm tuner scan -q -H "Authorization: Bearer x" rhythm tuner scan: -H and --cookie need targets on the command line when .tuner.yml chooses them: name the targets or use --no-configHeaders written out in the file itself still go to the targets it chose.
-
A file found in the current folder stays in its folder. Its folder targets and
baselinecan't point outside the folder that holds it (no../site, absolute paths or~paths). A file named with--configmay. -
It always tells you. The config note names the file, the targets it chose and any
rateorconcurrencyit set. After the scan another line says how many findings its ignore entries and baseline hid:rhythm tuner scan: using .tuner.yml, which chose the target: http://127.0.0.1:20400; it sets --rate 2
Run rhythm tuner scan --no-config in folders you don't trust. The WP-CLI command runs Tuner in an empty temporary folder with --no-config, so a .tuner.yml in a web root can't hide findings from it.
Every config error names the file and, where it can, the line:
| Message | Fix |
|---|---|
.tuner.yml line 2: unknown key "profle" |
fix the key |
.tuner.yml: profile: "turbo": want quick or default |
use a listed value |
.tuner.yml: ignore 1 (leak-dotenv): needs a reason, so the next person knows why it is accepted |
add reason:
|
.tuner.yml: ignore 1: needs an id or a path |
add one |
.tuner.yml: ignore 1 (x): until "31/12/2026": want a date such as 2026-12-31 |
use YYYY-MM-DD
|
.tuner.yml: holds more than one YAML document; keep the settings in one |
remove the second --- section |
--config and --no-config don't go together |
pick one |
← GitHub Action · Home · Watch and serve →
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
- Integrity and malware
- Changes and notifications
Tuner in depth
- Known vulnerabilities
- PHP advisories
- CI and code scanning
- GitHub Action
- Config file
- Watch and serve
- Writing checks
- Check packs
- Finding reference
- CLI reference
- Coming from Wordfence CLI or WPScan
- FAQ and troubleshooting
Soundcheck
- Overview
- Your first check
- Reading results
- Review and accept
- Discovery
- Page health
- Visual changes
- Interactions
- Forms and flows
- Cache
- Speed
- Accessibility and SEO
Soundcheck in depth
- CI
- CI baselines and PR comments
- Configuration
- Error rules and exec
- WordPress updates
- Fleet and client reports
- History
- Import from BackstopJS and Lost Pixel
- Firefox and WebKit
- CLI reference
- FAQ and troubleshooting
- Benchmark
Echo
- Overview
- Your first run
- Connectors
- Sealing staging
- Echo Inbox
- Messages and checks
- Checks and rules
- Attachments
- Actions and compare
- With Soundcheck
- Replay
- Deliverability
Echo in depth
- Docker and DDEV
- Agency hub and reports
- Schedule
- MCP server
- Conformance kit
- CI
- Configuration
- API
- CLI reference
- FAQ and troubleshooting
- Benchmark
Project