privacy

package
v0.0.0-...-e60528e Latest Latest
Warning

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

Go to latest
Published: Aug 30, 2026 License: Apache-2.0 Imports: 24 Imported by: 0

Documentation

Index

Constants

View Source
const DetectorVersion = "helm-privacy-v5"

DetectorVersion identifies the deterministic egress detector used by the shared privacy boundary. It is intentionally a version, not a description of any detected value.

Variables

View Source
var (
	// ErrDataEgressBlocked is the stable, value-free failure returned when a
	// value cannot be safely sent across a governed boundary.
	ErrDataEgressBlocked = errors.New("DATA_EGRESS_BLOCKED")

	// ErrDataEgressInvalid is kept distinct for callers that need to diagnose
	// malformed values locally. The MCP firewall maps both errors to the same
	// public data-egress denial.
	ErrDataEgressInvalid = errors.New("DATA_EGRESS_INVALID")
)

Functions

This section is empty.

Types

type DPConfig

type DPConfig struct {
	// Epsilon is the privacy budget. Lower values provide stronger privacy
	// guarantees but add more noise. Must be positive.
	Epsilon float64 `json:"epsilon"`

	// Delta is the failure probability bound. Must be in (0, 1).
	Delta float64 `json:"delta"`

	// Sensitivity is the maximum change any single record can cause in a query result.
	Sensitivity float64 `json:"sensitivity"`
}

DPConfig configures differential privacy parameters for compliance metrics.

type DPEngine

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

DPEngine applies differential privacy noise to compliance metrics. It uses the Laplace mechanism: noise is drawn from Laplace(0, sensitivity/epsilon) and added to the true value before release.

func NewDPEngine

func NewDPEngine(config DPConfig) *DPEngine

NewDPEngine creates a new differential privacy engine with the given configuration.

func (*DPEngine) AddNoise

func (e *DPEngine) AddNoise(metricName string, trueValue float64) *DPMetric

AddNoise adds calibrated Laplace noise to a metric value. The noise magnitude is sensitivity / epsilon, ensuring (epsilon, delta)-differential privacy.

func (*DPEngine) PrivateComplianceScore

func (e *DPEngine) PrivateComplianceScore(framework string, trueScore int) *DPMetric

PrivateComplianceScore returns a DP-protected compliance score. The trueScore is an integer (e.g., 0-100), and the result is a noisy float.

func (*DPEngine) WithClock

func (e *DPEngine) WithClock(clock func() time.Time) *DPEngine

WithClock overrides the clock for deterministic testing.

func (*DPEngine) WithRNG

func (e *DPEngine) WithRNG(rng func() float64) *DPEngine

WithRNG overrides the random source for deterministic testing. The function must return values uniformly distributed in (0, 1).

type DPMetric

type DPMetric struct {
	// MetricName identifies the metric.
	MetricName string `json:"metric_name"`

	// TrueValue is the actual value. Excluded from JSON serialization.
	TrueValue float64 `json:"-"`

	// NoisyValue is the differentially private value safe for release.
	NoisyValue float64 `json:"noisy_value"`

	// Epsilon records the privacy budget used for this metric.
	Epsilon float64 `json:"epsilon"`

	// Timestamp records when the metric was generated.
	Timestamp time.Time `json:"timestamp"`
}

DPMetric is a differentially private metric value. The TrueValue field is never serialized to prevent accidental leakage.

type PIIClassification

type PIIClassification string

PIIClassification defines the sensitivity level of data.

const (
	PIINone      PIIClassification = "NONE"
	PIISensitive PIIClassification = "SENSITIVE" // Name, Email, IP, etc.
	PIICritical  PIIClassification = "CRITICAL"  // SSN, Credit Card, Health Data
)

type PrivacyManager

type PrivacyManager interface {
	// Scrub removes PII from the given text based on the classification.
	Scrub(ctx context.Context, text string, level PIIClassification) string
	// Validate verifies if the data complies with privacy policies.
	Validate(ctx context.Context, data map[string]interface{}) (bool, []string)
}

PrivacyManager defines the interface for privacy controls.

type PrivateEvalRequest

type PrivateEvalRequest struct {
	// RequestID uniquely identifies this evaluation request.
	RequestID string `json:"request_id"`

	// PolicyHash identifies which policy to evaluate (public metadata).
	PolicyHash string `json:"policy_hash"`

	// InputShares are the secret-shared fragments of the governed data.
	InputShares []SecretShare `json:"input_shares"`

	// PartyIDs lists all participating parties.
	PartyIDs []string `json:"party_ids"`

	// Threshold is the quorum size needed for reconstruction.
	Threshold int `json:"threshold"`

	// Timestamp records when the request was created.
	Timestamp time.Time `json:"timestamp"`
}

PrivateEvalRequest is a policy evaluation request with secret-shared inputs. The governance engine receives only shares; no single party sees the full input.

type PrivateEvalResult

