redact

package
v0.1.0-rc.2 Latest Latest
Warning

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

Go to latest
Published: Jul 5, 2026 License: MIT Imports: 8 Imported by: 0

Documentation

Overview

Package redact provides value-level secret scrubbing for logs, errors, event payloads, and subprocess output.

It complements the key-name-based attribute redaction in internal/logging: that layer hides secrets attached under suspicious slog attribute KEYS, while this layer catches secret VALUES regardless of the field, string, or stream they appear in. The two are defense-in-depth — neither is sufficient alone.

The Secret capability type renders as the redaction placeholder through every common formatting and serialization path (fmt %v/%s/%#v, encoding/json, encoding/text, and slog), exposing the plaintext only through the single audited Reveal boundary.

Index

Constants

View Source
const Placeholder = "[REDACTED]"

Placeholder is the text substituted for any redacted value.

Variables

This section is empty.

Functions

func Scrub

func Scrub(s string) string

Scrub applies only the built-in token-shape patterns. Use it when no instance-specific secret values are known.

func StripURLUserinfo

func StripURLUserinfo(s string) string

StripURLUserinfo removes credentials from a URL while keeping it valid and usable. For http/https the whole userinfo is dropped (it can only be a credential). For ssh/git the username is the SSH login name (typically "git"), not a secret, so it is preserved and only any password is dropped. Non-URL input and URLs without userinfo are returned unchanged.

func URL

func URL(s string) string

URL strips userinfo (user:password@ or token@) from a URL-like string while preserving the rest. Non-URL input is returned unchanged.

Types

type Redactor

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

Redactor scrubs a set of known secret VALUES (registered via AddValue) in addition to the built-in token-shape patterns. It is safe for concurrent use.

func NewRedactor

func NewRedactor() *Redactor

NewRedactor returns an empty Redactor.

func (*Redactor) AddValue

func (r *Redactor) AddValue(values ...string)

AddValue registers a concrete secret value to scrub. Empty and very short values are ignored to avoid mangling unrelated text.

func (*Redactor) Scrub

func (r *Redactor) Scrub(s string) string

Scrub removes every registered secret value and built-in token shape from s.

type Secret

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

Secret wraps a sensitive string so it cannot be accidentally logged, printed, or serialized in cleartext. Every standard rendering path returns Placeholder; the plaintext is reachable only via Reveal.

func New

func New(v string) Secret

New wraps v in a Secret.

func (Secret) GoString

func (s Secret) GoString() string

GoString implements fmt.GoStringer so %#v also redacts.

func (Secret) IsZero

func (s Secret) IsZero() bool

IsZero reports whether the Secret holds an empty value.

func (Secret) LogValue

func (s Secret) LogValue() slog.Value

LogValue implements slog.LogValuer so structured logs redact even when the Secret is passed under a benign attribute key.

func (Secret) MarshalJSON

func (s Secret) MarshalJSON() ([]byte, error)

MarshalJSON implements json.Marshaler.

func (Secret) MarshalText

func (s Secret) MarshalText() ([]byte, error)

MarshalText implements encoding.TextMarshaler.

func (Secret) Reveal

func (s Secret) Reveal() string

Reveal returns the underlying plaintext. This is the single audited boundary through which secret material leaves the type; keep call sites few and obvious.

func (Secret) String

func (s Secret) String() string

String implements fmt.Stringer.

type Writer

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

Writer is a line-buffering io.Writer that scrubs secrets from each complete line before forwarding it to the destination. It is used to sanitize captured subprocess output (e.g. persisted agent logs) so credentials echoed by a tool never land on disk in cleartext. Writes are serialized so a single Writer is safe to share between an stdout and stderr copier. Call Close to flush any trailing partial line.

SECU-04: PEM private key blocks span multiple lines. When a BEGIN PRIVATE KEY header is detected, subsequent body lines are suppressed until the matching END line, so base64 key material never reaches the destination.

func NewWriter

func NewWriter(dst io.Writer, r *Redactor) *Writer

NewWriter returns a scrubbing Writer forwarding to dst. If r is nil, only the built-in token-shape patterns are applied.

func (*Writer) Close

func (w *Writer) Close() error

Close flushes any buffered trailing partial line (scrubbed) to the destination. It does not close the destination.

func (*Writer) Write

func (w *Writer) Write(p []byte) (int, error)

Write accumulates input and flushes scrubbed complete lines to the destination. It always reports len(p) consumed. SECU-04: multi-line PEM private key blocks are suppressed across line boundaries so base64 body lines never reach the destination. P5-SEC-05: a newline-free run longer than maxLineBytes is scrubbed and flushed as a partial line so the buffer cannot grow without bound.

Jump to

Keyboard shortcuts

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