redact

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Nov 4, 2026 License: MIT Imports: 13 Imported by: 0

Documentation

Overview

Package redact removes secrets and e-mail addresses from text before it is shown, stored or sent to a model provider.

Everything goes through one goredact engine: the balanced built-in rule set plus a custom rule for e-mail addresses. Spans are masked in place with a format-preserving mask, so a masked value keeps its length and shape and the text around it stays valid. Newlines a mask would overwrite are put back, so line numbers in a patch survive a secret that spans lines.

Index

Constants

View Source
const EmailRuleID = "email-address"

EmailRuleID is the id the e-mail rule reports its findings under.

Variables

View Source
var Config = goredact.Config{
	Profile:       goredact.ProfileBalanced,
	MaskStrategy:  goredact.MaskFormatPreserving,
	RecordAligned: true,
	CustomRules:   []goredact.CustomRule{emailRule},
}

Config is how every byte baum redacts is redacted. RecordAligned keeps emitted output on newline boundaries so JSONL streams stay whole records.

Functions

func Identities

func Identities(text string) (string, bool)

Identities removes what must never be published in text sent to a code host: an email address, replaced with "[redacted]", and an @mention, which would notify someone on every edit. The mention keeps its text and loses only the "@", which reads naturally and cannot ping. It reports whether anything was changed.

func StripMentions

func StripMentions(text string) (string, int)

StripMentions turns @-mentions into plain names and returns how many it rewrote. It cannot tell a person from an annotation such as @Override, so apply it only to text known to be conversation, never to anything that may hold code.

Types

type Engine

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

Engine redacts with Config. It is immutable and safe for concurrent use.

func New

func New() (*Engine, error)

New compiles the redaction rules.

func (*Engine) FindContext

func (e *Engine) FindContext(ctx context.Context, text string) ([]Span, error)

FindContext returns, in input order, the spans RedactContext masks in text, one per finding: two secrets side by side are two spans however little lies between them. An e-mail address is reported in full, and may also be reported as the rule's window saw it. A value that is already masked, behind "Bearer", "--password=" or "user:", is no finding. It stops with ctx's error if ctx ends first.

func (*Engine) Profile

func (e *Engine) Profile() string

Profile describes the configuration for a document's generator notes.

func (*Engine) Redact

func (e *Engine) Redact(text string) (string, Summary, error)

Redact is RedactContext without cancellation.

func (*Engine) RedactContext

func (e *Engine) RedactContext(ctx context.Context, text string) (string, Summary, error)

RedactContext masks every secret and e-mail address in text, stopping with ctx's error if ctx ends first. The result has the same length and the same lines as the input: secrets are found over the whole text, so a key spanning several lines is caught, and the newlines the mask overwrote are put back. An e-mail address is masked in full however long it is.

func (*Engine) RedactJSON

func (e *Engine) RedactJSON(ctx context.Context, data []byte) ([]byte, Summary, error)

RedactJSON masks the secrets and e-mail addresses in data, a JSON text, and returns valid JSON of the same shape whenever data is valid.

It finds them two ways and masks the union:

  • over the encoded text as a whole, as RedactContext would, so a key and its value in separate strings ("password": "…") are caught together;
  • over every string value and object key as decoded, so a rule anchored at the start of a line still fires after an escaped newline or tab (a tool's output holding an env file). These are scanned together, one string per line, in one pass.

Only the characters of strings are ever masked: never a quote, an escape's backslash, or anything between strings. A string with something masked is written again as JSON, with no HTML escaping; any other is left byte for byte as it was. The Summary adds up the findings of both passes, so a secret may be counted twice.

func (*Engine) RedactReader

func (e *Engine) RedactReader(ctx context.Context, dst io.Writer, src io.Reader) (Summary, error)

RedactReader streams src to dst with every secret and e-mail address masked. The stream is otherwise byte for byte the input. An address with more than 254 bytes on one side of its @ is masked only within those 254 bytes; Redact and RedactContext mask it in full. A stream is not held, so its Summary also counts a value that was already masked, which Redact leaves out.

type Span

type Span struct {
	Start, End int
	Email      bool
}

Span is the byte offsets [Start, End) of one secret or address the engine masks; Email marks an address.

type Summary

type Summary struct {
	// Findings is the number of spans masked, ByRule the same split by rule
	// id; e-mail addresses are under EmailRuleID.
	Findings int
	ByRule   map[string]int
}

Summary counts what one redaction masked.

func (*Summary) Add

func (s *Summary) Add(other Summary)

Add folds other into s.

Jump to

Keyboard shortcuts

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