| Crates.io | vsec |
| lib.rs | vsec |
| version | 0.0.1 |
| created_at | 2026-01-06 18:27:18.537635+00 |
| updated_at | 2026-01-06 18:27:18.537635+00 |
| description | Detect secrets and in Rust codebases |
| homepage | https://github.com/vsec-scan/vsec |
| repository | https://github.com/vsec-scan/vsec |
| max_upload_size | |
| id | 2026452 |
| size | 622,358 |
A research-grade static analysis tool for detecting hardcoded secrets in Rust codebases with intelligent false-positive filtering.
--scan-historycargo install --path .
Or build from source:
cargo build --release
# Scan directory
vsec scan --scan-history --config .vsec.toml ../rustfs
# Scan with lower threshold (more findings)
vsec scan --scan-history --config .vsec.toml --threshold 50
# Include test and example files
vsec scan --scan-history --config .vsec.toml --include-tests --include-examples
# Output as JSON
vsec scan --scan-history --config .vsec.toml -f json -o results.json
# Output as SARIF (for CI integration)
vsec scan --scan-history --config .vsec.toml -f sarif -o results.sarif
# Fail CI if findings exist
vsec scan --scan-history --config .vsec.toml --fail-on-findings
# Create default config file
vsec init
# Create minimal config
vsec init --minimal
# Specify output path
vsec init -o my-config.toml
# Get details about a specific finding
vsec explain SEC-abc123 --results results.json
# Show parsing details for a file
vsec debug src/auth.rs
# Include AST dump
vsec debug src/auth.rs --show-ast
Scan git history to find secrets that were committed and later deleted:
# Scan git history (requires --scan-history flag)
vsec scan --scan-history
# Limit to last 100 commits
vsec scan --scan-history --max-commits 100
# Only scan commits after a specific date
vsec scan --scan-history --since 2024-01-01
# Combine with other options
vsec scan --scan-history -f sarif -o history-results.sarif
Note: Git history scanning is opt-in because it can be slow on large repositories with many commits. Use it for security audits, not daily CI.
Create a .vsec.toml file in your project root:
[general]
# Sensitivity preset: "paranoid", "high", "normal", "low", or a number
sensitivity = "normal"
[scan]
# Patterns to ignore
ignore_paths = ["target", "vendor", ".git"]
# Include test files in scan
include_tests = false
# Include example files in scan
include_examples = false
[output]
# Show score breakdown for each finding
show_scores = false
# Show remediation suggestions
show_remediation = true
| Preset | Threshold | Use Case |
|---|---|---|
paranoid |
40 | Security audits, pre-release reviews |
high |
55 | CI/CD with manual review |
normal |
70 | Regular development (default) |
low |
85 | Large codebases, automated blocking |
Secretrace focuses on equality comparisons involving string constants, not just constant definitions. This approach catches actual authentication bypass vulnerabilities:
// This pattern is detected:
const AUTH_TOKEN: &str = "sk_live_12345";
fn authenticate(token: &str) -> bool {
if token == AUTH_TOKEN { // <- Comparison triggers detection
grant_access();
return true;
}
false
}
The four-layer filter pipeline eliminates common false positives:
VERSION, COLOR, HELP_TEXT are benignif cmd == "help") is filteredFindings are scored based on multiple factors:
| Factor | Impact |
|---|---|
| Suspicious name (password, secret, key) | +20 to +40 |
| High entropy value | +20 |
| Auth consequence (grant_access, authorize) | +25 |
| Long value (32+ chars) | +15 |
| Benign name (version, color, help) | -100 (killed) |
| Test context | -100 (killed) |
| Short value (<8 chars) | -20 |
| Placeholder pattern | -50 |
Human-readable output with colors and formatting.
Machine-readable format for tooling integration.
Static Analysis Results Interchange Format for CI/CD integration (GitHub, Azure DevOps, etc.)
Report format suitable for documentation or PR comments.
GitHub Actions annotation format for inline PR comments.
- name: Scan for secrets
run: |
cargo install vsec
vsec scan -f sarif -o results.sarif --fail-on-findings
- name: Upload SARIF
uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: results.sarif
#!/bin/bash
vsec scan --fail-on-findings -t 70
┌─────────────────────────────────────────────────────────────┐
│ Scanner │
├─────────────────────────────────────────────────────────────┤
│ Phase 1: Indexer │
│ - Parallel file parsing (rayon + syn) │
│ - Build SuspectRegistry (DashMap) │
│ - Index public constants │
├─────────────────────────────────────────────────────────────┤
│ Phase 2: Analyzer │
│ - Find equality comparisons │
│ - Resolve constant references │
│ - Run filter pipeline │
│ - Score findings │
├─────────────────────────────────────────────────────────────┤
│ Filter Pipeline │
│ ┌─────────┐ ┌─────────┐ ┌─────────────┐ ┌────────────┐ │
│ │ Layer 1 │→│ Layer 2 │→│ Layer 3 │→│ Layer 4 │ │
│ │ Names │ │ Scope │ │ Consequence │ │ RHS │ │
│ └─────────┘ └─────────┘ └─────────────┘ └────────────┘ │
├─────────────────────────────────────────────────────────────┤
│ Scoring Engine │
│ - Entropy analysis │
│ - Pattern matching │
│ - Factor aggregation │
│ - Threshold application │
└─────────────────────────────────────────────────────────────┘
Vsec is dual-licensed under either:
at your option.