Files
qwen-code/scripts
Shaojin Wen 480b4d341a feat(managed-agent): read the Harness credentials from one file (#15063)
* feat(managed-agent): read the Harness credentials from one file

The Hosted Harness and the control plane share a bearer token and a
capability digest, which the reference distribution stored twice, in
harness.env and server.env, so every rotation or hand edit had to change
both files identically.

QWEN_MANAGED_AGENT_HARNESS_CREDENTIALS_FILE now names the Harness's own
environment file. The control plane reads QWEN_SERVER_TOKEN and
QWEN_HOSTED_HARNESS_CAPABILITY_DIGEST from it into its configuration,
never into its process environment, and refuses to start when the file
is combined with a direct token or digest, or lacks either key.
Preflight reports the file's permissions and points credential fixes at
it. The bootstrap, templates, systemd instructions and guide store the
credentials once.

* fix(managed-agent): refuse credential lines the Harness reads differently

The credentials parser accepted a subset of the environment-file grammar
and silently mis-read the rest. A continuation, an escape, an
unterminated quote, text after a closing quote or a `$` expansion gave
the control plane a different value than systemd or a shell gave the
Harness, while preflight passed. Such lines now fail startup, naming
the file and line but never the content.

The file is now read once and only while the Harness is enabled, and an
unreadable file reports its exception type in the validation row.
Preflight shares one secret-file permission policy between the config
and credentials rows. The credentials row also fails an unreadable file
and reports an unusable path instead of aborting, and the harness row
fails the shipped placeholder token.

Tests now pin the run order, values containing `=`, world-readable
files, the file-aware 401 fix and the shipped harness.env.example keys.
The systemd READMEs describe the warning as a warning.

* fix(managed-agent): accept only credential lines both readers take literally

Credential values in the Harness credentials file may now contain only
letters, digits and ._:/+=-, and whitespace around `=` or a carriage
return is refused: a shell runs `KEY = value` as a command and keeps a
trailing \r, so the control plane and the Harness could hold different
digests while every preflight row passed.

When startup refuses the file, the harness row now skips its probe
instead of sending whatever credentials are left bound, and the file is
applied atomically. run() delegates to checks(args) so a test can pin
the credentials row after the harness row.
2026-10-22 14:07:39 +00:00
..
2025-08-27 15:23:21 +08:00