Merge branch 'fix/cli-45-credential-envvar'
ci / java (push) Successful in 2m51s
ci / windows-x86 (push) Successful in 1m21s
ci / nightly-windev (push) Has been skipped
ci / portable (push) Successful in 9m41s

# Conflicts:
#	archreview/2026-07-12/remediation/00-tracking.md
This commit is contained in:
Joseph Doherty
2026-08-07 06:09:03 -04:00
26 changed files with 773 additions and 53 deletions
@@ -32,6 +32,11 @@ logger = logging.getLogger(__name__)
MAX_AGGREGATE_EVENTS = 10_000
#: Canonical CLI credential environment variable, shared by every official client
#: CLI (CLI-45) so one exported variable drives the same operator workflow in all
#: five languages.
DEFAULT_VERIFY_PASSWORD_ENV = "MXGATEWAY_VERIFY_PASSWORD"
_BATCH_EOR = "__MXGW_BATCH_EOR__"
@@ -328,7 +333,8 @@ def write_secured(**kwargs: Any) -> None:
)
@click.option(
"--password-env",
default=None,
default=DEFAULT_VERIFY_PASSWORD_ENV,
show_default=True,
help="Environment variable holding the user password.",
)
@click.option("--correlation-id", default="", help="Client correlation id.")
@@ -834,17 +840,23 @@ async def _authenticate_user(**kwargs: Any) -> dict[str, Any]:
def _resolve_password(kwargs: dict[str, Any]) -> str:
"""Resolve the authenticate-user password from --password or --password-env.
Prefers the explicit flag, then falls back to the named environment
variable. The resolved secret is never echoed; callers pass it into the
``secrets`` redaction list so it cannot leak through a surfaced error.
Prefers the explicit flag, then falls back to the environment variable named
by ``--password-env`` (default :data:`DEFAULT_VERIFY_PASSWORD_ENV`). A missing
*or empty* value from either source is a usage error (CLI-45): the CLI never
sends a fabricated empty credential to the wire. The error names the option
and the variable only — the resolved secret is never echoed, and callers pass
it into the ``secrets`` redaction list so it cannot leak through a surfaced
error either.
"""
env_name = kwargs.get("password_env") or DEFAULT_VERIFY_PASSWORD_ENV
password = kwargs.get("password")
if not password:
env_name = kwargs.get("password_env")
password = os.environ.get(env_name) if env_name else None
password = os.environ.get(env_name)
if not password:
raise click.UsageError("a password is required via --password or --password-env")
raise click.UsageError(
f"a password is required via --password or the {env_name} environment variable"
)
return password