-
-
Notifications
You must be signed in to change notification settings - Fork 0
Pattern Development
Aegis patterns ship as Rust structs in
crates/aegis-patterns/src/
and are compiled into every surface. Two more paths exist for extending
detections without touching the compiled corpus:
- Rust — core patterns, reviewed and shipped with the binary
-
YAML — contributions bundled into a pattern pack with
aegis-bundler -
.aegis.yml— per-project custom patterns merged in at scan time
A pattern is a regex plus metadata. The regex uses the Rust regex
crate (RE2 syntax): no lookarounds, . does not cross newlines,
and nested quantifiers cannot backtrack (keep repetitions bounded
anyway).
1. Use word boundaries
# BAD - matches substrings
sk-[A-Za-z0-9]{32}
# GOOD - whole tokens only
\bsk-[A-Za-z0-9]{32}\b2. Be specific
# TOO GENERIC - many false positives
[A-Z]{2}-[A-Z]{5}
# SPECIFIC - identifiable prefix + assignment context
\bapi[_-]?token["\s]*[:=]["\s]*[A-Za-z0-9]{32,}3. Set an entropy floor for secrets — low-entropy matches
(password123) are usually placeholders:
min_entropy: Some(3.5)
4. Suppress safe idioms with exclude — when the exclude regex also
matches the candidate span, the finding is suppressed. Use it to exempt
documentation examples and placeholders. The exclude only sees the
matched span, not the rest of the line.
5. Never use nested quantifiers that can explode — the RE2 engine will not hang, but unbounded nesting still wastes cycles:
# BAD
(a+)+$
# GOOD
\ba{8,32}\bAdd a Pattern to the appropriate module in
crates/aegis-patterns/src/<category>.rs:
Pattern {
name: "my-service-key".to_string(),
category: "secrets".to_string(),
match_pattern: r#"(?i)myservice[_-]?key\s*[:=]\s*['"][A-Za-z0-9]{16,}"#.to_string(),
enabled: true,
severity: "high".to_string(), // critical | high | medium | low
confidence: "high".to_string(), // high | medium | low
min_entropy: Some(3.5),
description: "Detects hardcoded MyService keys".to_string(),
reference: Some("https://docs.example.com/security".to_string()),
tags: vec!["secrets".to_string(), "api-key".to_string()],
env_var: false, // true = only runs during `aegis scan --env`
binary: false, // true = may match inside binary files
exclude: Some(r#"(?i)example|placeholder|your[-_]key"#.to_string()),
file_extensions: Vec::new(), // empty = every text file
}Then:
- Add the pattern to
crates/aegis-patterns/src/lib.rsdispatch if it opens a new category. - Run
cargo run -p aegis-patterns --example generate_docs— the generated catalog must stay fresh; a CI test fails otherwise. - Add positive/negative fixtures to
crates/aegis-cli/tests/pattern_fixtures.rs. -
scripts/generate_examples.pybackfills the liveness example — every shipped pattern must have a provably firing example (pattern_liveness.rsfails CI without one).
Naming rules: pattern names and categories are kebab-case
(my-service-key); the hygiene tests reject anything else. Categories
must already exist in aegis_patterns::by_category().
YAML contributions skip the recompile step. Each pattern is a document in a YAML list (field names mirror the Rust struct):
- name: my-service-key
category: secrets
match: '(?i)myservice[_-]?key\s*[:=]\s*["''][A-Za-z0-9]{16,}'
severity: high
confidence: high
min_entropy: 3.5
description: Detects hardcoded MyService keys
enabled: trueBundle it and load it into a running MCP server:
cargo build --release -p aegis-bundler
./target/release/aegis-bundler ./patterns-dir ./my-patterns.bundle
# then: MCP method update_bundle with params ["./my-patterns.bundle", true]A scan root may contain a .aegis.yml (or .aegis.yaml) file whose
patterns are merged into the registry before the walk — useful for
project-specific rules without shipping them globally. See the
CLI guide.
Every pattern in the corpus is covered by three CI-enforced suites — mirror them for new rules:
-
Liveness (
pattern_liveness.rs): the pattern fires on its stored example, generated byscripts/generate_examples.py. -
Hygiene (
registry_hygiene.rs): regexes compile, names and categories are kebab-case, severities/confidences are enumerated values, references are real HTTPS URLs, entropy floors sit in the Shannon range, and the generated docs are fresh. -
Precision/recall (
corpus_precision_recall.rs): fixtures incrates/aegis-core/tests/corpus/keep false positives at or below a measured gate.
Manual check:
cargo run -p aegis-cli -- scan --stdin <<< 'myservice_key = "AbCdEf1234567890AbCdEf1234567890"'- Fork the repository and create a branch
- Add the pattern (Rust or YAML) with fixtures and an example
- Run the gates:
cargo fmt --all,cargo clippy --workspace --all-targets -- -D warnings,cargo test --workspace - Submit a pull request
See CONTRIBUTING for full guidelines.
- ✅ Specificity — uses word boundaries
\bwhere appropriate - ✅ Accuracy — minimal false positives on real code
- ✅ Clarity — name clearly describes what it detects (kebab-case)
- ✅ Testing — liveness example + precision fixtures pass
- ✅ Entropy — appropriate
min_entropyfor secret-shaped rules - ✅ Metadata — description, tags, and a reference URL
- ✅ Docs — generated catalog regenerated and committed
[0-9]{32} # matches ANY 32-digit numberpassword # matches "password" anywhere, including prose(?<=prefix)token # lookarounds do not exist in RE2 — express "prefix
# without capturing it" via the exclude field instead| Resource | Link |
|---|---|
| Documentation | docs/ |
| GitHub Repository | aliasfoxkde/aegis |
| Issue Tracker | Report Issues |
| Discussions | GitHub Discussions |
| Pattern Catalog | 660 patterns across 34 categories |
Aegis is an open-source security scanning tool.
Aegis is provided as-is for security scanning purposes. While it aims to detect security issues accurately, it may produce false positives and negatives. Always validate findings manually. The developers are not liable for any damages resulting from use of this tool.
See Releases for the current version and the changelog for what shipped in each. The pattern catalog is generated from the source and always reflects the shipped rule set.
Built with Rust for performance and reliability.
- Installation Guide - Binary releases, Docker
- Quick Start - Basic workflows
- CLI Reference - All commands
- Configuration - Profiles and options
- CI/CD Integration - GitHub, GitLab, Jenkins
- MCP Server - AI tool integration
- Building from Source - Contributor setup
- Adding Patterns - Rust and YAML contribution
- Architecture - System design
- Coding Standards - Rust conventions
- Pattern Catalog - All 660 patterns, one detail page per category
- Secrets - API keys, credentials
- Security Hardening - Security best practices
- Web Security - XSS, injection, CORS, SSRF
- AI Safety - Agentic and LLM safety checks
- Project Plan - Roadmap and milestones
- Changelog
- Releases