| Crates.io | shapash |
| lib.rs | shapash |
| version | 0.1.15 |
| created_at | 2026-01-24 02:53:33.905976+00 |
| updated_at | 2026-01-24 02:53:33.905976+00 |
| description | A deterministic, auditable forward-chaining rule engine with pluggable scoring |
| homepage | |
| repository | https://github.com/Sing-Security/Shapash |
| max_upload_size | |
| id | 2065962 |
| size | 85,516 |
Shapash is a deterministic, auditable forward-chaining rule engine designed for security analysis, compliance workflows, and intelligent automation.
.rule files with inline or external HEL conditionsCreate a .rule file:
[[rule]]
id = "high-risk-taint"
description = "Dangerous taint flow detected"
condition = 'TaintFlow.sink == "strcpy"' # Inline HEL
score = 75
justification = "strcpy is unsafe with untrusted input"
[[rule]]
id = "security-check"
description = "Complex security validation"
condition_file = "conditions/nx-check.hel" # External HEL script
score = 85
justification = "NX protection should be enabled"
use shapash::{HeuristicEngine, Fact, TaintFlow};
use std::collections::HashSet;
// Load rules from .rule files
let engine = HeuristicEngine::from_paths("rules/", None)?;
// Provide facts for evaluation
let mut facts = HashSet::new();
facts.insert(Fact::TaintFlow(TaintFlow {
source: "network".into(),
sink: "strcpy".into(),
}));
// Execute rule engine
let report = engine.execute(facts);
println!("Final Score: {}", report.final_score);
for rule in &report.triggered_rules {
println!(" ✓ {}: {}", rule.rule_id, rule.description);
}
Implement your own scoring logic:
use shapash::{ScoringModel, TriggeredRuleInfo};
struct CustomScorer;
impl ScoringModel for CustomScorer {
fn score(&self, triggered: &[TriggeredRuleInfo]) -> u32 {
// Custom scoring algorithm
triggered.iter().map(|r| r.score).max().unwrap_or(0)
}
}
let report = engine.execute_with_scorer(facts, &CustomScorer)?;
Rules support both inline and external HEL conditions:
[[rule]]
id = "example"
condition = 'binary.arch == "x86_64" AND security.nx == false'
score = 50
justification = "..."
description = "..."
[[rule]]
id = "example"
condition_file = "conditions/android-malware.hel"
score = 90
justification = "..."
description = "..."
File: conditions/android-malware.hel
let has_sms = manifest.permissions CONTAINS "READ_SMS"
let obfuscated = binary.entropy > 7.5
has_sms AND obfuscated
┌─────────────────────────────────────────────┐
│ Shapash │
│ • Rule orchestration │
│ • Fact management │
│ • Scoring coordination │
└─────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────┐
│ HEL (external crate) │
│ • Expression evaluation │
└─────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────┐
│ Products │
│ • Inject domain-specific facts │
│ • Custom scoring models │
└─────────────────────────────────────────────┘
See examples/c01-simple-pipeline.rs for a complete working example.
Apache-2.0. See LICENSE for details.