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
+56
View File
@@ -90,6 +90,37 @@ The shared inputs are:
The commands in the matrix use `MXGATEWAY_API_KEY` through each CLI's
`api-key-env` flag. They must not embed bearer tokens or raw API keys.
### Credential contract for `authenticate-user`
Every CLI resolves the MXAccess verify-user credential the same way, so one
exported variable drives the same operator workflow in all five languages:
| Variable | Default | Purpose |
|----------|---------|---------|
| `MXGATEWAY_VERIFY_PASSWORD` | Empty | Verify-user credential read by `authenticate-user` when `--password` is omitted. |
- Flags are `--password` (Go: `-password`) for an explicit value and
`--password-env` (Go: `-password-env`) for the *name* of the environment
variable, defaulting to `MXGATEWAY_VERIFY_PASSWORD`.
- Resolution order is flag, then environment variable. Prefer the variable: the
flag puts the secret in shell history and the process table.
- A resolved credential that is **missing or empty** is a usage error. The CLI
fails fast before dialing rather than authenticating with an empty password,
and the error names only the flag and the variable — never the value. Nothing
echoes the credential to stdout, stderr, or logs.
This is CLI argument validation, not an MXAccess parity exception: the client
*libraries* still transmit whatever credential they are given. Only the operator
tools refuse to fabricate an empty one.
The .NET CLI accepted `--verify-user-password`, `--verify-user-password-env`, and
`MXGATEWAY_VERIFY_USER_PASSWORD` before this contract was unified. Those names
remain as deprecated aliases for one release; new scripts must use the canonical
names above. The full .NET resolution order is `--password`,
`--verify-user-password`, the variable named by `--password-env` (or the
deprecated `--verify-user-password-env`, default `MXGATEWAY_VERIFY_PASSWORD`),
then `MXGATEWAY_VERIFY_USER_PASSWORD`.
### TLS variant
The matrix runs over plaintext (`h2c`) by default. A TLS variant exists but stays
@@ -132,6 +163,31 @@ for quick local checks, but the full cross-language matrix uses explicit
operation commands because not every bundled smoke command streams events yet.
The explicit sequence remains the parity baseline for issue-level validation.
## Per-CLI Subcommand Coverage
The matrix sequence itself is available everywhere, but the later single-item
session commands were not added to every CLI at the same time. A runner that
reaches beyond the required sequence must branch on language, so the current
deltas are specified here rather than left to be discovered:
| Subcommand | .NET | Rust | Go | Python | Java |
|------------|------|------|----|--------|------|
| `unregister` | yes | yes | no | no | no |
| `add-buffered-item` | yes | no | no | no | no |
| `set-buffered-update-interval` | yes | no | no | no | no |
| `suspend` | yes | no | no | no | no |
| `activate` | yes | no | no | no | no |
| `write-secured` | yes | yes | yes | yes | yes |
| `write-secured2` | yes | no | no | no | no |
| `authenticate-user` | yes | yes | yes | yes | yes |
| `archestra-user-to-id` | yes | no | no | no | no |
Only .NET exposes all nine. Rust adds `unregister` and the credential pair; Go,
Python, and Java expose the credential pair only. Every gap is CLI surface only —
all five *libraries* implement all nine typed helpers, so a gap is a missing
operator command, never a missing capability. Levelling the CLIs is separate
feature work and is not tracked as a defect here.
## Validation
Run the matrix shape tests after changing the smoke matrix: