mask

package
v1.5.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 17, 2026 License: Apache-2.0 Imports: 13 Imported by: 0

Documentation

Overview

Package mask provides pure, deterministic redaction for query results.

The package operates only on model.QueryResult values. It does not access databases, stores, files, networks, or pipeline state.

Index

Constants

View Source
const BlockPlaceholder = "***"

BlockPlaceholder is the fixed output for every non-empty value processed by the block algorithm.

View Source
const RedactedFallback = "[REDACTED]"

RedactedFallback is the fail-closed output for a non-empty value whose representation cannot be recognized by its configured masking rule.

Variables

View Source
var (
	ErrIdentityMeetUndefined = errors.New("identity-only mask meet is undefined")
	ErrIdentityCapability    = errors.New("mask identity capability is unavailable")
	ErrIdentityPlanInvalid   = errors.New("mask identity plan is invalid")
)
View Source
var (
	// ErrUnsupportedType indicates a sensitive type not supported by masking.
	ErrUnsupportedType = errors.New("unsupported sensitive type")
	// ErrUnsupportedAlgorithm indicates an algorithm not available for execution.
	ErrUnsupportedAlgorithm = errors.New("unsupported masking algorithm")
	// ErrInvalidRangeParams indicates invalid or mismatched range parameters.
	ErrInvalidRangeParams = errors.New("invalid range parameters")
	// ErrDuplicateMaskColumn indicates duplicate normalized rule columns.
	ErrDuplicateMaskColumn = errors.New("duplicate mask column")
	// ErrHashKeyRequired indicates that hash redaction has no configured key.
	ErrHashKeyRequired = errors.New("hash redaction key is required")
	// ErrHashKeyTooShort indicates that the hash key is shorter than 32 bytes.
	ErrHashKeyTooShort = errors.New("hash redaction key must be at least 32 bytes")
)
View Source
var ErrInvalidFingerprint = errors.New("invalid redaction fingerprint")
View Source
var ErrVersionedActiveNotEnabled = errors.New("versioned active hasher is not enabled in this build")

Functions

func KeyCommitment

func KeyCommitment(keyMaterial []byte) string

KeyCommitment returns the non-secret, stable commitment stored in the key registry. It never retains or mutates keyMaterial.

func NormalizeColumnName

func NormalizeColumnName(name string) string

NormalizeColumnName returns the canonical result-column key used by masking. It does not mutate the supplied string or any stored rule.

func ParseFingerprint

func ParseFingerprint(candidate string) (int, error)

ParseFingerprint validates the canonical fingerprint grammar and returns its key version. Legacy fingerprints use version 1; versioned fingerprints use a canonical decimal version in the range 2..9999. It does not verify the HMAC.

func SensitiveTypeOrder

func SensitiveTypeOrder(sensitiveType SensitiveType) int

SensitiveTypeOrder returns the shared deterministic sort key: phone, email, idcard, bankcard, ip, birthdate, generic, number, then date. Unknown types sort after them.

func ValidateRule

func ValidateRule(rule Rule) error

ValidateRule validates the column, sensitive type, and algorithm combination. Hash key availability is intentionally a NewRedactor construction concern.

func VerifyFingerprint

func VerifyFingerprint(version int, key []byte, value, candidate string) (bool, error)

Types

type ActiveHasher

type ActiveHasher interface {
	Version() int
	Fingerprint(value string) string
}

type Algorithm

type Algorithm string

Algorithm identifies the redaction algorithm applied to a value.

const (
	AlgoMask Algorithm = "mask"
	AlgoHash Algorithm = "hash"
	// AlgoRange buckets numeric values or truncates date values.
	AlgoRange Algorithm = "range"
	// AlgoBlock replaces every non-empty value with BlockPlaceholder.
	AlgoBlock Algorithm = "block"
)

func (Algorithm) String

func (algorithm Algorithm) String() string

type ColumnSource

type ColumnSource struct {
	Column string
	Source model.ObjectRef
}

ColumnSource identifies a result column's physical source column and its uniquely resolved physical relation. Source.Table is empty when unresolved.

type Identity

type Identity struct {
	AlgorithmID         string
	SemanticVersion     string
	KeyID               string
	KeyVersion          int
	CanonicalParameters string
	InputType           string
	OutputType          string
}

Identity is the exact equality key for the S4 meet operation.

type IdentityOnlyRedactor

type IdentityOnlyRedactor interface {
	Redactor
	BuildIdentityPlan([]IdentityRequest) ([]IdentityPlan, error)
	ApplyIdentityPlan(model.QueryResult, []IdentityPlan) (model.QueryResult, RedactReport, error)
}

type IdentityPlan

type IdentityPlan struct {
	OutputIndex int
	Identity    Identity
	// contains filtered or unexported fields
}

IdentityPlan is produced by a redactor and can only be executed by that same redactor. The concrete transform stays private so an outer layer cannot replace a proven identity with a different rule.

type IdentityRequest