type PrivateEvalResult struct {
	// RequestID links this result to the originating request.
	RequestID string `json:"request_id"`

	// Verdict is the governance decision: ALLOW or DENY.
	Verdict string `json:"verdict"`

	// ProofHash is a SHA-256 proof that the evaluation was performed correctly
	// on the reconstructed input, without revealing the input itself.
	ProofHash string `json:"proof_hash"`

	// Parties lists the party IDs that contributed shares.
	Parties []string `json:"parties"`

	// Timestamp records when the evaluation completed.
	Timestamp time.Time `json:"timestamp"`

	// ContentHash is the SHA-256 of the canonical result body.
	ContentHash string `json:"content_hash"`
}

PrivateEvalResult is the output of a private policy evaluation. The verdict is revealed, but the governed input remains hidden.

type PrivateEvaluator

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

PrivateEvaluator performs policy evaluation on secret-shared data. The evaluator reconstructs the input only transiently, evaluates the policy, then zeros the reconstructed data from memory.

func NewPrivateEvaluator

func NewPrivateEvaluator(threshold, totalParties int) (*PrivateEvaluator, error)

NewPrivateEvaluator creates a new private evaluator. threshold and totalParties configure the underlying secret sharing scheme.

func (*PrivateEvaluator) EvaluatePrivately

func (e *PrivateEvaluator) EvaluatePrivately(req PrivateEvalRequest, policyEvalFn func(input []byte) (string, error)) (*PrivateEvalResult, error)

EvaluatePrivately performs a governance decision on secret-shared input.

The evaluator never persists the full input. The reconstruction is transient: the input is recovered from shares, the policy function is evaluated, and the reconstructed bytes are zeroed from memory before returning.

The returned result contains the verdict (ALLOW/DENY) and a proof hash that binds the policy, input, and verdict together for auditability.

func (*PrivateEvaluator) WithClock

func (e *PrivateEvaluator) WithClock(clock func() time.Time) *PrivateEvaluator

WithClock overrides the clock for deterministic testing.

type SecretShare

type SecretShare struct {
	// ShareID uniquely identifies this share within a split operation.
	ShareID string `json:"share_id"`

	// PartyID identifies the party holding this share.
	PartyID string `json:"party_id"`

	// Value is the share payload (one byte per secret byte).
	Value []byte `json:"value"`

	// Index is the evaluation point (1-based, never zero).
	Index int `json:"index"`

	// Threshold is the minimum number of shares needed to reconstruct.
	Threshold int `json:"threshold"`

	// Total is the total number of shares created.
	Total int `json:"total"`
}

SecretShare represents one party's share of a secret value. Shares are created by Shamir's Secret Sharing over GF(256) and can only be combined when at least Threshold shares are present.

type SecretSharer

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

SecretSharer splits and reconstructs secrets using Shamir's Secret Sharing over GF(256). Each byte of the secret is independently split using a random polynomial of degree (threshold - 1).

func NewSecretSharer

func NewSecretSharer(threshold, total int) (*SecretSharer, error)

NewSecretSharer creates a new secret sharer. threshold is the minimum number of shares needed to reconstruct (must be >= 2). total is the number of shares to generate (must be >= threshold).

func (*SecretSharer) Reconstruct

func (s *SecretSharer) Reconstruct(shares []SecretShare) ([]byte, error)

Reconstruct recovers the secret from at least threshold shares using Lagrange interpolation over GF(256).

func (*SecretSharer) Split

func (s *SecretSharer) Split(secret []byte) ([]SecretShare, error)

Split divides a secret into shares using Shamir's Secret Sharing. Each byte of the secret is independently shared using a random polynomial of degree (threshold - 1) evaluated at points 1..total over GF(256).

type StandardPrivacyManager

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

StandardPrivacyManager implements the PrivacyManager interface.

func NewPrivacyManager

func NewPrivacyManager() *StandardPrivacyManager

NewPrivacyManager returns a new instance of StandardPrivacyManager.

func (*StandardPrivacyManager) Protect

func (pm *StandardPrivacyManager) Protect(ctx context.Context, value any) (protected any, findings []string, err error)

Protect returns a deep, non-mutating copy of value suitable for crossing a governed MCP boundary. Ordinary email and phone values are replaced with stable markers. Restricted credentials and financial/identity values fail closed. findings contains only unique detector labels and never a value.

Protect deliberately accepts any so callers cannot accidentally protect only the top-level map while allowing a nested map, slice, or JSON raw value to cross the boundary unchanged.

func (*StandardPrivacyManager) Scrub

Scrub redacts PII from the text.

func (*StandardPrivacyManager) Validate

func (pm *StandardPrivacyManager) Validate(ctx context.Context, data map[string]interface{}) (bool, []string)

Validate checks for privacy compliance. For now, it just ensures no critical PII keys exist in the top level of the map.

Jump to

Keyboard shortcuts

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