Hi, I noticed two related proxy-key handling issues while reviewing the startup and setup paths.
In the current main branch (b3fecbf), PROXY_API_KEY protects both OpenAI-compatible and Anthropic-compatible endpoints, but the setup tool and reset flow can set it to a fixed public value.
The endpoint checks depend directly on PROXY_API_KEY in src/proxy_app/main.py:
# lines 666-672
async def verify_api_key(auth: str = Depends(api_key_header)):
if not PROXY_API_KEY:
return auth
if not auth or auth != f"Bearer {PROXY_API_KEY}":
raise HTTPException(status_code=401, detail="Invalid or missing API Key")
return auth
# lines 680-694
async def verify_anthropic_api_key(...):
if x_api_key and x_api_key == PROXY_API_KEY:
return x_api_key
if auth and auth == f"Bearer {PROXY_API_KEY}":
return auth
raise HTTPException(status_code=401, detail="Invalid or missing API Key")
However, first-time setup writes a hard-coded default in src/rotator_library/credential_tool.py:
# lines 1095-1111
if get_key(str(_get_env_file()), "PROXY_API_KEY") is None:
default_key = "VerysecretKey"
set_key(str(_get_env_file()), "PROXY_API_KEY", default_key)
The launcher reset flow also resets to the same fixed value in src/proxy_app/launcher_tui.py:
# lines 728-785
default_api_key = "VerysecretKey"
...
LauncherConfig.update_proxy_api_key(default_api_key)
...
self.console.print(f" Proxy API Key: {default_api_key}")
The current startup banner also prints the full proxy key in src/proxy_app/main.py:
# lines 87-97
proxy_api_key = os.getenv("PROXY_API_KEY")
if proxy_api_key:
key_display = f"✓ {proxy_api_key}"
...
print(f"Proxy API Key: {key_display}")
The same header is printed again after clearing the screen:
# lines 248-252
print(f"Starting proxy on {args.host}:{args.port}")
print(f"Proxy API Key: {key_display}")
And the launcher status screen prints the full value in src/proxy_app/launcher_tui.py:
# lines 454-457
proxy_key = os.getenv("PROXY_API_KEY")
if proxy_key:
self.console.print(f" Proxy API Key: {proxy_key}")
Minimal reproduction:
- Run first-time setup without an existing
PROXY_API_KEY, or use the launcher reset-to-defaults flow.
- Observe that
.env receives PROXY_API_KEY=VerysecretKey.
- Start the proxy and observe that the full proxy key is printed in startup output.
- Any client can authenticate with
Authorization: Bearer VerysecretKey unless the user manually changes it.
Why this matters:
- A fixed default key means fresh installs or reset installs can share the same bearer credential.
- If the proxy is bound beyond localhost, deployed behind a tunnel/reverse proxy, or hosted on a platform, anyone who knows the default can call the relay.
- The full key in startup output/UI can leak through Docker logs, Render logs, terminal recordings, screenshots, or support bundles.
- This is especially sensitive for an LLM relay because the proxy key gates access to all configured provider credentials behind the service.
Suggested fix:
- Generate a random first-boot/default key, for example with
secrets.token_urlsafe(32).
- Do not reset to a hard-coded shared key.
- Display only a masked value such as
sk-...abcd, or show "Set" without revealing the secret.
- Optionally print the full generated key only once during setup, with an explicit warning that it will not be shown again.
- Consider masking both startup and launcher status output consistently.
Thanks for maintaining the project.
Hi, I noticed two related proxy-key handling issues while reviewing the startup and setup paths.
In the current
mainbranch (b3fecbf),PROXY_API_KEYprotects both OpenAI-compatible and Anthropic-compatible endpoints, but the setup tool and reset flow can set it to a fixed public value.The endpoint checks depend directly on
PROXY_API_KEYinsrc/proxy_app/main.py:However, first-time setup writes a hard-coded default in
src/rotator_library/credential_tool.py:The launcher reset flow also resets to the same fixed value in
src/proxy_app/launcher_tui.py:The current startup banner also prints the full proxy key in
src/proxy_app/main.py:The same header is printed again after clearing the screen:
And the launcher status screen prints the full value in
src/proxy_app/launcher_tui.py:Minimal reproduction:
PROXY_API_KEY, or use the launcher reset-to-defaults flow..envreceivesPROXY_API_KEY=VerysecretKey.Authorization: Bearer VerysecretKeyunless the user manually changes it.Why this matters:
Suggested fix:
secrets.token_urlsafe(32).sk-...abcd, or show "Set" without revealing the secret.Thanks for maintaining the project.