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.
# 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
brew tap Noah4ever/tap
brew install sshconfig-lint
cargo install sshconfig-lint
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.
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
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.
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:
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.
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 |
The rule guides show the exact broken fragment, a corrected config, why it matters, and how to verify the result with OpenSSH.
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.
MIT