[Rust Frontend] Add /server_info to Rust frontend#43942
Conversation
Signed-off-by: xunzhuo <xunzhuo@vllm-semantic-router.ai>
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Adds a new /server_info endpoint that returns a snapshot of server configuration and environment metadata for debugging/inspection.
Changes:
- Introduced
ServerInfoSnapshot+ServerInfoConfigFormatand wired them intoAppState. - Added
/server_infoAxum route withconfig_formatquery parameter (text default, json optional). - Added route tests validating default (text) and requested (json) config formats.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| rust/src/server/src/state.rs | Adds server info snapshot model, env collection helpers, and exposes /server_info response via AppState. |
| rust/src/server/src/routes/server_info.rs | Implements the /server_info handler and query param parsing. |
| rust/src/server/src/routes.rs | Registers the new /server_info route. |
| rust/src/server/src/lib.rs | Populates AppState with a config-derived ServerInfoSnapshot. |
| rust/src/server/src/routes/tests.rs | Adds endpoint tests for default and json config formats. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| .route("/metrics", get(metrics::scrape)) | ||
| .route("/load", get(load::load)) | ||
| .route("/version", get(version::version)) | ||
| .route("/server_info", get(server_info::server_info)) |
| fn collect_vllm_env() -> BTreeMap<String, String> { | ||
| std::env::vars() | ||
| .filter(|(key, _)| key.starts_with("VLLM_") && !key.contains("KEY")) | ||
| .collect() | ||
| } |
| let vllm_config_json = json!({ | ||
| "transport_mode": format!("{:?}", config.transport_mode), | ||
| "coordinator_mode": format!("{:?}", config.coordinator_mode), | ||
| "model": config.model.clone(), | ||
| "served_model_name": config.served_model_name.clone(), | ||
| "listener_mode": format!("{:?}", config.listener_mode), | ||
| "tool_call_parser": format!("{:?}", config.tool_call_parser), | ||
| "reasoning_parser": format!("{:?}", config.reasoning_parser), | ||
| "renderer": format!("{:?}", config.renderer), | ||
| "chat_template": config.chat_template.clone(), | ||
| "default_chat_template_kwargs": config.default_chat_template_kwargs.clone(), | ||
| "chat_template_content_format": format!("{:?}", config.chat_template_content_format), | ||
| "enable_log_requests": config.enable_log_requests, | ||
| "disable_log_stats": config.disable_log_stats, | ||
| "grpc_port": config.grpc_port, | ||
| "shutdown_timeout_secs": config.shutdown_timeout.as_secs_f64(), | ||
| "engine_count": config.engine_count(), | ||
| }); |
| Self { | ||
| vllm_config_text: format!("{config:#?}"), | ||
| vllm_config_json, | ||
| vllm_env: collect_vllm_env(), | ||
| system_env: collect_system_env(), | ||
| } |
| fn collect_vllm_env() -> BTreeMap<String, String> { | ||
| std::env::vars() | ||
| .filter(|(key, _)| key.starts_with("VLLM_") && !key.contains("KEY")) |
There was a problem hiding this comment.
🟡 Severity: MEDIUM
Unlike the Python equivalent which iterates over a curated whitelist of ~240 known attributes in the vllm.envs module, this function reads all OS environment variables matching VLLM_*. Any custom deployment-set env var (e.g. VLLM_AUTH_TOKEN, VLLM_DB_PASSWORD) that doesn't contain "KEY" in its name would be leaked through the unauthenticated /server_info endpoint.
Helpful? Add 👍 / 👎
💡 Fix Suggestion
Suggestion: The collect_vllm_env() function reads ALL OS environment variables matching VLLM_*, unlike the Python equivalent which only iterates over a curated whitelist of ~240 known attributes defined in vllm.envs. Any deployment-custom env var (e.g. VLLM_AUTH_TOKEN, VLLM_DB_PASSWORD) that doesn't contain "KEY" in its name would be leaked through the unauthenticated /server_info endpoint.
The ideal fix is to replicate the Python behavior by maintaining an explicit allowlist of known VLLM environment variable names (the ~240 variables defined in vllm/envs.py), and only exposing those. This is a larger change requiring an allowlist constant to be kept in sync with the Python vllm.envs module.
As an immediate improvement, enhance the denylist filter to exclude additional common sensitive patterns such as SECRET, TOKEN, PASSWORD, CREDENTIAL, and AUTH. This reduces the attack surface but is not as robust as the allowlist approach.
⚠️ Experimental Feature: This code suggestion is automatically generated. Please review carefully.
| fn collect_vllm_env() -> BTreeMap<String, String> { | |
| std::env::vars() | |
| .filter(|(key, _)| key.starts_with("VLLM_") && !key.contains("KEY")) | |
| fn collect_vllm_env() -> BTreeMap<String, String> { | |
| const SENSITIVE_PATTERNS: &[&str] = &[ | |
| "KEY", "SECRET", "TOKEN", "PASSWORD", "CREDENTIAL", "AUTH", | |
| ]; | |
| std::env::vars() | |
| .filter(|(key, _)| { | |
| key.starts_with("VLLM_") | |
| && !SENSITIVE_PATTERNS.iter().any(|pat| key.contains(pat)) | |
| }) | |
| .collect() | |
| } |
Signed-off-by: xunzhuo <xunzhuo@vllm-semantic-router.ai>
Signed-off-by: xunzhuo <xunzhuo@vllm-semantic-router.ai>
Signed-off-by: xunzhuo <xunzhuo@vllm-semantic-router.ai>
Signed-off-by: xunzhuo <xunzhuo@vllm-semantic-router.ai>
| } | ||
|
|
||
| fn collect_vllm_env() -> BTreeMap<String, String> { | ||
| std::env::vars().filter(|(key, _)| is_public_vllm_env_key(key)).collect() |
There was a problem hiding this comment.
⚪ Severity: LOW
Unlike the Python equivalent (which reads only known declared attrs from vllm.envs — an allowlist), this reads all process env vars prefixed with VLLM_ and applies a key-name denylist. Custom operator env vars whose names don't match the denylist patterns (e.g. VLLM_DB_URL=postgres://user:pass@host/db) would have their values exposed through the /server_info endpoint.
Helpful? Add 👍 / 👎
💡 Fix Suggestion
Suggestion: Switch from a denylist approach to an allowlist approach, matching the Python frontend's behavior. Instead of reading all process env vars prefixed with VLLM_ and filtering out sensitive patterns, define an explicit allowlist of known safe VLLM environment variable names (mirroring the attributes declared in vllm/envs.py). This way, only recognized configuration env vars are exposed, and arbitrary operator-set env vars like VLLM_DB_URL with credential-bearing values won't leak.
Concretely:
- Define a
const KNOWN_VLLM_ENV_KEYS: &[&str]containing the recognized public VLLM environment variable names (e.g.,VLLM_LOGGING_LEVEL,VLLM_USE_MODELSCOPE, etc.). - Change
collect_vllm_env()to only read those specific keys from the environment rather than iterating all env vars. - Keep the sensitive pattern check as a defense-in-depth secondary filter.
Alternatively, as a minimal improvement, also scan the env var values for common credential patterns (e.g., ://...@ URI patterns) before including them in the output.
| } | ||
|
|
||
| /// Capture the runtime configuration fields available to the Rust frontend. | ||
| pub(crate) fn from_config(config: &Config) -> Self { |
There was a problem hiding this comment.
What about also moving the construction-related logic into a separate module?
| } | ||
| } | ||
|
|
||
| fn transport_mode_config(transport_mode: &TransportMode) -> Value { |
There was a problem hiding this comment.
I think it would be better to derive Serialize to replace these manually implemented conversions.
Signed-off-by: xunzhuo <xunzhuo@vllm-semantic-router.ai>
Signed-off-by: xunzhuo <xunzhuo@vllm-semantic-router.ai>
|
This pull request has merge conflicts that must be resolved before it can be |
| } | ||
|
|
||
| fn collect_vllm_env() -> BTreeMap<String, String> { | ||
| std::env::vars().filter(|(key, _)| is_public_vllm_env_key(key)).collect() |
There was a problem hiding this comment.
⚪ Severity: LOW
Unlike the Python frontend, which reads from a curated envs module (allowlist), this reads all process VLLM_* env vars and applies a denylist. Env vars whose names don't contain KEY/SECRET/TOKEN/PASSWORD/CREDENTIAL/AUTH but whose values carry secrets (e.g., VLLM_PROXY=http://user:pass@host, connection-string style vars) will be served to any unauthenticated client with dev-mode access.
Helpful? Add 👍 / 👎
💡 Fix Suggestion
Suggestion: Switch from a denylist approach to an allowlist approach to match the Python frontend's behavior. The Python frontend reads only from explicitly defined variables in vllm/envs.py (via dir(envs)), which acts as a curated allowlist. The current Rust implementation reads all VLLM_* process env vars and only excludes names containing sensitive keywords, which can leak secrets embedded in values (e.g., VLLM_PROXY=http://user:pass@host).
To fix this, define a static allowlist of known safe VLLM_* env var names (mirroring the keys defined in vllm/envs.py), and only collect env vars whose names appear in that allowlist. For example:
const KNOWN_PUBLIC_VLLM_ENV_KEYS: &[&str] = &[
"VLLM_HOST_IP",
"VLLM_PORT",
"VLLM_USE_MODELSCOPE",
"VLLM_LOGGING_LEVEL",
"VLLM_CONFIGURE_LOGGING",
"VLLM_TARGET_DEVICE",
"VLLM_SERVER_DEV_MODE",
// ... add all non-sensitive VLLM_* keys from vllm/envs.py
];
fn collect_vllm_env() -> BTreeMap<String, String> {
std::env::vars()
.filter(|(key, _)| {
let upper = key.to_ascii_uppercase();
KNOWN_PUBLIC_VLLM_ENV_KEYS.contains(&upper.as_str())
})
.collect()
}Alternatively, at minimum, also filter values for patterns that may embed credentials (e.g., URLs containing @ after ://), though an allowlist is the more robust approach.
…sion-server-info Signed-off-by: xunzhuo <xunzhuo@vllm-semantic-router.ai> # Conflicts: # rust/src/server/src/lib.rs # rust/src/server/src/state.rs
|
This pull request has merge conflicts that must be resolved before it can be |
…sion-server-info Signed-off-by: xunzhuo <xunzhuo@vllm-semantic-router.ai> # Conflicts: # rust/src/server/src/routes/tests.rs
Signed-off-by: Bugen Zhao <i@bugenzhao.com>
|
Hi @Xunzhuo I've pushed a commit to simplify the implementation more by directly deriving |
Signed-off-by: xunzhuo <xunzhuo@vllm-semantic-router.ai> Signed-off-by: Bugen Zhao <i@bugenzhao.com> Co-authored-by: Bugen Zhao <i@bugenzhao.com> Signed-off-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
Signed-off-by: xunzhuo <xunzhuo@vllm-semantic-router.ai> Signed-off-by: Bugen Zhao <i@bugenzhao.com> Co-authored-by: Bugen Zhao <i@bugenzhao.com> Signed-off-by: JisoLya <523420504@qq.com>
Signed-off-by: xunzhuo <xunzhuo@vllm-semantic-router.ai> Signed-off-by: Bugen Zhao <i@bugenzhao.com> Co-authored-by: Bugen Zhao <i@bugenzhao.com>
Signed-off-by: xunzhuo <xunzhuo@vllm-semantic-router.ai> Signed-off-by: Bugen Zhao <i@bugenzhao.com> Co-authored-by: Bugen Zhao <i@bugenzhao.com> Signed-off-by: Waqar Ahmed <waqar.ahmed@amd.com>
Signed-off-by: xunzhuo <xunzhuo@vllm-semantic-router.ai> Signed-off-by: Bugen Zhao <i@bugenzhao.com> Co-authored-by: Bugen Zhao <i@bugenzhao.com>
Summary
Adds
/server_infoto the Rust HTTP frontend alongside the existing/versionroute.The endpoint follows the Python frontend's top-level response shape with
vllm_config,vllm_env, andsystem_env. It returns a text config snapshot by default and supports?config_format=jsonfor structured config fields.Tests
cargo fmt --all --check(fromrust/)git diff --checkcargo check -p vllm-server --tests(fromrust/)cargo test -p vllm-server version_returns_engine_vllm_version -- --nocapture(fromrust/)cargo test -p vllm-server server_info_endpoint -- --nocapture(fromrust/)