///|
/// Detection categories intentionally stay small and auditable. This library
/// detects structured secrets and common identifiers; it is not an NLP system.
pub(all) enum SensitiveKind {
AccessToken
BearerToken
Jwt
CredentialAssignment
Email
Ipv4
PaymentCard
PrivateKey
UrlCredential
CustomSecret
ResidentId
MacAddress
Uuid
Ipv6
Phone
PublicKey
WalletAddress
WebhookUrl
} derive(Eq, @debug.Debug)
///|
pub extend SensitiveKind with Eq::{equal, not_equal}
///|
pub extend SensitiveKind with @debug.Debug::{to_repr}
///|
pub fn SensitiveKind::to_string(self : SensitiveKind) -> String {
match self {
AccessToken => "ACCESS_TOKEN"
BearerToken => "BEARER_TOKEN"
Jwt => "JWT"
CredentialAssignment => "CREDENTIAL"
Email => "EMAIL"
Ipv4 => "IPV4"
PaymentCard => "PAYMENT_CARD"
PrivateKey => "PRIVATE_KEY"
UrlCredential => "URL_CREDENTIAL"
CustomSecret => "CUSTOM_SECRET"
ResidentId => "RESIDENT_ID"
WebhookUrl => "WEBHOOK_URL"
WalletAddress => "WALLET_ADDRESS"
PublicKey => "PUBLIC_KEY"
Phone => "PHONE"
Ipv6 => "IPV6"
Uuid => "UUID"
MacAddress => "MAC_ADDRESS"
}
}
///|
pub(all) enum Confidence {
High
Medium
} derive(Eq, @debug.Debug)
///|
pub extend Confidence with Eq::{equal, not_equal}
///|
pub extend Confidence with @debug.Debug::{to_repr}
///|
pub fn Confidence::to_string(self : Confidence) -> String {
match self {
High => "HIGH"
Medium => "MEDIUM"
}
}
///|
/// Half-open UTF-16 offsets. A finding never stores or returns the matched
/// value, making reports safer to log than the original input.
pub(all) struct Finding {
kind : SensitiveKind
start : Int
end : Int
confidence : Confidence
} derive(Eq, @debug.Debug)
///|
pub extend Finding with Eq::{equal, not_equal}
///|
pub extend Finding with @debug.Debug::{to_repr}
///|
pub(all) enum RedactionStyle {
Marker
Typed
PreserveLast4
} derive(Eq, @debug.Debug)
///|
pub extend RedactionStyle with Eq::{equal, not_equal}
///|
pub extend RedactionStyle with @debug.Debug::{to_repr}
///|
/// A policy controls which detector families run. Known credentials are always
/// enabled because suppressing them creates surprising leak paths.
pub(all) struct ScanPolicy {
detect_email : Bool
detect_ipv4 : Bool
detect_payment_card : Bool
} derive(Eq, @debug.Debug)
///|
pub extend ScanPolicy with Eq::{equal, not_equal}
///|
pub extend ScanPolicy with @debug.Debug::{to_repr}
///|
pub fn ScanPolicy::secrets_only() -> ScanPolicy {
{ detect_email: false, detect_ipv4: false, detect_payment_card: false, }
}
///|
pub fn ScanPolicy::standard() -> ScanPolicy {
{ detect_email: true, detect_ipv4: true, detect_payment_card: true, }
}
///|
pub(all) struct RedactionResult {
text : String
findings : Array[Finding]
changed : Bool
} derive(Eq, @debug.Debug)
///|
pub extend RedactionResult with Eq::{equal, not_equal}
///|
pub extend RedactionResult with @debug.Debug::{to_repr}
///|
pub(all) struct BatchSummary {
lines : Int
mut changed_lines : Int
mut findings : Int
mut access_tokens : Int
mut bearer_tokens : Int
mut jwts : Int
mut credentials : Int
mut emails : Int
mut ipv4s : Int
mut payment_cards : Int
mut private_keys : Int
mut url_credentials : Int
mut custom_secrets : Int
mut resident_ids : Int
mut mac_addresses : Int
mut uuids : Int
mut ipv6s : Int
mut phones : Int
mut public_keys : Int
mut wallet_addresses : Int
mut webhook_urls : Int
} derive(Eq, @debug.Debug)
///|
pub extend BatchSummary with Eq::{equal, not_equal}
///|
pub extend BatchSummary with @debug.Debug::{to_repr}
///|
/// A caller-supplied exact value that should never leave the process. Rules
/// shorter than four UTF-16 code units are ignored to limit accidental broad
/// matches. The label is metadata only and never appears in output markers.
pub(all) struct CustomRule {
label : String
value : String
} derive(Eq, @debug.Debug)
///|
pub extend CustomRule with Eq::{equal, not_equal}
///|
pub extend CustomRule with @debug.Debug::{to_repr}
///|
/// Domain-neutral structured field adapter. `path` may be a JSON pointer,
/// dotted property path, form field name, or database column name.
pub(all) struct StructuredField {
path : String
value : String
} derive(Eq, @debug.Debug)
///|
pub extend StructuredField with Eq::{equal, not_equal}
///|
pub extend StructuredField with @debug.Debug::{to_repr}
///|
pub(all) struct StructuredFieldResult {
path : String
value : String
findings : Array[Finding]
changed : Bool
sensitive_path : Bool
} derive(Eq, @debug.Debug)
///|
pub extend StructuredFieldResult with Eq::{equal, not_equal}
///|
pub extend StructuredFieldResult with @debug.Debug::{to_repr}
///|
pub(all) struct StructuredResult {
fields : Array[StructuredFieldResult]
changed_fields : Int
findings : Int
} derive(Eq, @debug.Debug)
///|
pub extend StructuredResult with Eq::{equal, not_equal}
///|
pub extend StructuredResult with @debug.Debug::{to_repr}
///|
/// One kind-to-count pair; summaries are ordered by kind name so identical
/// inputs always produce identical reports.
pub(all) struct KindCount {
kind : SensitiveKind
mut count : Int
} derive(Eq, @debug.Debug)
///|
pub extend KindCount with Eq::{equal, not_equal}
///|
pub extend KindCount with @debug.Debug::{to_repr}
///|
pub(all) struct BatchResult {
lines : Array[String]
summary : BatchSummary
/// Zero-based indices of lines that changed, for callers that only need
/// to re-route or archive the affected records.
changed_indices : Array[Int]
} derive(Eq, @debug.Debug)
///|
pub extend BatchResult with Eq::{equal, not_equal}
///|
pub extend BatchResult with @debug.Debug::{to_repr}
///|
/// A finding located inside a JSON document, addressed by a JSON-pointer-like
/// path such as `/user/0/email`. Array positions appear as numeric segments.
/// The field name is metadata; the matched value itself is never stored.
pub(all) struct JsonFinding {
path : String
finding : Finding
} derive(Eq, @debug.Debug)
///|
pub extend JsonFinding with Eq::{equal, not_equal}
///|
pub extend JsonFinding with @debug.Debug::{to_repr}
///|
pub(all) struct JsonRedactionResult {
text : String
changed_fields : Int
findings : Array[JsonFinding]
/// False when the input was not valid JSON and the text fell back to plain
/// content scanning, which is the fail-closed path for malformed payloads.
parsed : Bool
} derive(Eq, @debug.Debug)
///|
pub extend JsonRedactionResult with Eq::{equal, not_equal}
///|
pub extend JsonRedactionResult with @debug.Debug::{to_repr}