type IdentityRequest struct {
	OutputIndex int
	ResultName  string
	Sources     []PhysicalColumn
}

type Option

type Option func(*redactorOptions)

Option configures a Redactor without changing the frozen rule set.

func WithHashKey

func WithHashKey(key []byte) Option

WithHashKey supplies the dedicated HMAC key used by hash rules. The key is copied immediately so later caller mutations cannot affect the option.

func WithRedactionPlan

func WithRedactionPlan(plan RedactionPlan) Option

type PhysicalColumn

type PhysicalColumn struct {
	Schema    string
	Table     string
	Column    string
	InputType string
}

PhysicalColumn contains only catalog identity. It cannot carry a cell value and therefore keeps mask selection independent of sensitive data.

type ProjectionLineageAwareRedactor

type ProjectionLineageAwareRedactor interface {
	Redactor
	ApplyWithProjectionLineages(result model.QueryResult, aligned [][]model.LineageArm) (model.QueryResult, RedactReport)
}

ProjectionLineageAwareRedactor applies rules using projection lineage that has already been aligned to result positions. Each outer entry corresponds to one result column and contains all set-operation arms for that position.

type RangeGranularity

type RangeGranularity string

RangeGranularity controls date truncation for range rules.

const (
	RangeYear    RangeGranularity = "year"
	RangeQuarter RangeGranularity = "quarter"
	RangeMonth   RangeGranularity = "month"
)

type RangeParams

type RangeParams struct {
	BucketWidth  *int64
	BucketOffset *int64
	Granularity  *RangeGranularity
}

RangeParams configures numeric bucketing or date truncation. Pointer fields distinguish omitted values from explicitly supplied zero values.

type RedactReport

type RedactReport struct {
	// TouchedColumns includes columns whose values are all empty/null sentinels.
	TouchedColumns map[int]SensitiveType
	// MaskedCells is the number of non-empty cells successfully processed or
	// replaced fail-closed.
	MaskedCells       int
	HashFallbackCount int `json:"hash_fallback_count,omitempty"`
	// HashKeyVersion is present only when at least one non-empty cell was
	// successfully fingerprinted with the assembled active key.
	HashKeyVersion *int `json:"-"`
	// UnresolvedScopedColumns records scoped-rule columns that were protected
	// by the fixed block fallback because their physical source was unresolved.
	// A column is included only when at least one non-empty cell was replaced.
	UnresolvedScopedColumns map[int]SensitiveType `json:"unresolved_scoped_columns,omitempty"`
}

RedactReport records redaction activity for a result.

type RedactionPlan

type RedactionPlan struct {
	// contains filtered or unexported fields
}

func BuildRedactionPlan

func BuildRedactionPlan(activeVersion int, keys map[int][]byte) (RedactionPlan, error)

type Redactor

type Redactor interface {
	Apply(result model.QueryResult) (model.QueryResult, RedactReport)
}

Redactor applies configured masking rules to a query result.

func NewRedactor

func NewRedactor(rules []Rule, opts ...Option) (Redactor, error)

NewRedactor validates and freezes the supplied rules for deterministic use.

type RelationSourceAwareRedactor

type RelationSourceAwareRedactor interface {
	Redactor
	ApplyWithColumnSources(result model.QueryResult, sources []ColumnSource, possibleRelations []model.ObjectRef) (model.QueryResult, RedactReport)
}

RelationSourceAwareRedactor applies rules using both physical column sources and all physical relations that may contribute to the statement.

type Rule

type Rule struct {
	Schema        string
	Table         string
	Column        string
	SensitiveType SensitiveType
	Algorithm     Algorithm
	Range         *RangeParams
}

Rule configures redaction for one result-set column.

type SensitiveType

type SensitiveType string

SensitiveType identifies the kind of sensitive value in a result column.

const (
	TypePhone SensitiveType = "phone"
	TypeEmail SensitiveType = "email"
	// TypeIDCard masks recognized 15-digit and 18-digit identity-card text.
	TypeIDCard SensitiveType = "idcard"
	// TypeBankCard masks recognized 13-to-19-digit payment-card text.
	TypeBankCard SensitiveType = "bankcard"
	// TypeIP masks recognized IPv4, IPv6, inet, and CIDR text.
	TypeIP SensitiveType = "ip"
	// TypeBirthDate masks recognized calendar dates and supported timestamps.
	TypeBirthDate SensitiveType = "birthdate"
	// TypeGeneric identifies a general sensitive value supported by whole-value
	// hash and block algorithms.
	TypeGeneric SensitiveType = "generic"
	TypeNumber  SensitiveType = "number"
	TypeDate    SensitiveType = "date"
)

type SourceAwareRedactor

type SourceAwareRedactor interface {
	Redactor
	ApplyWithSourceColumns(result model.QueryResult, sources []string) (model.QueryResult, RedactReport)
}

SourceAwareRedactor optionally matches positional top-level direct source columns after the final result-column name has failed to match.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL