Documentation
¶
Overview ¶
Package secret is the agent's in-memory credential primitive: a string-like value that holds an API key, token, or password but refuses to render itself. Every way a value normally escapes a process by accident - fmt verbs, JSON encoding, structured logs, an event written to the spine - returns a fixed redaction marker instead of the secret. The value leaves only through one explicit, grep-able call, Expose, used at the single point where it crosses the network boundary (an Authorization header). A credential leak by stray %v or a logged struct is therefore not a bug to be careful about, it is unrepresentable.
Text pairs with Source, the vault port: where a named credential reference resolves to a value. The default EnvSource reads the process environment so the agent runs with zero setup; an OS keychain, an age-encrypted file vault, a KMS, or a remote broker are swap-in adapters of the same port, the credential analog of state.Provider.
Honest scope: Go strings and the garbage collector make true zeroization best-effort. Text stores its bytes in a slice it owns and Destroy overwrites them, but copies the runtime made before Destroy (or that escaped via Expose) are beyond reach. The redaction guarantees are exact; the wiping is mitigation.
Index ¶
- Constants
- Variables
- type EnvSource
- type Source
- type Text
- func (t *Text) Destroy()
- func (t Text) Empty() bool
- func (t Text) Equal(other Text) bool
- func (t Text) Expose() string
- func (t Text) Format(f fmt.State, _ rune)
- func (t Text) GoString() string
- func (t Text) MarshalJSON() ([]byte, error)
- func (t Text) MarshalText() ([]byte, error)
- func (t Text) String() string
Constants ¶
const Redacted = "[REDACTED]"
Redacted is what every rendering of a Text shows in place of the value. It is deliberately not empty so a redacted secret is visible as such in output rather than looking like a missing field.
Variables ¶
var ErrNotFound = errors.New("secret: not found")
ErrNotFound is returned by a Source when a reference resolves to no secret. It is a distinct sentinel so a caller can tell "this credential is not configured" apart from a backend failure (a locked keychain, an unreachable vault).
Functions ¶
This section is empty.
Types ¶
type EnvSource ¶
type EnvSource struct{}
EnvSource resolves a reference to the process environment variable of the same name. It is the standalone default: it needs no configuration and works on every host. It is the only place the agent reads a credential from the environment, so the environment-as-secret-store assumption lives behind the port rather than scattered through the code.
type Source ¶
Source resolves a named reference to a secret value. It is the vault port: the agent asks for a credential by name and a backend supplies it, so the rest of the code never reads a raw environment variable or file. The default EnvSource keeps the agent zero-setup; an OS keychain, an age-encrypted file vault, a KMS, or a remote broker implement the same interface and swap in without touching the call sites. A Source must be safe for concurrent use and must return ErrNotFound (not an empty Text) for an absent reference.
func Chain ¶
Chain resolves a reference through an ordered list of Sources, returning the first value found. It is how a binary composes credential backends without the call site knowing the order: try the OS keychain, then a sealed file, then the environment, and stop at the first hit. A Source that returns ErrNotFound is skipped; any other error stops the chain and is returned, so a locked keychain or a corrupt vault surfaces rather than being silently masked by a later fallback. With no source holding the reference the chain returns ErrNotFound.
type Text ¶
type Text struct {
// contains filtered or unexported fields
}
Text holds a secret value and renders only as Redacted. The zero value is a valid empty secret. Text is a value type; copying it shares the underlying bytes, so Destroy on any copy clears them for all. It is safe to read concurrently; Destroy must not race a concurrent Expose.
func New ¶
New wraps a plaintext value in a Text. The input string's bytes are copied into storage the Text owns, so the caller may discard or overwrite its own copy.
func (*Text) Destroy ¶
func (t *Text) Destroy()
Destroy overwrites the secret's bytes with zeros and empties the receiver. Because copies of a Text share the same backing array, the wipe clears the value for every copy; the receiver is additionally reset so it reports Empty. It is best-effort (see the package doc): it cannot reach copies the runtime made during a GC move, or a string an earlier Expose returned.
func (Text) Equal ¶
Equal compares two secrets in constant time, so a comparison does not leak the value through timing. Two empty secrets are equal.
func (Text) Expose ¶
Expose returns the underlying plaintext. This is the one audited point where a secret becomes an ordinary string: call sites are intentionally easy to grep, and it should be used only where the value must cross a boundary the agent does not control (a request header). Do not log, format, or store the result.
func (Text) Format ¶
Format implements fmt.Formatter, which fmt consults before Stringer, GoStringer, or struct-field reflection for every verb. It writes Redacted unconditionally, so even a numeric verb (%d, %x) that would otherwise recurse into the byte slice and print its contents cannot reveal the value.
func (Text) GoString ¶
GoString implements fmt.GoStringer so the %#v verb (used by test helpers and struct dumps) also redacts.
func (Text) MarshalJSON ¶
MarshalJSON ensures a Text encodes as the redaction marker string, never the value, so a secret embedded in a struct cannot leak into JSON written to a log, an API response, or the event spine. Together with Format (which guards every fmt verb) this covers both the JSON and the text rendering paths a structured logger uses, so a Text logged through any handler shows only the marker.
func (Text) MarshalText ¶
MarshalText makes Text redact under any encoding that honors encoding.TextMarshaler, and lets a struct field of type Text serialize safely without a custom marshaler on the parent.