Harden tool endpoint origin validation and source fingerprinting
All checks were successful
Deploy Gateway / deploy (push) Successful in 2m45s
All checks were successful
Deploy Gateway / deploy (push) Successful in 2m45s
This commit is contained in:
@@ -31,7 +31,7 @@ MCP는 Agent Builder가 `tools/call`에 명시한 단일 Tool을 실행한다. T
|
||||
7. `tools/list`는 `ToolRegistryService`의 in-memory snapshot에서 실행 metadata를 얻는다. 요청 경로는 Redis를 호출하지 않으므로 Redis 장애·지연이 응답에 영향을 주지 않으며, snapshot이 비어 있는 기동 직후에만 Tool catalog provider를 한 번 조회한다. 이후 `ToolsListHandler`가 MCP SDK의 `Tool`과 `ListToolsResult`로 변환한다. local 기본 구성은 Tool Service 매니페스트를 먼저 조회하고, 최초 실패 시 bundle별 local manifest sample을 cold-start fallback으로 사용한다. 운영은 이 배포가 보는 Tool Service 매니페스트의 사용 가능한 성공본만 원천으로 사용한다.
|
||||
8. `tools/call`은 `ToolsCallHandler`가 표준 MCP의 `params.name`과 object인 `params.arguments`를 검증하고 추출한다.
|
||||
9. `ToolExecutionService`가 표준 Tool name으로 metadata를 확정하고 argument schema를 검증한다. `ToolRoutingService`는 snapshot에 저장된 정확한 Tool endpoint와 metadata timeout으로 HTTP 요청을 만든다. Agent Builder가 보낸 `arguments` 객체는 JSON raw body로 전달하며 MCP가 Tool을 대체 선택하지 않는다.
|
||||
10. `arguments`의 어떤 field도 outbound URL 선택에 사용하지 않는다. Portal registry는 Tool Server의 `serviceDomain`과 `manifestPath`만 제공하고, Tool별 실행 endpoint는 Tool Server manifest의 top-level `endpoint` 또는 `_meta.endpoint`에서 가져온다. manifest endpoint가 절대 HTTP(S) URL이면 Tool Server가 제공한 실행 주소 원천으로 허용하고, 상대 경로이면 Portal registry의 `serviceDomain` 뒤에 붙인다.
|
||||
10. `arguments`의 어떤 field도 outbound URL 선택에 사용하지 않는다. Portal registry는 Tool Server의 `serviceDomain`과 `manifestPath`만 제공하고, Tool별 실행 endpoint는 Tool Server manifest의 top-level `endpoint` 또는 `_meta.endpoint`에서 가져온다. 상대 endpoint는 Portal registry의 `serviceDomain` 뒤에 붙이며, 절대 HTTP(S) endpoint도 `serviceDomain`과 scheme·host·유효 port가 같은 origin일 때만 허용한다. 이 경계를 벗어난 endpoint는 bundle 갱신 실패로 격리해 API Key와 사용자 헤더가 Portal이 승인하지 않은 서버로 전달되지 않게 한다.
|
||||
11. `HttpToolClient`가 JDK 공유 HTTP client의 connection pool을 사용해 correlation 헤더와 함께 POST를 실행한다. `X-Caller-IP`와 `X-Caller-Host`는 기동 시 Downward API의 `POD_IP`·`POD_NAME`을 우선 사용하고, 값이 없을 때만 로컬 host를 한 번 조회해 프로세스 수명 동안 재사용한다. Portal Registry와 Tool manifest 조회도 별도의 공유 JDK HTTP client를 사용한다. arguments는 JSON body로 전달하며 Tool read timeout은 metadata timeout과 요청 전체 deadline의 남은 시간 이하로 제한한다. Authorization 전달은 설정으로 통제한다.
|
||||
12. Tool 응답은 요청 payload와 분리해 `response.data`만 사용한다. plain text는 그대로, JSON object/array는 compact JSON string으로 MCP SDK `CallToolResult`/`TextContent`의 `result.content[0].text`에 넣고 outer JSON serializer가 escaping을 처리한다. 호출 소요 시간(ms)은 `result.content[0]._meta.searchTime`으로 반환하고, 정상 결과에도 `isError: false`를 명시한다. Tool 실행·timeout·권한 오류는 JSON-RPC error가 아니라 `isError: true` result로 변환한다. JSON-RPC envelope/params/method 및 서버 구성 오류는 최상위 JSON-RPC `error`로 반환한다.
|
||||
13. local과 운영 모두 같은 `name` lookup, endpoint/timeout, inputSchema validation 경로를 사용한다.
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
"content": [
|
||||
{
|
||||
"type": "text",
|
||||
"text": "customer.search@1.0.0: timed out"
|
||||
"text": "{\"reasonCode\":\"TOOL_TIMEOUT\",\"message\":\"Tool execution timed out.\"}"
|
||||
}
|
||||
],
|
||||
"isError": true
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
"id": 3,
|
||||
"error": {
|
||||
"code": -32602,
|
||||
"message": "Invalid params: 'query' is required"
|
||||
"message": "Invalid params",
|
||||
"data": {
|
||||
"reasonCode": "INVALID_PARAMS",
|
||||
"message": "Request parameters are invalid."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
|
||||
## tools/call 성공·오류 응답 기준
|
||||
|
||||
Agent Builder는 HTTP 상태만으로 성공 여부를 판단하지 않고 JSON-RPC body의 최상위 `result` 또는 `error`를 확인해야 한다. 일반적인 JSON-RPC 요청 오류는 HTTP `200 OK`와 함께 최상위 `error`로 반환될 수 있다. `-32602`의 `error.message`는 `Invalid params: <상세 원인>` 형식이며, 예를 들어 필수 `query`가 없으면 `Invalid params: 'query' is required`를 반환한다. 선택적인 `error.data`에는 `guid`와 상세 원인을 추가로 담을 수 있다. 단, `MCP-Protocol-Version` 누락·미지원처럼 HTTP transport 단계에서 거부된 요청은 HTTP `400 Bad Request`다.
|
||||
Agent Builder는 HTTP 상태만으로 성공 여부를 판단하지 않고 JSON-RPC body의 최상위 `result` 또는 `error`를 확인해야 한다. 일반적인 JSON-RPC 요청 오류는 HTTP `200 OK`와 함께 최상위 `error`로 반환될 수 있다. `-32602`의 `error.message`는 내부 검증 내용을 노출하지 않는 `Invalid params`이며, `error.data.reasonCode`와 `error.data.message`에는 Agent Builder가 안전하게 처리할 수 있는 정형화된 공개 오류 정보가 담긴다. 단, `MCP-Protocol-Version` 누락·미지원처럼 HTTP transport 단계에서 거부된 요청은 HTTP `400 Bad Request`다.
|
||||
|
||||
| 상황 | HTTP 상태 | JSON-RPC body | `isError` | 현재 구현의 처리 주체 |
|
||||
|---|---:|---|---|---|
|
||||
|
||||
Reference in New Issue
Block a user