Avoid persisting or logging API keys from run_server.py

Author: maxpetrusenkoagentCreated Jun 20, 2026Updated Aug 16, 2026

Problem

run_server.py currently copies the CLI --api_key value into the repository-local qwen_server/server_config.json, then logs the full server_config object at startup.

For local demos this is easy to miss. For a self-hosted BrowserQwen/Qwen-Agent deployment, it creates two operational footguns:

  1. A real DashScope/OpenAI-compatible API key passed with python run_server.py --api_key ... is persisted into a tracked JSON file under the source tree.
  2. The same config object is logged with logger.info(server_config), so the key can appear in stdout/process-manager logs.

This is not a request for a full production auth system. It is a small config/secret-handling hardening request so operators do not accidentally persist or log model-provider credentials while trying the documented server path.

Max / self-hosted use case

We run OSS agent tools behind local services and process managers. For that workflow, API keys should come from environment variables or untracked runtime config, and logs should redact secrets by default. A key ending up in git diff, shell history, or service logs is exactly the kind of small ops mistake that turns into a real incident.

Evidence inspected

Source:

  • run_server.py:37-43 defines --api_key as a CLI argument.
  • run_server.py:80-93 writes args.api_key into server_config.server.api_key and then writes the updated config back to qwen_server/server_config.json.
  • run_server.py:114-115 logs server_config after the write.
  • qwen_server/server_config.json:12-14 contains the persisted model_server, api_key, and llm fields.
  • qwen_server/assistant_server.py:42-47 and qwen_server/workstation_server.py:42-47 read the key from that JSON file.

Docs:

  • README.md:77-80 says DashScope use should set DASHSCOPE_API_KEY.
  • qwen-agent-docs/website/content/en/guide/get_started/configuration.md:17 says api_key can come from environment variables.
  • The published docs at https://qwenlm.github.io/Qwen-Agent/en/guide/get_started/configuration/ contain api_key, DASHSCOPE_API_KEY, and model_server guidance.

Related prior issue:

  • #520 reports run_server.py overwriting server_config.json and blanking an API key. The maintainer answer was to use export DASHSCOPE_API_KEY=xxx. That covers the blank-key confusion, but not the broader secret-handling behavior: CLI keys are still persisted to a tracked file and the whole config is still logged.

Expected behavior

Starting run_server.py with runtime credentials should not write secrets into tracked repo files or print them in logs.

Suggested implementation shape

Any of these would solve the operator pain:

  • Treat CLI args as in-memory runtime overrides instead of writing them back to qwen_server/server_config.json.
  • Prefer DASHSCOPE_API_KEY / OPENAI_API_KEY when --api_key is omitted, matching the docs.
  • If a config file is still needed, write user-specific runtime config to an untracked path such as workspace/server_config.local.json, not the checked-in template.
  • Redact secret-like fields before logging, e.g. log api_key='***' or omit it entirely.
  • Optionally add a short README/docs note: avoid passing real API keys on the command line; prefer environment variables.

Duplicate search performed

I searched the current upstream issue/PR backlog before opening this:

  • Fetched and scanned 200 open issues/PRs and 200 closed issues/PRs with gh.
  • Targeted searches: api_key server_config, DASHSCOPE_API_KEY server_config, run_server api_key, secret api_key, credential leak, logger.info server_config, plaintext api key, environment variable api_key.
  • Closest result: #520, related but closed and focused on the key becoming blank after run_server.py, not on avoiding secret persistence/logging.

Willingness to contribute

Happy to contribute a small PR if maintainers agree with the desired config behavior. I did not open a PR directly because the safest shape depends on whether you want run_server.py to keep mutating server_config.json for non-secret fields or move all runtime overrides out of the tracked template.