Streaming sensitive-data detection and redaction engine for MoonBit
moon add sujy123456/lunasieve///|
import {
"sujy123456/lunasieve",
}///|
fn main {
let input = "user=alice@example.com token=ghp_abcdefghijklmnopqrstuvwxyz0123456789"
let result = @lunasieve.scan(input)
println("findings: \{result.findings.length()}")
println(result.redacted)
}moon run cmd/main///|
let policy = @lunasieve.Policy::new([
@lunasieve.Rule::new("email", Mask(fill='*', keep_start=2, keep_end=3)),
@lunasieve.Rule::new("github-pat", Replace("[GITHUB_TOKEN]")),
@lunasieve.Rule::new("cn-identity", Drop),
])
///|
let result = @lunasieve.Scanner::new(policy~).scan(input)///|
let stream = @lunasieve.StreamScanner::new(overlap=128)
///|
let first = stream.push("contact alice@")
///|
let second = stream.push("example.com next")
///|
let remaining = stream.finish()///|
let scanner = @lunasieve.LiteralScanner::new([
@lunasieve.LiteralRule::new(
"internal-key",
"ACME-SECRET",
boundary=Word,
case_sensitive=false,
),
])
///|
let allowlist = [
@lunasieve.AllowRule::new(
detector_id="email",
exact_value="example@example.com",
reason="documentation fixture",
),
]let result = @lunasieve.scan_documents([
@lunasieve.Document::new("service.env", env_text),
@lunasieve.Document::new("application.log", log_text),
])
println(@lunasieve.batch_to_text(result))
let sarif = @lunasieve.batch_to_sarif(result)moon fmt --check
moon check
moon test
moon build --release
moon package./tools/generate_catalog_tests.ps1pub(all) struct BatchResult {
findings : Array[DocumentFinding]
summary : BatchSummary
} derive(Eq, Debug)pub(all) struct BatchSummary {
documents : Int
bytes : Int
findings : Int
critical : Int
high : Int
medium : Int
low : Int
info : Int
by_detector : Array[DetectorCount]
} derive(Eq, Debug)pub(all) struct DocumentFinding {
path : String
finding : Finding
start : SourceLocation
end : SourceLocation
fingerprint : String
} derive(Eq, Debug)pub(all) struct Finding {
detector_id : String
kind : DetectorKind
severity : Severity
span : Span
confidence : Int
preview : String
message : String
} derive(Eq, Debug)fn Finding::new(detector_id : String, kind : DetectorKind, severity : Severity, start : Int, end : Int, confidence : Int, preview : String, message : String) -> Findingfn KeyPattern::new(id : String, key : String, severity : Severity, minimum_length? : Int, message? : String) -> KeyPatternpub(all) struct LiteralRule {
id : String
literal : String
case_sensitive : Bool
boundary : BoundaryMode
severity : Severity
message : String
} derive(Eq, Debug)fn LiteralRule::new(id : String, literal : String, severity? : Severity, case_sensitive? : Bool, boundary? : BoundaryMode, message? : String) -> LiteralRulepub(all) struct LiteralScanner {
rules : Array[LiteralRule]
include_preview : Bool
} derive(Eq, Debug)pub(all) struct LocatedFinding {
finding : Finding
start : SourceLocation
end : SourceLocation
} derive(Eq, Debug)fn PrefixPattern::new(id : String, prefix : String, minimum_tail : Int, maximum_tail : Int, severity : Severity, message : String) -> PrefixPatternpub(all) struct Rule {
detector_id : String
minimum_severity : Severity
action : RedactionAction
enabled : Bool
} derive(Eq, Debug)fn Rule::new(detector_id : String, action : RedactionAction, minimum_severity? : Severity, enabled? : Bool) -> Rulepub(all) struct StreamScanner {
scanner : Scanner
overlap : Int
pending : String
absolute_offset : Int
finished : Bool
}fn filter_new_findings(findings : Array[DocumentFinding], known_fingerprints : Array[String]) -> Array[DocumentFinding]Install
Download zipStreaming sensitive-data detection and redaction engine for MoonBit