mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-09 12:17:13 +00:00
`container exec -e NAME=VALUE` puts VALUE in the argv of the host-side
process, where ps shows it to every local account for as long as the call runs.
no_log cannot mask a process table. The credentials that travel this way are
live: platform_administrator and every secrets.credentials.* value rotate
between the two passes of a matrix-deploy round.
tests/lint/ansible/shell/container/test_exec_env_passes_no_value.py rejects the
form for credential-bearing values, recognised by either the variable's name or
a credential source in the expression behind it. The second signal is what
keeps it from being a name denylist, which would be no protection on its own: a
secret handed over as -e FOO={{ lookup('users','x').password }} is caught by its
source although its name says nothing. Literal values pass; ports, paths and
model names are not worth moving.
The 24 sites it found now pass the name alone and bind the value in the task's
environment. Value-shaping filters stay, because the container needs the shaped
form; the shell-quoting | quote goes, and that is safe: shlex.quote builds
armour the host shell consumes while parsing argv, so what docker receives is
byte-identical either way, checked with a password of @, space, apostrophe
and $.
Three sites needed more than the pattern. set_postgres_superuser_password.sh
took the password as $2, so it stood in the argv of the script and of three
container exec calls; it now reads POSTGRES_SUPERUSER_PASSWORD, and both callers
follow. svc-db-elasticsearch built an exec prefix with the password inside it for
five tasks, so the binding moved to the two include sites and is inherited.
web-app-taiga had its upsert as a semicolon-chained one-liner inside the command;
it is a file read on stdin now, which took the name and the e-mail out of the
argv too.
What this does not do, stated because the docstring first claimed otherwise:
with ansible.builtin.script the value reaches no argv, but with shell and
command ansible-core still prefixes NAME='value' onto the module wrapper's own
line, from Shell.env_prefix in build_module_command. The window shrinks from the
whole container call, re-executed on every pass of an until: loop, to the
module's runtime. It does not vanish.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>