
sshconfig-lint v0.5.0
Rule-based linter for OpenSSH client config files that detects duplicate hosts, missing identity files, weak algorithms, wildcard ordering issues, and dangerous settings with JSON output and CI-friendly exit codes.
sshconfig-lint
One engine for every place your SSH config changes.
sshconfig-lint finds semantic mistakes in OpenSSH client configs: duplicate hosts, broken identity paths, unsafe options, weak algorithms, wildcard ordering, and tangled Include chains. Use the same rule codes locally, in Git hooks, GitHub Actions, and editors.
Try the private browser playground · Learn with interactive examples · Read every rule
The browser checker runs on your device. Config contents are not uploaded and no telemetry is collected.
Quick start
# check ~/.ssh/config
sshconfig-lint
# check one or more repository configs
sshconfig-lint .ssh/config infrastructure/ssh_config
# fail on warnings and errors
sshconfig-lint .ssh/config --strict
Install
Homebrew
brew tap Noah4ever/tap
brew install sshconfig-lint
Cargo
cargo install sshconfig-lint
Arch Linux
yay -S sshconfig-lint-bin
The release page provides verified binaries for Linux, macOS, and Windows. The convenience installer verifies the release checksum before installing:
curl -fsSL https://raw.githubusercontent.com/Noah4ever/sshconfig-lint/main/install.sh | bash
Set VERSION=v0.5.0 or INSTALL_DIR=~/.local/bin to override the defaults.
GitHub Actions
name: SSH config
on: [push, pull_request]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: Noah4ever/[email protected]
with:
paths: |
.ssh/config
infrastructure/ssh_config
strict: true
Findings appear as annotations on the exact file and line. The Action downloads the release matching its tag and verifies SHA256SUMS before execution.
For repositories with GitHub Code Scanning enabled, SARIF can be uploaded separately:
- run: sshconfig-lint .ssh/config --format sarif > sshconfig-lint.sarif
- uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: sshconfig-lint.sarif
Pre-Commit
repos:
- repo: https://github.com/Noah4ever/sshconfig-lint
rev: v0.5.0
hooks:
- id: sshconfig-lint-strict
Use id: sshconfig-lint when warnings should not block a commit. Override files: in your project when configs use another naming convention.
Editors
Install the VS Code extension from the Marketplace or run:
code --install-extension NoahThiering.sshconfig-lint
The extension starts sshconfig-lint lsp, downloads a matching verified binary once, and then works offline. It recognizes .ssh/config, ssh_config, and chezmoi's dot_ssh/config. No telemetry is collected. Its source is available in editors/vscode.
Any editor with LSP support can start:
sshconfig-lint lsp
The v0.5 language server publishes full-line diagnostics on open, change, and save. Untitled buffers run content-only rules; saved files additionally resolve Include and filesystem paths.
Output formats
sshconfig-lint --format text
sshconfig-lint --format json
sshconfig-lint --format github
sshconfig-lint --format sarif
JSON findings contain severity, code, rule, line, file, message, hint, and documentation. Rule codes and exit codes are stable automation interfaces.
| Exit | Meaning |
|---|---|
0 | No error-level finding, and no warnings with --strict |
1 | At least one blocking finding |
2 | At least one requested config could not be read |
Rules
| Code | Rule | Severity |
|---|---|---|
DUP_HOST | Duplicate Host block | warning |
MISSING_IDENTITY | IdentityFile not found | error |
WILDCARD_ORDER | Host wildcard order | warning |
WEAK_ALGO | Weak algorithm | warning |
DUP_DIRECTIVE | Duplicate directive | warning |
INSECURE_OPT | Insecure option | warning |
UNSAFE_CTRL_PATH | Unsafe ControlPath | warning |
INCLUDE_CYCLE | Include cycle | error |
INCLUDE_READ | Include cannot be read | error |
INCLUDE_GLOB | Invalid Include pattern | error |
INCLUDE_NO_MATCH | Include matches no files | info |
The rule guides show the exact broken fragment, a corrected config, why it matters, and how to verify the result with OpenSSH.
Development
Requires Rust 1.85 or newer.
cargo test --all
cargo clippy --all-targets --all-features -- -D warnings
cargo fmt -- --check
See CONTRIBUTING.md, the public roadmap, and security policy.
License
MIT