Skip to main content
← Back to list
01Issue
FeatureOpenSwamp CLIPublicTeam
AssigneesNone

Relationships

#4225 vault put --server: accept the value on stdin (keep secrets out of argv)

Opened by nckrtl · 10/31/2026

Problem

swamp vault put --server <url> refuses stdin. The value must be a positional argument or KEY=VALUE:

A value must be provided as an argument when using --server (no interactive prompt or stdin reading remotely)

Local vault put recommends stdin because argv shows up in ps, shell history and process accounting. With --server, the only option left is the one the docs call insecure. That forces automation (for example, a control plane that pushes execution copies of secrets to a remote serve) to put secret values on its command line.

Proposal

With --server, read the value from stdin when it isn't a TTY and no value argument is given, the same way local put does. The CLI reads stdin locally and sends the value over the existing authenticated server connection. Nothing reaches argv and no remote prompt opens. Keep the local trailing-newline convention, so multiline values such as PEM keys survive.

printf '%s' "$SECRET" | swamp vault put execution-inputs node-14-identity --server wss://swamp.example.com --force

Sketch (tested against v20261031.063736.0-sha.e459d219)

In src/cli/commands/vault_put.ts, replace the remote branch's argument-only parsing with:

/** Remote writes accept piped values without putting them in argv or opening a prompt. */
export async function resolveRemoteKeyValue(
  argument: string,
  valueArg: string | undefined,
  stdinTty: boolean,
  read: () => Promise<string | null>,
): Promise<{ key: string; value: string }> {
  if (valueArg !== undefined) return { key: argument, value: valueArg };
  const inline = parseKeyValue(argument);
  if (inline) return inline;
  const result = resolveKeyValue(argument, stdinTty ? null : await read());
  if ("error" in result) throw new UserError(result.error);
  return result;
}
// remote branch:
const { key, value } = await resolveRemoteKeyValue(keyOrKeyValue, valueArg, isStdinTty(), readStdin);

Update the help text to say: "With --server, pipe the value on stdin to keep it out of the process argument list. Interactive prompts are not available remotely." Tests cover the piped value, value-argument precedence, KEY=VALUE, a TTY with no value (error), and a multiline PEM value.

02Bog Flow
◉OPEN○TRIAGED○IN PROGRESS○SHIPPED

Open

10/31/2026, 12:51:36 PM

No activity in this phase yet.

03Sludge Pulse

Sign in to post a ripple.