Skip to content

fix(secrets): keep passwords out of process arguments, previews and errors - #55

Merged
grojof merged 1 commit into
mainfrom
fix/secrets-out-of-argv
Oct 8, 2026
Merged

grojof merged 1 commit into
mainfrom
fix/secrets-out-of-argv

Conversation

@grojof

@grojof grojof commented Oct 8, 2026

Copy link
Copy Markdown
Owner

Every database password went into the command text (PGPASSWORD=… psql, psql -c "CREATE ROLE … PASSWORD '…'"). A step runs as bash -lc "<command>", so the password sat in that process's arguments — visible to every local user via ps, another instance's Odoo user included — for the whole step (a long pg_dump/pg_restore). The plan preview printed it, with odoo.conf's admin_passwd/db_password in its heredoc, and a failed step's error printed the command again.

Changes

  • Command gains env (secrets, in the step's environment — readable only by root) and display (what the preview shows, secrets masked). pg_env() gives libpq its PGPASSWORD plus PGCONNECT_TIMEOUT=10 (a blackholed remote DB used to hang probes for minutes). SQL holding a password goes to psql on stdin (<<<"$OIM_SQL").
  • write_text_file_command: atomic (private temp file, chmod, rename) with the content in the environment; preview shows the file masked.
  • A failed step's error names the step, not its command.
  • All 15 PGPASSWORD=/password-SQL sites converted (system, planners, addons, common, health, purge, manage, backup_restore).
  • Smaller: addon deps checked by distribution name first, as Odoo does (python-stdnum was "MISSING"); health check reaches a Unix-socket DB (db_host = False); export OSError no longer crashes; server report's DB list no longer matches by prefix.

OpenSpec change: secrets-out-of-sight (execution-safety, addon-inventory).

Verification

  • pytest 194 passed; ruff, openspec clean; ShellCheck clean on the generated install/DB/update commands.
  • tools/verify_secrets.py (new) — 12/12: a password in Command.env never appears in ps while the step runs, while the old PGPASSWORD= form does (negative control); files written exactly, mode 640, no temp left, preview masked; a failure's error has no secret; the role SQL on stdin creates the role with its password in a throwaway PostgreSQL.
  • tools/verify_data_safety.py, tools/verify_ops_configs.py and tools/verify_neutralisation.py (real Odoo 18) still pass.

Assisted-by: Claude

…rrors

Every database password went into the command text (PGPASSWORD=... psql),
so it sat in the running step's arguments, which ps shows every local user,
including another instance's Odoo user; the plan preview and a failed
step's error printed it again, as they printed odoo.conf's passwords.

A step now carries its secrets in Command.env and what the preview shows in
Command.display, masked. libpq clients take PGPASSWORD (and a 10 s connect
timeout) from the environment, SQL with a password goes to psql on stdin,
files are written atomically with their content in the environment, and a
failure names the step.

Also: dependencies are checked by distribution name first, as Odoo does;
the health check reaches a socket database; a failed export no longer
crashes; the report's database list no longer matches by prefix.
tools/verify_secrets.py runs the steps and looks at ps.
@grojof
grojof merged commit ff4cbfb into main Oct 8, 2026
1 check passed
@grojof
grojof deleted the fix/secrets-out-of-argv branch October 8, 2026 11:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant