mirror of
https://github.com/meta-llama/llama-stack.git
synced 2025-12-03 09:53:45 +00:00
feat: add response sanitization and validation for MCP authorization
- Add Field(exclude=True) to authorization parameter to prevent token leakage in responses - Add model validator to reject Authorization header in headers dict - Users must use dedicated 'authorization' parameter instead of headers - Headers field is preserved for legitimate non-auth headers (tracing, routing, etc.) This implements the security requirement that authorization params are never returned in responses, unlike generic headers which may be echoed back.
This commit is contained in:
parent
267c895827
commit
1c27c1bef6
1 changed files with 20 additions and 3 deletions
|
|
@ -486,8 +486,8 @@ class OpenAIResponseInputToolMCP(BaseModel):
|
|||
:param type: Tool type identifier, always "mcp"
|
||||
:param server_label: Label to identify this MCP server
|
||||
:param server_url: URL endpoint of the MCP server
|
||||
:param headers: (Optional) HTTP headers to include when connecting to the server
|
||||
:param authorization: (Optional) OAuth access token for authenticating with the MCP server
|
||||
:param headers: (Optional) HTTP headers to include when connecting to the server (cannot contain Authorization)
|
||||
:param authorization: (Optional) OAuth access token for authenticating with the MCP server (excluded from responses)
|
||||
:param require_approval: Approval requirement for tool calls ("always", "never", or filter)
|
||||
:param allowed_tools: (Optional) Restriction on which tools can be used from this server
|
||||
"""
|
||||
|
|
@ -496,11 +496,28 @@ class OpenAIResponseInputToolMCP(BaseModel):
|
|||
server_label: str
|
||||
server_url: str
|
||||
headers: dict[str, Any] | None = None
|
||||
authorization: str | None = None
|
||||
# Authorization is excluded from serialization for security (never returned in responses)
|
||||
authorization: str | None = Field(default=None, exclude=True)
|
||||
|
||||
require_approval: Literal["always"] | Literal["never"] | ApprovalFilter = "never"
|
||||
allowed_tools: list[str] | AllowedToolsFilter | None = None
|
||||
|
||||
@model_validator(mode="after")
|
||||
def validate_no_auth_in_headers(self) -> "OpenAIResponseInputToolMCP":
|
||||
"""Ensure Authorization header is not passed via headers dict.
|
||||
|
||||
Authorization must be provided via the dedicated 'authorization' parameter
|
||||
to ensure proper security handling and prevent token leakage in responses.
|
||||
"""
|
||||
if self.headers:
|
||||
for key in self.headers.keys():
|
||||
if key.lower() == "authorization":
|
||||
raise ValueError(
|
||||
"Authorization header cannot be passed via 'headers'. "
|
||||
"Please use the 'authorization' parameter instead."
|
||||
)
|
||||
return self
|
||||
|
||||
|
||||
OpenAIResponseInputTool = Annotated[
|
||||
OpenAIResponseInputToolWebSearch
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue