Documentation
¶
Overview ¶
Package incognigo provides bounded PII detection and transformation.
Detectors report only PII types and half-open byte spans. Policies select a transformer and an explicit overlap priority for each type. NewEngine validates and copies configuration before exposing an immutable engine that is safe for concurrent use. Engine.ProtectBytes is the canonical batch processing path; Engine.ProtectString is its byte-preserving string adapter. Engine.Inspect returns source-content-free classification and resolution metadata without transforming source bytes. Engine.ProtectStream applies the same semantics to an arbitrary-length io.Reader while bounding undecided source retention. Package sloghandler protects structured log records with the same configured engine before a downstream slog handler can format or transport them. ContainsPII provides an early-exit, metadata-free check for validation boundaries such as strict log-key inspection.
The module README documents the complete behavioral contracts, including ownership, malformed UTF-8, overlap resolution, and streaming failure semantics.
Example ¶
package main
import (
"context"
"fmt"
"github.com/Chadi00/incognigo"
"github.com/Chadi00/incognigo/detector"
"github.com/Chadi00/incognigo/transform"
)
func main() {
engine, err := incognigo.NewEngine(incognigo.Config{
Detectors: []incognigo.DetectorRegistration{
detector.Email(),
detector.IPAddress(),
detector.PaymentCard(),
detector.NANPPhone(),
},
Policies: []incognigo.Policy{
{
Type: incognigo.PIITypeEmailAddress,
Priority: 100,
Transformer: transform.Replace([]byte("[email]")),
Determinism: incognigo.Deterministic,
},
{
Type: incognigo.PIITypeIPAddress,
Priority: 90,
Transformer: transform.Replace([]byte("[ip]")),
Determinism: incognigo.Deterministic,
},
{
Type: incognigo.PIITypePaymentCardNumber,
Priority: 80,
Transformer: transform.Replace([]byte("[payment-card]")),
Determinism: incognigo.Deterministic,
},
{
Type: incognigo.PIITypePhoneNumber,
Priority: 70,
Transformer: transform.Replace([]byte("[nanp-phone]")),
Determinism: incognigo.Deterministic,
},
},
})
if err != nil {
panic(err)
}
protected, err := engine.ProtectString(
context.Background(),
"email owner@example.test from 192.0.2.1 "+
"with card 4111 1111 1111 1111 or call 212-555-0100",
)
if err != nil {
panic(err)
}
fmt.Println(protected)
}
Output: email [email] from [ip] with card [payment-card] or call [nanp-phone]
Index ¶
- Variables
- type ConfidenceBand
- type Config
- type Detector
- type DetectorBounds
- type DetectorID
- type DetectorRegistration
- type Determinism
- type Engine
- func (e *Engine) ContainsPII(ctx context.Context, input []byte) (bool, error)
- func (e *Engine) Inspect(ctx context.Context, input []byte) ([]Finding, error)
- func (e *Engine) Limits() ProcessingLimits
- func (e *Engine) ProtectBytes(ctx context.Context, input []byte) ([]byte, error)
- func (e *Engine) ProtectStream(ctx context.Context, destination io.Writer, source io.Reader) (int64, error)
- func (e *Engine) ProtectString(ctx context.Context, input string) (string, error)
- type Error
- func (e *Error) Counts() (actual int, maximum int, ok bool)
- func (e *Error) DetectorID() DetectorID
- func (e *Error) Error() string
- func (e *Error) Field() string
- func (e *Error) Is(target error) bool
- func (e *Error) Kind() ErrorKind
- func (e *Error) Limit() string
- func (e *Error) Operation() string
- func (e *Error) PIIType() PIIType
- func (e *Error) Unwrap() error
- type ErrorKind
- type EvidenceFlags
- type Finding
- type FindingOutcome
- type Match
- type MatchSink
- type PIIType
- type Policy
- type ProcessingLimits
- type SizedTransformer
- type Span
- type Transformer
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( // ErrInvalidConfiguration identifies rejected configuration, use of an // unconfigured engine, or a required operation argument that is nil. ErrInvalidConfiguration = errors.New("incognigo: invalid configuration") // ErrLimitExceeded identifies an operation that crossed a configured // processing limit. ErrLimitExceeded = errors.New("incognigo: processing limit exceeded") // ErrInvalidMatch identifies invalid metadata returned by a detector. ErrInvalidMatch = errors.New("incognigo: invalid detector match") // ErrDetection identifies a detector that could not finish safely. ErrDetection = errors.New("incognigo: detection failed") // ErrTransformation identifies a transformer that could not finish safely. ErrTransformation = errors.New("incognigo: transformation failed") // ErrStreamRead identifies a streaming source that could not be read // safely. ErrStreamRead = errors.New("incognigo: stream read failed") // ErrStreamWrite identifies a streaming destination that could not accept // protected output safely. ErrStreamWrite = errors.New("incognigo: stream write failed") )
Functions ¶
This section is empty.
Types ¶
type ConfidenceBand ¶ added in v0.2.0
type ConfidenceBand uint8
ConfidenceBand is an ordinal evidence classification, not a calibrated probability and not an overlap priority.
const ( // ConfidenceUnspecified uses the detector registration's default. ConfidenceUnspecified ConfidenceBand = iota ConfidenceWeak ConfidencePossible ConfidenceLikely ConfidenceStrong )
func (ConfidenceBand) Valid ¶ added in v0.2.0
func (confidence ConfidenceBand) Valid() bool
Valid reports whether confidence is an explicit recognized band.
type Config ¶
type Config struct {
// Detectors lists the detection extensions and their bounded metadata.
Detectors []DetectorRegistration
// Policies contains exactly one transformation policy per declared type.
Policies []Policy
// Limits bounds processing work; zero fields use documented defaults.
Limits ProcessingLimits
}
Config describes an engine before validation and compilation.
NewEngine copies the slices and metadata reachable through Config. Detector and transformer implementations are retained as interfaces and must satisfy their documented immutability and concurrency contracts.
type Detector ¶
Detector finds candidate PII matches in input and emits them to sink.
Detect may be called concurrently with independent inputs and sinks. It must treat input as read-only, must not retain input or sink after returning, and must honor cancellation through ctx. Apart from cancellation or failure, emitted matches must depend only on input; streaming may call Detect repeatedly with overlapping views. DetectorBounds must be sufficient for a view containing a possible match and its declared context to produce the same decision as the complete input.
Emitted matches must use byte offsets, be within input, fit MaxMatchBytes, and use a type declared by the detector's registration. Detect must return after Add returns false; Incognigo still inspects the latched sink failure if a detector ignores the return value.
Detector errors must not contain input, matched values, or data derived from them. Incognigo still converts detector failures into its own safe Error rather than returning an extension error directly.
type DetectorBounds ¶
type DetectorBounds struct {
// MaxMatchBytes is the maximum length of any span returned by the
// detector. It must be greater than zero.
MaxMatchBytes int
// LookbehindBytes is the maximum number of bytes before a possible match
// that can affect whether it is a match.
LookbehindBytes int
// LookaheadBytes is the maximum number of bytes after a possible match
// that can affect whether it is a match.
LookaheadBytes int
}
DetectorBounds declares the finite context a detector needs. Incognigo uses these values to retain enough bytes across streaming read boundaries.
type DetectorID ¶
type DetectorID string
DetectorID is stable, non-sensitive metadata used to identify a configured detector and to break otherwise identical match-ordering ties.
func (DetectorID) Valid ¶
func (id DetectorID) Valid() bool
Valid reports whether id is a valid detector identifier. Detector IDs use the same grammar as PIIType and contain at most 128 bytes.
type DetectorRegistration ¶
type DetectorRegistration struct {
// ID is unique, stable, and safe to include in diagnostics.
ID DetectorID
// Detector is the executable extension.
Detector Detector
// Types is the complete set of PII types Detector may return.
Types []PIIType
// Bounds declares Detector's finite byte-context requirements.
Bounds DetectorBounds
// AlgorithmVersion is stable audit metadata. Empty selects "v1".
AlgorithmVersion string
// Locale is optional stable region or locale metadata, such as "global" or
// "nanp". It uses the public identifier grammar.
Locale string
// DefaultConfidence applies when a Match leaves Confidence unspecified.
// Zero selects ConfidenceStrong for compatibility with deterministic
// pre-confidence detectors.
DefaultConfidence ConfidenceBand
// Evidence is fixed registration-level evidence metadata.
Evidence EvidenceFlags
}
DetectorRegistration binds a detector implementation to stable metadata.
ID must be unique within a Config. Types must be non-empty and contain no duplicates. Incognigo copies Types during construction.
type Determinism ¶
type Determinism uint8
Determinism states whether a transformer promises stable output.
const ( // Deterministic means identical PII type and value bytes produce identical // output bytes for the lifetime of the effective configuration. Deterministic Determinism = iota + 1 // NonDeterministic means repeated transformations may produce different // output bytes. NonDeterministic )
func (Determinism) Valid ¶
func (d Determinism) Valid() bool
Valid reports whether d is a recognized determinism declaration.
type Engine ¶
type Engine struct {
// contains filtered or unexported fields
}
Engine is an immutable, concurrency-safe compiled configuration.
The zero value is not a configured engine. Engines must be constructed with NewEngine.
func NewEngine ¶
NewEngine validates and copies config into an immutable engine.
At least one detector and one policy are required. Detector IDs and policy types must be unique. Every type declared by a detector must have one policy, and every policy must correspond to a declared detector type.
Example ¶
package main
import (
"bytes"
"context"
"fmt"
"github.com/Chadi00/incognigo"
)
type exampleDetector struct{}
func (exampleDetector) Detect(
_ context.Context,
input []byte,
sink incognigo.MatchSink,
) error {
const value = "EMP-0042"
start := bytes.Index(input, []byte(value))
if start < 0 {
return nil
}
sink.Add(incognigo.Match{
Type: "company.employee_id",
Span: incognigo.Span{
Start: start,
End: start + len(value),
},
})
return nil
}
type exampleTransformer struct{}
func (exampleTransformer) Transform(
context.Context,
incognigo.PIIType,
[]byte,
) ([]byte, error) {
return []byte("[protected]"), nil
}
func main() {
engine, err := newExampleEngine()
if err != nil {
panic(err)
}
fmt.Println(engine.Limits().MaxBatchInputBytes > 0)
}
func newExampleEngine() (*incognigo.Engine, error) {
return incognigo.NewEngine(incognigo.Config{
Detectors: []incognigo.DetectorRegistration{
{
ID: "company.employee_id",
Detector: exampleDetector{},
Types: []incognigo.PIIType{"company.employee_id"},
Bounds: incognigo.DetectorBounds{
MaxMatchBytes: 8,
},
},
},
Policies: []incognigo.Policy{
{
Type: "company.employee_id",
Priority: 100,
Transformer: exampleTransformer{},
Determinism: incognigo.Deterministic,
},
},
})
}
Output: true
func (*Engine) ContainsPII ¶ added in v0.3.0
ContainsPII reports whether any configured detector emits a valid candidate for input.
Unlike Inspect, ContainsPII stops at the first candidate and does not allocate result metadata or apply confidence thresholds and overlap resolution. It is intended for trust-boundary validation such as rejecting PII-looking log keys, where even a below-threshold candidate is unsafe.
ContainsPII never transforms, mutates, retains, or returns input. Detector and Incognigo failures return false with a source-safe error; callers must treat an error as an indeterminate protection failure rather than as "no PII".
Example ¶
package main
import (
"bytes"
"context"
"fmt"
"github.com/Chadi00/incognigo"
)
type exampleDetector struct{}
func (exampleDetector) Detect(
_ context.Context,
input []byte,
sink incognigo.MatchSink,
) error {
const value = "EMP-0042"
start := bytes.Index(input, []byte(value))
if start < 0 {
return nil
}
sink.Add(incognigo.Match{
Type: "company.employee_id",
Span: incognigo.Span{
Start: start,
End: start + len(value),
},
})
return nil
}
type exampleTransformer struct{}
func (exampleTransformer) Transform(
context.Context,
incognigo.PIIType,
[]byte,
) ([]byte, error) {
return []byte("[protected]"), nil
}
func main() {
engine, err := newExampleEngine()
if err != nil {
panic(err)
}
found, err := engine.ContainsPII(
context.Background(),
[]byte("dynamic-key-EMP-0042"),
)
if err != nil {
panic(err)
}
fmt.Println(found)
}
func newExampleEngine() (*incognigo.Engine, error) {
return incognigo.NewEngine(incognigo.Config{
Detectors: []incognigo.DetectorRegistration{
{
ID: "company.employee_id",
Detector: exampleDetector{},
Types: []incognigo.PIIType{"company.employee_id"},
Bounds: incognigo.DetectorBounds{
MaxMatchBytes: 8,
},
},
},
Policies: []incognigo.Policy{
{
Type: "company.employee_id",
Priority: 100,
Transformer: exampleTransformer{},
Determinism: incognigo.Deterministic,
},
},
})
}
Output: true
func (*Engine) Inspect ¶ added in v0.2.0
Inspect detects configured candidates without transforming input.
Candidate budgeting happens before confidence filtering. Eligible candidates then undergo the same deterministic overlap resolution as ProtectBytes. The returned slice contains engine-owned metadata copies and never aliases input. On failure Inspect returns nil.
Example ¶
package main
import (
"bytes"
"context"
"fmt"
"github.com/Chadi00/incognigo"
)
type exampleDetector struct{}
func (exampleDetector) Detect(
_ context.Context,
input []byte,
sink incognigo.MatchSink,
) error {
const value = "EMP-0042"
start := bytes.Index(input, []byte(value))
if start < 0 {
return nil
}
sink.Add(incognigo.Match{
Type: "company.employee_id",
Span: incognigo.Span{
Start: start,
End: start + len(value),
},
})
return nil
}
type exampleTransformer struct{}
func (exampleTransformer) Transform(
context.Context,
incognigo.PIIType,
[]byte,
) ([]byte, error) {
return []byte("[protected]"), nil
}
func main() {
engine, err := newExampleEngine()
if err != nil {
panic(err)
}
findings, err := engine.Inspect(
context.Background(),
[]byte("employee EMP-0042 signed in"),
)
if err != nil {
panic(err)
}
for _, finding := range findings {
fmt.Println(
finding.Type,
finding.Span.Start,
finding.Span.End,
finding.Outcome == incognigo.FindingSelected,
)
}
}
func newExampleEngine() (*incognigo.Engine, error) {
return incognigo.NewEngine(incognigo.Config{
Detectors: []incognigo.DetectorRegistration{
{
ID: "company.employee_id",
Detector: exampleDetector{},
Types: []incognigo.PIIType{"company.employee_id"},
Bounds: incognigo.DetectorBounds{
MaxMatchBytes: 8,
},
},
},
Policies: []incognigo.Policy{
{
Type: "company.employee_id",
Priority: 100,
Transformer: exampleTransformer{},
Determinism: incognigo.Deterministic,
},
},
})
}
Output: company.employee_id 9 17 true
func (*Engine) Limits ¶
func (e *Engine) Limits() ProcessingLimits
Limits returns the effective, fully populated processing limits.
func (*Engine) ProtectBytes ¶
ProtectBytes detects and transforms configured PII matches in input.
ProtectBytes never mutates or retains input. On success, the returned slice is owned by the caller and does not alias input, including when input is empty or no matches are found. Bytes outside resolved matches are preserved exactly. On failure, ProtectBytes returns a nil result rather than partial or unprotected output.
One Engine may be used concurrently. The configured detectors and transformers must satisfy their own concurrency contracts.
Example ¶
package main
import (
"bytes"
"context"
"fmt"
"github.com/Chadi00/incognigo"
)
type exampleDetector struct{}
func (exampleDetector) Detect(
_ context.Context,
input []byte,
sink incognigo.MatchSink,
) error {
const value = "EMP-0042"
start := bytes.Index(input, []byte(value))
if start < 0 {
return nil
}
sink.Add(incognigo.Match{
Type: "company.employee_id",
Span: incognigo.Span{
Start: start,
End: start + len(value),
},
})
return nil
}
type exampleTransformer struct{}
func (exampleTransformer) Transform(
context.Context,
incognigo.PIIType,
[]byte,
) ([]byte, error) {
return []byte("[protected]"), nil
}
func main() {
engine, err := newExampleEngine()
if err != nil {
panic(err)
}
protected, err := engine.ProtectBytes(
context.Background(),
[]byte("employee EMP-0042 signed in"),
)
if err != nil {
panic(err)
}
fmt.Println(string(protected))
}
func newExampleEngine() (*incognigo.Engine, error) {
return incognigo.NewEngine(incognigo.Config{
Detectors: []incognigo.DetectorRegistration{
{
ID: "company.employee_id",
Detector: exampleDetector{},
Types: []incognigo.PIIType{"company.employee_id"},
Bounds: incognigo.DetectorBounds{
MaxMatchBytes: 8,
},
},
},
Policies: []incognigo.Policy{
{
Type: "company.employee_id",
Priority: 100,
Transformer: exampleTransformer{},
Determinism: incognigo.Deterministic,
},
},
})
}
Output: employee [protected] signed in
func (*Engine) ProtectStream ¶
func (e *Engine) ProtectStream( ctx context.Context, destination io.Writer, source io.Reader, ) (int64, error)
ProtectStream reads source, protects configured PII, and writes the protected bytes to destination.
ProtectStream applies the same detector ordering, match validation, overlap resolution, and transformations as ProtectBytes. Total stream length and total output are not bounded by the batch input and output limits. Undecided source bytes are bounded by MaxStreamBufferBytes, and MaxBatchMatches bounds the candidates retained during each streaming decision.
The returned count includes only bytes successfully written to destination. A failure after an earlier write can therefore leave a protected prefix in destination. ProtectStream never follows that prefix with undecided or unprotected source bytes. Callers requiring all-or-nothing delivery must use a transactional destination or buffer the result before committing it.
Reader and writer failures are converted to source-data-safe Error values; errors returned by source or destination are not retained. One Engine may be used concurrently. The configured extensions and the supplied Reader and Writer must satisfy their own concurrency contracts.
Example ¶
package main
import (
"bytes"
"context"
"fmt"
"strings"
"github.com/Chadi00/incognigo"
)
type exampleDetector struct{}
func (exampleDetector) Detect(
_ context.Context,
input []byte,
sink incognigo.MatchSink,
) error {
const value = "EMP-0042"
start := bytes.Index(input, []byte(value))
if start < 0 {
return nil
}
sink.Add(incognigo.Match{
Type: "company.employee_id",
Span: incognigo.Span{
Start: start,
End: start + len(value),
},
})
return nil
}
type exampleTransformer struct{}
func (exampleTransformer) Transform(
context.Context,
incognigo.PIIType,
[]byte,
) ([]byte, error) {
return []byte("[protected]"), nil
}
func main() {
engine, err := newExampleEngine()
if err != nil {
panic(err)
}
var destination bytes.Buffer
written, err := engine.ProtectStream(
context.Background(),
&destination,
strings.NewReader("employee EMP-0042 signed in"),
)
if err != nil {
panic(err)
}
fmt.Println(destination.String())
fmt.Println(written)
}
func newExampleEngine() (*incognigo.Engine, error) {
return incognigo.NewEngine(incognigo.Config{
Detectors: []incognigo.DetectorRegistration{
{
ID: "company.employee_id",
Detector: exampleDetector{},
Types: []incognigo.PIIType{"company.employee_id"},
Bounds: incognigo.DetectorBounds{
MaxMatchBytes: 8,
},
},
},
Policies: []incognigo.Policy{
{
Type: "company.employee_id",
Priority: 100,
Transformer: exampleTransformer{},
Determinism: incognigo.Deterministic,
},
},
})
}
Output: employee [protected] signed in 30
func (*Engine) ProtectString ¶
ProtectString detects and transforms configured PII matches in input.
String processing preserves the exact bytes in input and delegates to the byte processing path. On failure, ProtectString returns an empty string and an error, never the original input as a fallback.
Example ¶
package main
import (
"bytes"
"context"
"fmt"
"github.com/Chadi00/incognigo"
)
type exampleDetector struct{}
func (exampleDetector) Detect(
_ context.Context,
input []byte,
sink incognigo.MatchSink,
) error {
const value = "EMP-0042"
start := bytes.Index(input, []byte(value))
if start < 0 {
return nil
}
sink.Add(incognigo.Match{
Type: "company.employee_id",
Span: incognigo.Span{
Start: start,
End: start + len(value),
},
})
return nil
}
type exampleTransformer struct{}
func (exampleTransformer) Transform(
context.Context,
incognigo.PIIType,
[]byte,
) ([]byte, error) {
return []byte("[protected]"), nil
}
func main() {
engine, err := newExampleEngine()
if err != nil {
panic(err)
}
protected, err := engine.ProtectString(
context.Background(),
"employee EMP-0042 signed in",
)
if err != nil {
panic(err)
}
fmt.Println(protected)
}
func newExampleEngine() (*incognigo.Engine, error) {
return incognigo.NewEngine(incognigo.Config{
Detectors: []incognigo.DetectorRegistration{
{
ID: "company.employee_id",
Detector: exampleDetector{},
Types: []incognigo.PIIType{"company.employee_id"},
Bounds: incognigo.DetectorBounds{
MaxMatchBytes: 8,
},
},
},
Policies: []incognigo.Policy{
{
Type: "company.employee_id",
Priority: 100,
Transformer: exampleTransformer{},
Determinism: incognigo.Deterministic,
},
},
})
}
Output: employee [protected] signed in
type Error ¶
type Error struct {
// contains filtered or unexported fields
}
Error contains only non-sensitive failure metadata.
Use errors.As to inspect an Error and errors.Is with one of the sentinel errors above to classify it. Error never retains an extension error because an arbitrary extension error may contain source data.
Example ¶
package main
import (
"bytes"
"context"
"errors"
"fmt"
"strings"
"github.com/Chadi00/incognigo"
)
type exampleDetector struct{}
func (exampleDetector) Detect(
_ context.Context,
input []byte,
sink incognigo.MatchSink,
) error {
const value = "EMP-0042"
start := bytes.Index(input, []byte(value))
if start < 0 {
return nil
}
sink.Add(incognigo.Match{
Type: "company.employee_id",
Span: incognigo.Span{
Start: start,
End: start + len(value),
},
})
return nil
}
type exampleTransformer struct{}
func (exampleTransformer) Transform(
context.Context,
incognigo.PIIType,
[]byte,
) ([]byte, error) {
return []byte("[protected]"), nil
}
func main() {
engine, err := newExampleEngine()
if err != nil {
panic(err)
}
_, err = engine.ProtectString(
context.Background(),
strings.Repeat("x", engine.Limits().MaxBatchInputBytes+1),
)
if err == nil {
panic("expected the configured input limit to be enforced")
}
var protectionErr *incognigo.Error
if errors.As(err, &protectionErr) {
actual, maximum, hasCounts := protectionErr.Counts()
fmt.Println(
protectionErr.Kind() == incognigo.ErrorKindLimitExceeded,
)
fmt.Println(protectionErr.Operation())
fmt.Println(protectionErr.Limit())
fmt.Println(actual > maximum, hasCounts)
}
}
func newExampleEngine() (*incognigo.Engine, error) {
return incognigo.NewEngine(incognigo.Config{
Detectors: []incognigo.DetectorRegistration{
{
ID: "company.employee_id",
Detector: exampleDetector{},
Types: []incognigo.PIIType{"company.employee_id"},
Bounds: incognigo.DetectorBounds{
MaxMatchBytes: 8,
},
},
},
Policies: []incognigo.Policy{
{
Type: "company.employee_id",
Priority: 100,
Transformer: exampleTransformer{},
Determinism: incognigo.Deterministic,
},
},
})
}
Output: true protect_string max_batch_input_bytes true true
func (*Error) Counts ¶
Counts returns the observed and configured limit values. ok is false when the failure is not a limit failure with meaningful counts.
func (*Error) DetectorID ¶
func (e *Error) DetectorID() DetectorID
DetectorID returns the non-sensitive detector identifier associated with a runtime failure, if any.
func (*Error) Field ¶
Field returns the configuration or operation field associated with a failure. It never includes the field's value.
func (*Error) Is ¶ added in v0.2.0
Is matches the fixed Incognigo category sentinel and, for canceled operations, context.Canceled or context.DeadlineExceeded. Arbitrary extension errors are never retained or exposed.
func (*Error) Operation ¶
Operation returns the library operation that failed. Callers should branch on Kind rather than parsing this diagnostic label.
type ErrorKind ¶
type ErrorKind uint8
ErrorKind classifies an Incognigo failure without exposing source data.
const ( // ErrorKindUnknown is the zero value and does not classify a failure. ErrorKindUnknown ErrorKind = iota // ErrorKindInvalidConfiguration classifies configuration and invalid // engine-use failures. ErrorKindInvalidConfiguration // ErrorKindLimitExceeded classifies processing-limit failures. ErrorKindLimitExceeded // ErrorKindInvalidMatch classifies invalid detector metadata. ErrorKindInvalidMatch // ErrorKindDetection classifies detector execution failures. ErrorKindDetection // ErrorKindTransformation classifies transformer execution failures. ErrorKindTransformation // ErrorKindStreamRead classifies streaming source failures. ErrorKindStreamRead // ErrorKindStreamWrite classifies streaming destination failures. ErrorKindStreamWrite )
type EvidenceFlags ¶ added in v0.2.0
type EvidenceFlags uint16
EvidenceFlags describes fixed, non-sensitive reasons for a classification. Flags never contain source-derived text, hashes, or excerpts.
const ( EvidenceShape EvidenceFlags = 1 << iota EvidenceBoundary EvidenceChecksum EvidenceScheme EvidenceContext EvidenceDictionary EvidenceModel )
func (EvidenceFlags) Valid ¶ added in v0.2.0
func (evidence EvidenceFlags) Valid() bool
Valid reports whether evidence contains only recognized flags.
type Finding ¶ added in v0.2.0
type Finding struct {
Type PIIType
Span Span
DetectorID DetectorID
AlgorithmVersion string
Locale string
Confidence ConfidenceBand
Evidence EvidenceFlags
MinimumConfidence ConfidenceBand
Outcome FindingOutcome
}
Finding is source-content-free inspection metadata tied to the exact input bytes supplied to Inspect.
It contains no copied match, context excerpt, source-derived hash, token, or arbitrary provider error. Finding metadata is still content-derived and must not automatically be treated as safe to log.
type FindingOutcome ¶ added in v0.2.0
type FindingOutcome uint8
FindingOutcome records the deterministic result of confidence filtering and overlap resolution.
const ( FindingOutcomeUnknown FindingOutcome = iota FindingSelected FindingBelowThreshold FindingOverlapRejected )
type Match ¶
type Match struct {
// Type selects the configured policy.
Type PIIType
// Span locates the value without retaining it.
Span Span
// Confidence optionally overrides the detector registration's default
// confidence for this match. Zero uses the registration default.
Confidence ConfidenceBand
// Evidence optionally augments the detector registration's fixed evidence
// flags. It must contain only recognized flags.
Evidence EvidenceFlags
}
Match is the non-sensitive metadata emitted by a Detector.
A Match deliberately contains no copy, excerpt, hash, or token derived from the matched value.
type MatchSink ¶ added in v0.2.0
MatchSink accepts candidate metadata from a Detector.
Add returns false once the operation's match budget is exhausted, a match is invalid, or Detect has returned. A detector must stop emitting promptly when Add returns false. Incognigo validates and copies the metadata before Add returns; a sink is borrowed for one Detect call and must not be retained, called concurrently, or used by another goroutine.
type PIIType ¶
type PIIType string
PIIType is a stable, non-sensitive identifier for a class of personally identifiable information. Custom identifiers must satisfy Valid.
A PIIType identifies policy; it does not imply that Incognigo has a built-in detector for that type.
const ( PIITypeEmailAddress PIIType = "email_address" PIITypeIPAddress PIIType = "ip_address" PIITypePaymentCardNumber PIIType = "payment_card_number" PIITypePhoneNumber PIIType = "phone_number" PIITypeIBAN PIIType = "iban" PIITypeMACAddress PIIType = "mac_address" PIITypeUSSSN PIIType = "us_ssn" PIITypeUSITIN PIIType = "us_itin" PIITypeUSABARouting PIIType = "us_aba_routing_number" PIITypeUSNPI PIIType = "us_npi" PIITypeGBNINO PIIType = "gb_nino" PIITypeGBNHSNumber PIIType = "gb_nhs_number" )
Initial PII type identifiers. Detector packages may add support for these identifiers independently.
type Policy ¶
type Policy struct {
// Type is the unique PII type governed by this policy.
Type PIIType
// Priority resolves overlaps; a larger value wins.
Priority int
// Transformer replaces values selected by this policy.
Transformer Transformer
// Determinism declares Transformer's output stability.
Determinism Determinism
// MinimumConfidence filters candidates before overlap resolution. Zero
// selects ConfidenceWeak, preserving eligibility for existing detectors.
MinimumConfidence ConfidenceBand
}
Policy assigns a transformation and overlap priority to one PII type.
Higher Priority values win overlap conflicts. Equal priorities are resolved by the stable rules documented in the module README. Transformer must remain safe for concurrent use and must not be mutated while an Engine uses it.
type ProcessingLimits ¶
type ProcessingLimits struct {
// MaxBatchInputBytes is the largest input accepted by one batch
// operation.
MaxBatchInputBytes int
// MaxBatchOutputBytes is the largest completed output from one batch
// operation.
MaxBatchOutputBytes int
// MaxBatchMatches is the largest number of detector candidates retained
// during one batch operation or one streaming decision.
MaxBatchMatches int
// MaxStreamBufferBytes is the largest number of undecided source bytes
// retained across streaming reads. It does not limit total stream length.
MaxStreamBufferBytes int
}
ProcessingLimits bounds memory and input-driven work.
A zero field selects that field's value from DefaultProcessingLimits. Negative fields are invalid. Batch byte limits apply to one batch call; the match limit also applies to one streaming decision. The stream buffer limit bounds undecided source bytes retained while processing a stream; it does not limit the total length of a stream or its output.
func DefaultProcessingLimits ¶
func DefaultProcessingLimits() ProcessingLimits
DefaultProcessingLimits returns the limits used for zero-valued fields: 8 MiB of batch input, 32 MiB of batch output, 10,000 candidates per batch or streaming decision, and 256 KiB of retained streaming source data.
type SizedTransformer ¶ added in v0.2.0
SizedTransformer is an optional conformance contract that lets the batch engine reject oversized output before Transform allocates a replacement.
TransformedSize must return the exact successful Transform output length for the supplied type and input byte length. It must not allocate in proportion to valueBytes. A negative size or an error fails closed. Implementations are immutable, concurrency-safe extensions subject to the same trust boundary as Transformer.
type Span ¶
type Span struct {
// Start is the inclusive byte offset.
Start int
// End is the exclusive byte offset.
End int
}
Span identifies a non-empty half-open byte range [Start, End).
Offsets always refer to the exact input byte sequence supplied to a detector. They are not rune indexes.
type Transformer ¶
type Transformer interface {
Transform(ctx context.Context, piiType PIIType, value []byte) ([]byte, error)
}
Transformer replaces one matched value.
Transform may be called concurrently. It must treat value as read-only and must not retain value after returning. Ownership of a successful result is transferred to Incognigo; the transformer must not later mutate or reuse its backing array. A nil result with a nil error is a valid empty replacement.
Transformer errors must not contain value or data derived from it. Incognigo converts transformer failures into its own safe Error and discards any result returned alongside an error.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
cmd
|
|
|
incognigo-benchguard
command
Command incognigo-benchguard fails when established hot benchmarks exceed reviewed time or allocation regression limits.
|
Command incognigo-benchguard fails when established hot benchmarks exceed reviewed time or allocation regression limits. |
|
incognigo-detector-coverage
command
Command incognigo-detector-coverage generates the auditable built-in detector conformance-fixture inventory.
|
Command incognigo-detector-coverage generates the auditable built-in detector conformance-fixture inventory. |
|
incognigo-evaluate
command
Command incognigo-evaluate scores built-in detectors against an external JSONL corpus without retaining or printing source text.
|
Command incognigo-evaluate scores built-in detectors against an external JSONL corpus without retaining or printing source text. |
|
Package detector provides Incognigo's curated, standard-library-only PII detectors.
|
Package detector provides Incognigo's curated, standard-library-only PII detectors. |
|
gb
Package gb provides opt-in Great Britain structured-identifier detectors.
|
Package gb provides opt-in Great Britain structured-identifier detectors. |
|
us
Package us provides opt-in United States structured-identifier detectors.
|
Package us provides opt-in United States structured-identifier detectors. |
|
examples
|
|
|
http
command
Command http demonstrates a small net/http service with fail-closed, trust-boundary-aware structured logging.
|
Command http demonstrates a small net/http service with fail-closed, trust-boundary-aware structured logging. |
|
internal
|
|
|
match
Package match contains deterministic validation, ordering, and overlap resolution for detector candidates.
|
Package match contains deterministic validation, ordering, and overlap resolution for detector candidates. |
|
stream
Package stream contains bounded source retention and closed-prefix mechanics used by the root package's streaming surface.
|
Package stream contains bounded source retention and closed-prefix mechanics used by the root package's streaming surface. |
|
Package sloghandler protects log/slog records with a configured Incognigo engine before passing them to another slog.Handler.
|
Package sloghandler protects log/slog records with a configured Incognigo engine before passing them to another slog.Handler. |
|
Package transform provides redaction, masking, and tokenization transformations that implement the contracts defined by the root incognigo package.
|
Package transform provides redaction, masking, and tokenization transformations that implement the contracts defined by the root incognigo package. |