rastray
Blazing-fast static analysis CLI for security, dependency, and performance audits.
rastray is a single-binary, Rust-native command-line scanner that walks a project tree in parallel and runs a registry of pluggable analyzers against it — looking for hard-coded secrets, vulnerable or out-of-date dependencies, and hot-path performance smells. It is designed to be fast enough to run in pre-commit hooks and strict enough to gate CI pipelines.
It is not another lint wrapper. rastray carries its own crawler, its own diagnostic renderer (powered by miette), and emits both human-friendly terminal output and machine-readable JSON from the same engine.
Why rastray?
Most security/dep/perf tools in the polyglot world fall into one of three buckets:
- Language-locked (
banditfor Python,npm auditfor Node,cargo auditfor Rust). You end up running four of them in CI. - Heavy SaaS (Snyk, SonarQube). Paid, network-dependent, slow.
- Generic linters with plugins. Good signal, but configuration sprawl.
rastray aims to be the fourth option: one offline binary, one config-free invocation, polyglot from day one, and aggressively fast because it is built on ignore::WalkBuilder (the engine that powers ripgrep) plus a tokio runtime for network-bound advisory lookups.
Installation
Prebuilt binaries (recommended)
Each release attaches statically-linked binaries for the common platforms. The shell installer downloads, checksum-verifies, and extracts the right archive for your OS / arch:
Linux / macOS
|
Windows (PowerShell)
irm https://github.com/balangyaoejuspher/rastray/releases/latest/download/install.ps1 | iex
Both installers honor RASTRAY_VERSION (e.g. 0.1.0) and
RASTRAY_INSTALL_DIR. See install/README.md for
details.
From crates.io
Prerequisites (for source builds)
- Rust 1.86.0 or newer (
rustup default stable) - A working C/C++ toolchain for linking:
- Windows → Visual Studio Build Tools with the Desktop development with C++ workload (provides
link.exe) - macOS → Xcode Command Line Tools (
xcode-select --install) - Linux →
build-essential/gcc+pkg-config
- Windows → Visual Studio Build Tools with the Desktop development with C++ workload (provides
From source
# Binary lands at ./target/release/rastray
Usage
PATH defaults to the current directory.
Common invocations
# Scan the current project, human-friendly output
# Scan a specific directory, only show medium+ findings
# Emit JSON for CI ingestion
# Force inclusion of hidden files and ignored paths
# Limit parallelism (default is num_cpus)
# Crank verbosity for debugging the crawler
Flags
| Flag | Default | Description |
|---|---|---|
PATH |
. |
Directory or file to scan. |
--min-severity <LEVEL> |
low |
Suppress findings below this severity. One of: info, low, medium, high, critical. |
--json |
off | Shortcut for --format json. |
--format <FMT> |
inferred | human, json, gh-actions, or sarif. Overrides --json when both are set. |
-o, --output <FILE> |
stdout | Write json / sarif output to a file instead of stdout. No effect for human/gh-actions. |
--no-ignore |
off | Ignore .gitignore, .ignore, and global ignore files. |
--hidden |
off | Descend into hidden files and directories. |
--follow-links |
off | Follow symlinks during the walk. |
-j, --threads <N> |
auto | Worker thread count for the parallel crawler. |
--max-depth <N> |
unlimited | Cap directory recursion depth. |
--config <FILE> |
auto | Path to a .rastray.toml config file. By default, rastray walks up from the scan path looking for one. |
--no-config |
off | Skip config-file discovery and loading. |
--fail-on <LEVEL> |
inherited | Exit code 1 if any finding is at or above this severity. One of: info, low, medium, high, critical, never. Defaults to --min-severity. Overrides [scan].fail_on in config. |
-v, --verbose |
off | Repeat for more detail (-v, -vv, -vvv). |
-q, --quiet |
off | Suppress non-finding output. Mutually exclusive with --verbose. |
Configuration file
If a .rastray.toml file exists in the scan directory (or any ancestor),
rastray loads it automatically. Use --config to point at a specific file
or --no-config to skip loading entirely.
[]
= "high" # exit non-zero only on findings >= high (default: any)
[]
= ["target/**", "dist/**", "vendor/**"]
[]
= false # disable a rule entirely
= { = "low" } # downgrade a rule's severity
= { = false } # explicit form
Exit codes
rastray follows the standard CI-friendly convention:
| Code | Meaning |
|---|---|
0 |
Scan completed; no findings at or above the fail-on threshold. |
1 |
Scan completed; at least one finding at or above the fail-on threshold. |
2 |
Runtime error (I/O failure, malformed input, configuration error). |
The fail-on threshold defaults to --min-severity and can be overridden
via --fail-on <LEVEL> or [scan].fail_on in .rastray.toml. Use
--fail-on never (or fail_on = "never") to always exit 0 regardless
of findings — useful for advisory CI runs.
Wire it into CI as:
||
Architecture
┌────────────┐
│ cli.rs │ clap-derive parser
└─────┬──────┘
│ Cli
┌─────▼──────┐
│ crawler.rs │ ignore::WalkBuilder + mpsc aggregator
└─────┬──────┘
│ CrawlSummary
┌─────▼──────┐
│ modules/ │ Analyzer trait registry
│ secrets │
│ deps │
│ perf │
└─────┬──────┘
│ Vec<Finding>
┌─────▼──────┐
│ reporter.rs│ Human (miette) | JSON (serde)
└────────────┘
main.rs— orchestrator. Installs themiettehook, parses CLI, runs the crawler, dispatches analyzers, applies severity filtering, renders, returnsExitCode.cli.rs—clapderive structs (Cli,Severity,OutputFormat). Handles--json/--formatreconciliation.crawler.rs— parallel filesystem walk. Hard-blocks noise dirs (.git,node_modules,target,dist,build,.venv,venv,__pycache__). Classifies each entry asManifest | Source | Config | Other.reporter.rs—Finding,Location,Report. Dual renderer:miette::Diagnosticfor humans,serde_json::to_string_prettyfor machines. Source spans are read lazily and degrade gracefully on I/O errors.modules/— analyzer trait + registry. New analyzers implementAnalyzerand are appended todefault_registry().
Adding a new analyzer
- Create
src/modules/<name>.rs. - Define a unit struct and implement
Analyzer:; - Register it in
default_registry()insrc/modules/mod.rs.
JSON output schema
{
"stats": {
"files_scanned": 0,
"manifests": 0,
"source_files": 0,
"config_files": 0,
"other_files": 0,
"crawl_errors": 0,
"skipped": 0,
},
"perf": {
"walk_ms": 0,
"analyze_ms": 0,
"total_ms": 0,
"bytes_scanned": 0,
},
"findings": [
{
"code": "RSTR-XXX-000",
"message": "...",
"severity": "low|medium|high|critical|info",
"category": "secret|dependency|performance|crawler|internal",
"help": "remediation hint or null",
"location": {
"file": "relative/path/to/file",
"line": 0,
"column": 0,
"byte_offset": 0,
"byte_length": 0,
},
},
],
}
The JSON output is considered stable within a minor version and follows semantic versioning. See CHANGELOG.md for any schema additions.
Continuous integration
A ready-to-copy GitHub Actions workflow is available under
examples/github-actions/. It runs rastray
on every push and pull request, posts findings as inline annotations
(--format gh-actions), and uploads a SARIF report to GitHub Code
Scanning (--format sarif --output rastray.sarif).
See examples/github-actions/README.md
for setup instructions.
Drop-in .rastray.toml snippets for common adoption patterns (advisory,
strict, monorepo) are in examples/config/.
Security
rastray is itself a security-focused tool, so it holds itself to its own standards:
- No
unsafeRust anywhere in the codebase. - No
unwrap/expect/panic!in user-facing code paths. - TLS via
rustlsonly — no OpenSSL surface area. - Minimal default feature flags on
tokioandreqwestto keep the dependency graph small. - Pinned MSRV (
1.86.0).
To report a vulnerability, please do not open a public issue. See SECURITY.md for the disclosure process.
Contributing
rastray is currently source-available but closed to external code contributions
while the architecture stabilises. Bug reports, security reports, feature requests,
and forks are welcome. See CONTRIBUTING.md for the full policy
and the rules that apply to pre-approved pull requests.
License
Licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.