[Bugfix][Frontend] Keep credentials out of the Rust frontend launch log (#53738)
Signed-off-by: mhuzaifa3 <mhuzaifa3@outlook.com>
This commit is contained in:
@@ -401,3 +401,52 @@ def test_gather_actual_addresses_child_crash_before_report():
|
||||
manager.shutdown()
|
||||
time.sleep(0.2)
|
||||
sock.close()
|
||||
|
||||
|
||||
def test_rust_frontend_launch_log_redacts_credentials(monkeypatch, caplog):
|
||||
"""The Rust frontend command carries every non-default arg as JSON.
|
||||
Credentials must not reach the log line."""
|
||||
import subprocess as subprocess_mod
|
||||
|
||||
from vllm.entrypoints.launchers.cli_args import make_arg_parser
|
||||
from vllm.utils.argparse_utils import FlexibleArgumentParser
|
||||
from vllm.v1.utils import RustFrontendProcessManager
|
||||
|
||||
hf_token = "hf_TESTTOKEN123"
|
||||
api_key = "sk-TESTKEY456"
|
||||
args = make_arg_parser(FlexibleArgumentParser()).parse_args(
|
||||
["--model", "org/model", "--hf-token", hf_token, "--api-key", api_key]
|
||||
)
|
||||
|
||||
class _FakeProc:
|
||||
pid = 4321
|
||||
returncode = 0
|
||||
|
||||
def poll(self):
|
||||
return 0
|
||||
|
||||
def wait(self, timeout=None):
|
||||
return 0
|
||||
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
try:
|
||||
monkeypatch.setattr(subprocess_mod, "Popen", lambda *a, **kw: _FakeProc())
|
||||
with caplog.at_level("INFO", logger="vllm.v1.utils"):
|
||||
RustFrontendProcessManager(
|
||||
binary_path="/nonexistent/vllm-rs",
|
||||
sock=sock,
|
||||
args=args,
|
||||
input_address="ipc:///tmp/in",
|
||||
output_address="ipc:///tmp/out",
|
||||
engine_start_index=0,
|
||||
engine_count=1,
|
||||
data_parallel_size=1,
|
||||
)
|
||||
finally:
|
||||
sock.close()
|
||||
|
||||
message = caplog.text
|
||||
assert "Launching Rust frontend:" in message
|
||||
assert hf_token not in message
|
||||
assert api_key not in message
|
||||
assert '"hf_token": "***"' in message
|
||||
|
||||
@@ -8,8 +8,8 @@ import pytest
|
||||
from vllm.entrypoints.openai.engine.protocol import StreamOptions
|
||||
from vllm.entrypoints.serve.utils import api_utils
|
||||
from vllm.entrypoints.serve.utils.api_utils import (
|
||||
_redact_sensitive_args,
|
||||
get_max_tokens,
|
||||
redact_sensitive_args,
|
||||
should_include_usage,
|
||||
)
|
||||
|
||||
@@ -121,7 +121,7 @@ class TestRedactSensitiveArgs:
|
||||
|
||||
def test_redact_replaces_sensitive_values_only(self):
|
||||
args = {"api_key": self.API_KEY, "hf_token": "hf_secret", "other": "visible"}
|
||||
redacted = _redact_sensitive_args(args)
|
||||
redacted = redact_sensitive_args(args)
|
||||
assert redacted == {
|
||||
"api_key": "***",
|
||||
"hf_token": "***",
|
||||
@@ -136,7 +136,7 @@ class TestRedactSensitiveArgs:
|
||||
|
||||
def test_no_sensitive_fields_returns_original(self):
|
||||
args = {"model_tag": "org/model", "other": "visible"}
|
||||
assert _redact_sensitive_args(args) is args
|
||||
assert redact_sensitive_args(args) is args
|
||||
|
||||
def test_api_key_not_in_log(self, monkeypatch, caplog):
|
||||
non_default = {
|
||||
|
||||
@@ -271,7 +271,7 @@ def jsonify_non_default_args(
|
||||
_SENSITIVE_ARG_FIELDS = frozenset({"api_key", "hf_token"})
|
||||
|
||||
|
||||
def _redact_sensitive_args(args: dict[str, Any]) -> dict[str, Any]:
|
||||
def redact_sensitive_args(args: dict[str, Any]) -> dict[str, Any]:
|
||||
"""Return a copy of `args` with sensitive values redacted for logging."""
|
||||
if not any(key in _SENSITIVE_ARG_FIELDS for key in args):
|
||||
return args
|
||||
@@ -283,7 +283,7 @@ def _redact_sensitive_args(args: dict[str, Any]) -> dict[str, Any]:
|
||||
|
||||
def log_non_default_args(args: Namespace | EngineArgs):
|
||||
non_default_args = get_non_default_args(args)
|
||||
logger.info("non-default args: %s", _redact_sensitive_args(non_default_args))
|
||||
logger.info("non-default args: %s", redact_sensitive_args(non_default_args))
|
||||
|
||||
|
||||
def should_include_usage(
|
||||
|
||||
+6
-1
@@ -389,7 +389,12 @@ class RustFrontendProcessManager:
|
||||
args_json = json.dumps(args_dict, sort_keys=True)
|
||||
cmd.extend(["--args-json", args_json])
|
||||
|
||||
logger.info("Launching Rust frontend: %s", " ".join(cmd))
|
||||
# The subprocess needs the real values, but the log must not carry
|
||||
# credentials such as api_key or hf_token.
|
||||
from vllm.entrypoints.serve.utils.api_utils import redact_sensitive_args
|
||||
|
||||
redacted_json = json.dumps(redact_sensitive_args(args_dict), sort_keys=True)
|
||||
logger.info("Launching Rust frontend: %s", " ".join(cmd[:-1] + [redacted_json]))
|
||||
self._proc = subprocess.Popen(cmd, pass_fds=(fd,))
|
||||
|
||||
# Create a process wrapper with a sentinel fd for monitoring
|
||||
|
||||
Reference in New Issue
Block a user