Skip to main content

Module argv_secrets

Module argv_secrets 

Source
Expand description

@secret:<path> substitution wrapper for child-process argv per ADR-020 §5.

ADR-020 §5 second bullet:

A wrapper rewrites @secret:<path> occurrences in argv before exec. Because argv is visible to other processes through ps, the wrapper prefers passing the secret through stdin or a file descriptor when the target tool supports it (for example, gh auth login --with-token, git credential fill). Direct argv substitution is the fallback for tools that accept secrets only in argv, and is documented as such.

rewrite_argv is the planning function: it takes the raw argv plus a SecretResolver, decides for each known tool whether to redirect through stdin, and returns a RewritePlan that captures:

  • the final argv (with aliases removed when they go through stdin, or with plaintext substituted when they go through argv),
  • an optional stdin_payload (SecretString) the caller writes to the child’s stdin,
  • a per-substitution audit trail (Substitution) so callers can log which paths were resolved through which strategy,
  • an argv_visible flag so the caller can warn when at least one secret will land in ps output.

apply_plan_to_command hands the plan to a tokio::process::Command — sets stdio, then the caller .spawn()s and writes the payload to the child’s stdin.

§Known-tool detection

The first version recognises two FD-friendly invocation patterns:

  • gh auth login --with-token <alias>gh reads the token from stdin when --with-token is present.
  • git credential fill|approve|reject — the git credential protocol is stdin-only.

Adding more patterns (vault login -method=token, aws ssm put-parameter --value, …) is one entry per case in the Known enum + a small predicate. Until they’re added, the wrapper falls back to plaintext-in-argv with a structured warning surface.

§What this module does not do

  • Spawn the child. The caller decides how (tokio::spawn, blocking, supervised), and only this module knows the stdio shape.
  • Resolve aliases against a router. The SecretResolver trait is the boundary; the storage-layer impl that walks the router/credential chain lands separately.

Structs§

RewritePlan
Outcome of rewrite_argv.
Substitution
Per-substitution audit entry. Surfaced through RewritePlan::substitutions so callers can log routing decisions without reaching into the secret values.

Enums§

ArgvRewriteError
Failure modes for rewrite_argv.
SubstitutionStrategy
How the wrapper passed a secret to the child.

Functions§

apply_plan_to_command
Wire a RewritePlan into a tokio::process::Command.
rewrite_argv
Plan a substitution for the given child invocation.