runner

package
v0.15.1 Latest Latest
Warning

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

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

Documentation

Overview

Package runner executes the child process with secrets in its environment: exec, stream stdio, propagate exit code. Plaintext exists only in the child's env for its lifetime; Masker additionally scrubs the values from captured output.

Index

Constants

View Source
const MinMaskLen = 6

MinMaskLen is the shortest value the masker will rewrite. Below it, values are too likely to collide with ordinary output ("true", "8080") and would shred it; such secrets pass through unmasked by design.

Variables

This section is empty.

Functions

func Run

func Run(argv []string, env []string, stdin io.Reader, stdout, stderr io.Writer) (int, error)

Run executes argv with the given environment, wiring stdin through (nil reads as empty, for callers whose own stdin belongs to a protocol) and streaming the child's output to stdout/stderr (pass os.Stdout/os.Stderr for a direct wire, or Maskers to scrub captured output; the caller flushes those after Run returns), forwarding termination signals to the child. It returns the child's exit code (128+signal if the child was killed by a signal); a child that never started is a *StartError.

Types

type Masker added in v0.6.0

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

Masker is a Writer that rewrites occurrences of injected secret values in a byte stream with placeholders before forwarding to dst. It exists for captured output: anything a child process prints can end up in an agent's context window, a CI log, or a shell pipeline, and a server that echoes its connection string on boot would otherwise hand the secret to whatever is reading. Masking is accident-proofing, not a boundary: code that already holds the secret can always move it some other way.

Matching is exact byte matching, streamed: a value split across two writes is still caught (the longest tail that could open a secret is held back until later bytes decide). Flush emits whatever is still held at end-of-stream; callers must call it after the child exits or trailing output is lost.

func NewMasker added in v0.6.0

func NewMasker(dst io.Writer, secrets []Secret) *Masker

NewMasker builds a masker over dst for the given secrets. Values shorter than MinMaskLen are skipped; duplicate values collapse into one pattern (named after the first env var alphabetically). With no usable patterns the masker degrades to a plain passthrough.

func (*Masker) Flush added in v0.6.0

func (m *Masker) Flush() error

Flush emits the held tail. No more bytes are coming, so a partial prefix can no longer complete, but a shorter secret inside the tail still can, so the tail is re-scanned for complete matches rather than emitted raw.

func (*Masker) Write added in v0.6.0

func (m *Masker) Write(p []byte) (int, error)

Write rewrites complete matches and holds back a tail that might still become one. It always reports len(p) consumed: held bytes are not an error, they are emitted by a later Write or by Flush.

type Secret added in v0.6.0

type Secret struct {
	Name  string
	Value string
}

Secret is one injected env var for masking purposes.

type StartError added in v0.11.0

type StartError struct{ Err error }

StartError reports that the child process never ran (the command was not found, not executable, or the spawn itself failed), as opposed to an error after a successful start. Callers map the distinction to exit codes.

func (*StartError) Error added in v0.11.0

func (e *StartError) Error() string

func (*StartError) Unwrap added in v0.11.0

func (e *StartError) Unwrap() error

Jump to

Keyboard shortcuts

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