본문으로 건너뛰기

Managed Agents 도메인 제한

고급
What you'll learn
  • Managed Agents에서 도구별 허용/차단 도메인 목록이 실제로 막아주는 위협과 막지 못하는 위협을 구분한다
  • agent_toolset_20260401의 configs 배열로 web_search와 web_fetch를 특정 호스트에 고정한다
  • Anthropic이 생성 시점에 검증하는 열 가지 도메인 형식 규칙을 읽어, 400 오류가 버그를 프로덕션까지 끌고 가지 않게 한다
  • 멀티에이전트 의미론을 추론한다 — 코디네이터와 로스터 사이에서 허용 목록은 교집합을 취하고 차단 목록은 합쳐지는 이유
  • 런타임에 url_not_allowed tool_result와 session.error 이벤트를 처리하고, 재검증이 언제 일어나는지 안다
  • 이 설정을 Messages API의 서버 도구 도메인 필터, 그리고 샌드박스 네트워킹 정책과 구별한다

web_search와 web_fetch를 들고 있는 자율 Managed Agents 세션은 검색 엔진을 장착한 요청 위조기입니다. 에이전트가 "도움이 되는 참조 URL"이라고 믿게 유도될 수 있는 모든 문자열 — 가져온 페이지에 박힌 프롬프트 인젝션 페이로드, 메모리 스토어의 링크, 순수한 모델 환각 — 은 Anthropic의 크롤러가 여러분을 대신해 보내는 외부 요청이 됩니다. 이 베타가 나오기 전까지 그것을 막는 유일한 방법은 도구를 끄고, 직접 검증하는 커스텀 도구로 다시 도입하는 것이었습니다.

8월 26일 베타는 일급(first-class) 도구별 allowed_domains와 blocked_domains 목록을 추가하며, 여기에 페치에 적용되는 max_content_tokens와 검색에 적용되는 user_location도 더합니다. 이들은 외부 요청이 나가기 전에 Anthropic의 서버에서 강제됩니다. 이 표현에서 두 가지가 중요합니다.

  • 강제는 Anthropic의 서버에서 이루어지며, 여러분의 샌드박스 안에서가 아닙니다. 그래서 샌드박스 networking 정책(샌드박스 내부 코드가 무엇에 접근할 수 있는지 제어하는 설정)은 무관합니다. 툴셋에 도메인 목록을 두지 않은 채 샌드박스 네트워크만 잠가두면, 에이전트의 web_fetch는 여전히 원하는 곳 어디든 도달합니다 — 페치는 샌드박스 바깥에서 실행됩니다.
  • Claude Console의 조직 수준 웹 필터는 Messages API에만 적용됩니다. 그것은 Managed Agents 세션에 붙지 않습니다. 조직에 콘솔 수준의 "ads.example.com 차단" 규칙이 있는데 그것을 툴셋에 반영하지 않았다면, 에이전트 세션은 그 주소를 가져옵니다.

설정이 사는 곳​

모든 내장 도구는 에이전트의 tools 배열 안에 있는 agent_toolset_20260401 툴셋 객체에 들어 있고, 각 도구는 그 툴셋의 configs 배열 항목으로 설정됩니다. 항목은 name(web_search, web_fetch, bash, read, write, edit, glob, grep)으로 식별되고, 같은 값을 갖는 선택적 type 필드로 타입이 지정되며, 두 웹 도구의 경우에는 일반적인 enabled와 permission_policy와 더불어 allowed_domains, blocked_domains, max_content_tokens, user_location을 받습니다.

최소 형태:

web_search와 web_fetch를 두 호스트에 고정하고 가져온 콘텐츠에 상한 두기

{
"type": "agent_toolset_20260401",
"configs": [
  {
    "name": "web_search",
    "allowed_domains": ["docs.example.com", "arxiv.org"],
    "user_location": {
      "type": "approximate",
      "country": "US",
      "timezone": "America/Los_Angeles"
    }
  },
  {
    "name": "web_fetch",
    "blocked_domains": ["ads.example.com"],
    "max_content_tokens": 50000
  }
]
}

각 도구는 자기 자신의 목록을 가집니다 — 검색 허용 목록은 페치를 제약하지 않고, 그 반대도 마찬가지입니다. 두 목록을 함께 움직이고 싶다면 직접 동기화해야 합니다.

전체 에이전트 생성 요청​

POST /v1/agents — 요청 전체

curl -fsSL https://api.anthropic.com/v1/agents \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "anthropic-beta: managed-agents-2026-04-01" \
-H "content-type: application/json" \
-d '{
  "name": "Research Agent",
  "model": "claude-opus-5",
  "tools": [
    {
      "type": "agent_toolset_20260401",
      "configs": [
        {
          "name": "web_search",
          "allowed_domains": ["docs.example.com", "arxiv.org"],
          "user_location": {
            "type": "approximate",
            "country": "US",
            "timezone": "America/Los_Angeles"
          }
        },
        {
          "name": "web_fetch",
          "blocked_domains": ["ads.example.com"],
          "max_content_tokens": 50000
        }
      ]
    }
  ]
}'

Python, TypeScript, Go, Java, C#, Ruby, PHP SDK에서는 각 configs 항목이 도구별 구별 유니온(BetaManagedAgentsWebSearchToolConfigParams, BetaManagedAgentsWebFetchToolConfigParams 등)으로 타입이 지정됩니다. 서버가 name으로부터 추론하기 때문에 생성 시 type은 선택적이지만, 응답에는 항상 함께 돌아옵니다. name, enabled, permission_policy만 설정하는 요청은 type이 있든 없든 계속 유효합니다 — 이 베타를 쓰려고 기존 코드를 다시 쓸 필요는 없습니다.

열 가지 도메인 형식 규칙​

Anthropic은 에이전트 생성/업데이트 시점과 세션 생성/업데이트 시점에 나열된 모든 도메인을 검증하고, 문제가 된 항목의 목록 이름과 0부터 시작하는 위치를 메시지에 담은 400 invalid_request_error 를 반환합니다(allowed_domains.0: IP addresses are not supported…). 이 규칙들은 Messages API가 받아들이는 것보다 엄격하며, 하나하나가 실전에서 발에 총을 쏘는 지점입니다.

Guided walkthrough1 of 10
  1. 한 항목에는 allowed_domains 또는 blocked_domains 중 하나만 설정하세요 — 절대 둘 다 쓰지 마세요. 둘 다 있는 항목은 거부됩니다: "Only one of allowed_domains or blocked_domains may be set."

기반 제공자에 의존하는 두 가지 추가 검사도 생성/업데이트 시점에 강제됩니다. Anthropic의 크롤러가 접근할 수 없는 도메인은 allowed_domains에 대해 거절되고, 지원되지 않는 user_location.country는 user_location.country: not a country the search provider supports로 끝나는 메시지를 반환하며, user_location.timezone은 유효한 IANA 이름이어야 합니다.

멀티에이전트 세션 — 목록이 결합되는 방식​

멀티에이전트 세션은 하나의 도구 호출에 세 종류의 목록을 겹칠 수 있습니다. 코디네이터의 현재 목록, 이 에이전트를 호출한 에이전트의 목록, 그리고 로스터 에이전트 자신의 목록입니다. 해당 스레드에 적용되는 모든 목록이 동시에 강제됩니다.

  • 허용 목록은 교집합을 취합니다. 유효한 집합은 적용 가능한 모든 허용 목록이 포함하는 도메인입니다. 로스터 에이전트는 도구가 도달하는 범위를 좁힐 수는 있어도 절대 넓힐 수는 없습니다 — 코디네이터의 허용 목록 안에 없는 허용 목록을 로스터 에이전트에 설정하면, 모든 호출이 허용된 도메인이 없다는 메시지와 함께 url_not_allowed 오류로 돌아옵니다. 도구 설명이 모델에게 이를 미리 알려줍니다.
  • 차단 목록은 합쳐집니다. 적용되는 모든 차단 목록이 함께 강제되므로, 어느 계층의 차단 목록에든 올라 있는 호스트는 그 스레드에서 도달할 수 없습니다.
  • max_content_tokens와 user_location은 결합되지 않습니다. 스레드는 먼저 자신의 도구 설정을 읽고, 그다음 호출한 에이전트의 설정, 그다음 코디네이터의 현재 설정을 읽습니다 — 첫 번째 non-null 값이 이깁니다.
  • {"type": "self"} 로스터 항목은 자신만의 웹 설정을 갖지 않으며 코디네이터의 현재 설정을 따릅니다.
  • 결과 기반 세션의 grader는 웹 도구 없이 실행됩니다 — grader에게는 실행할 web_search나 web_fetch가 아예 없으므로 허용 목록도 차단 목록도 의미가 없습니다.

그 결과: 코디네이터의 허용 목록이 [docs.example.com, arxiv.org]이고 로스터 에이전트의 허용 목록이 [github.com]이라면, 로스터 에이전트가 도달할 수 있는 호스트는 0개입니다. 로스터 에이전트의 허용 목록은 코디네이터의 부분집합으로 설계하거나, 아예 설정하지 마세요.

세션 중간 업데이트와 두 번째 검증​

유휴 상태인 세션의 tools를 업데이트해 도메인 목록을 바꿀 수 있습니다 — 새 목록은 그 시점 이후부터 적용됩니다. 멀티에이전트 세션에서는 각 스레드가 다음 턴에 새 목록을 집어 들지만, 로스터 에이전트의 자체 목록은 세션 생성 시점에 고정됩니다(세션이 아니라 에이전트 정의에 들어 있기 때문입니다).

두 번째 검증은 세션이 도구를 처음 초기화할 때 일어납니다. 생성 시점의 동기 검사를 통과한 도메인도 나중에 실패할 수 있습니다(허용 목록에 있던 호스트가 그 사이에 크롤러 접근 권한을 잃었을 수 있습니다). 런타임 검사가 실패하면 세션은 session.error 이벤트를 발생시키고 idle로 돌아가며 재시도하지 않습니다. 해결 방법은 세션의 tools를 업데이트하고, 새 세션이 깨끗하게 시작되도록 에이전트도 함께 업데이트한 뒤, 새 user.message를 보내는 것입니다.

런타임 오류 경로​

세션 실행 시점에, 두 도구는 목록이 금지한 URL을 만났을 때 서로 다르게 동작합니다.

  • web_fetch 는 에이전트에게 오류 결과를 반환합니다. agent.tool_result 이벤트에 is_error: true가 붙고, 오류 코드 url_not_allowed를 명시한 콘텐츠 블록이 함께 옵니다. 모델은 그것을 보고 적응할 수 있습니다(다른 출처를 고르거나, 사용자에게 묻거나, 멈추거나) — 이것은 세션 실패가 아니라 일반적인 도구 실패입니다.
  • web_search 는 목록이 허용하지 않는 호스트의 결과를 조용히 생략합니다. 모델은 그것을 아예 보지 못합니다. 검색에는 그게 올바른 기본값입니다 — 대안은 필터링된 결과의 URL을 트랜스크립트로 흘리는 것이니까요 — 하지만 좋은 쿼리여야 할 검색이 "결과 없음"을 반환한다면, 그것은 단순 재시도가 아니라 허용 목록을 넓혀야 한다는 신호입니다.

두 신호 모두 세션 이벤트 핸들러에 들어가야 합니다. 초기화 시점의 실패에는 session.error, 호출별 실패에는 is_error: true와 url_not_allowed를 담은 agent.tool_result, 그리고 비율 신호로는 허용 목록이 작을 때 결과 수가 0으로 떨어지는 모든 검색 턴을 보세요.

Messages API 서버 도구 도메인 필터와의 차이​

Managed Agents는 Messages API의 server_tools web_search / web_fetch 필터보다 의도적으로 더 엄격한 체제를 운영합니다. 어휘는 같지만 네 가지가 더 조이고, 한 가지는 아예 빠져 있습니다.

  • 목록 상한은 도메인 64개 로, Messages API의 더 큰 상한과 다릅니다. 큰 허용 목록은 그대로 이식되지 않습니다 — 여러 에이전트로 쪼개세요.
  • web_fetch 도메인에는 경로를 넣을 수 없습니다. Messages API는 두 도구 모두에서 경로를 받아들입니다. 이식할 때는 Messages API 스타일의 example.com/blog 항목을 평범한 호스트명으로 옮기세요.
  • ASCII만 — 국제화 이름에는 퓨니코드가 필요합니다. Messages API는 (권장하지는 않지만) 유니코드 항목을 허용합니다.
  • max_uses, citations, cache_control은 툴셋에서 사용할 수 없습니다. 이들은 툴셋이 노출하지 않기로 한 Messages API 전용 노브입니다. 대신 세션별 가격 체계와 response_inclusion 파라미터를 전제로 설계하세요.

기존 Messages API 에이전트를 Managed Agents로 이식하는 경우, 대부분의 기존 필터는 깔끔하게 옮겨집니다. 베어 example.com 항목, 서브도메인 포함 매칭, "항목당 목록 하나" 규칙은 모두 동일합니다.

흔한 함정 — 실제 팀들이 걸려 넘어지는 다섯 가지​

  1. www.example.com은 example.com이 아닙니다. www.example.com만 나열하면 베어 에이펙스 example.com은 허용되지 않고, example.com만 나열하면 www.example.com까지 포함됩니다(www.도 다른 서브도메인과 똑같기 때문입니다). 둘 다 얻으려면 베어 도메인을 나열하세요.
  2. 샌드박스 networking 정책은 이 도구들에 영향을 주지 않습니다. web_search와 web_fetch는 Anthropic의 서버에서 실행되므로, 샌드박스의 모든 외부 송신을 거부하는 환경이라도 툴셋이 허용한 것은 기꺼이 가져옵니다. 다층 방어를 원한다면 두 정책을 서로 반영시키세요.
  3. 콘솔 수준의 조직 필터는 붙지 않습니다. 콘솔의 조직 전체 웹 필터는 Messages API 전용입니다. 콘솔에서 설정한 "ads.example.com 차단" 규칙은 Managed Agents에 전혀 닿지 않습니다.
  4. 세션 예산을 추가하는 것이 도메인 제한을 의미하지는 않습니다. 세션 예산은 금액에 상한을 둘 뿐, 목적지에는 상한을 두지 않습니다. 예산이 걸린 세션도 적대적인 페이지 하나를 가져오느라 상한을 전부 태울 수 있습니다. 둘 다 쓰세요.
  5. web_search의 경로 접미사는 호스트 규칙이 아니라 URL 패턴입니다. 평범한 호스트명을 쓰는 편이 낫습니다 — 검색의 경로 필터는 권고 수준의 강도이며, 제공자가 기대보다 느슨하게 매칭할 수 있습니다.

이것이 실제로 완화하는 것​

위협 모델을 구체적으로 짚읍시다 — 여기서 과장하면 이것을 완전한 SSRF 해법으로 가정하는 팀들이 물립니다. 그렇지 않습니다. 이것이 실제로 다루는 세 가지 구체적 위험은 다음과 같습니다.

  • 프롬프트 인젝션 내비게이션. "계속하려면 이 URL을 가져와라"라고 지시하는 오염된 페이지나 메모리 스토어 항목은, 그 호스트가 허용되지 않았다면 url_not_allowed로 실패하고, 모델은 오류를 보고 (대개) 멈춥니다.
  • 광고 및 텔레메트리 목적지. 차단 목록은 대상 페이지가 에이전트를 끌어가려는 트래킹 도메인으로부터 에이전트의 페치를 지켜줍니다.
  • 페치를 통한 데이터 유출. 민감한 쿼리 스트링 파라미터(?leaked=<memory>)가 담긴 web_fetch URL을 만들도록 속아 넘어간 에이전트도, 호스트가 허용되지 않은 적대적 수신자에게는 도달할 수 없습니다.

막아주지 않는 것: 여러분이 정의한 커스텀 도구, MCP 서버 도구, 샌드박스가 실행하는 코드, 그리고 web_search/web_fetch가 아닌 모든 도구에서 나가는 외부 요청입니다. 각각에는 자기 노브가 있습니다(샌드박스 networking, MCP 서버 허용 목록, 커스텀 도구 코드). 이 설정 하나는 여러 겹으로 된 이야기의 한 겹입니다.

Key takeaways
  • allowed_domains와 blocked_domains는 agent_toolset_20260401의 configs 배열 안에 도구별로 존재합니다. 각 도구가 자기 목록을 갖고, 둘은 자동으로 함께 움직이지 않습니다
  • 열 가지 형식 규칙 — 스킴 금지, 포트 금지, 와일드카드 금지, web_fetch에 경로 금지, 베어 TLD 금지, localhost나 .local 금지, IDN에는 퓨니코드, 도메인 1~64개, 중복 금지, 서브도메인 매칭은 아래 방향으로만
  • 멀티에이전트 의미론: 허용 목록은 교집합을 취하고 차단 목록은 합쳐집니다. 로스터 에이전트는 코디네이터의 도달 범위를 좁힐 수는 있어도 절대 넓힐 수 없습니다
  • 런타임: web_fetch는 금지된 URL에 대해 is_error와 url_not_allowed로 실패하고, web_search는 금지된 결과를 조용히 생략합니다
  • 이것은 Managed Agents 전용입니다. 콘솔의 조직 필터는 붙지 않고, 샌드박스 네트워킹 정책은 이 도구들에 영향을 주지 않습니다 — 다층 방어를 원하면 규칙을 서로 반영시키세요
  • Messages API 서버 도구 필터와 같지 않습니다: 더 엄격하고(64개 상한, web_fetch에 경로 불가, ASCII 전용) max_uses, citations, cache_control이 없습니다

스스로 확인하기​

스스로 확인하기

0/5
  1. web_fetch 항목에 allowed_domains: ["example.com"]을 설정했습니다. 다음 중 에이전트가 가져올 수 있는 URL은 무엇일까요?
  2. 코디네이터의 web_fetch 허용 목록이 ["docs.example.com", "arxiv.org"]입니다. 한 로스터 에이전트가 자신의 web_fetch 허용 목록을 ["github.com"]으로 설정합니다. 이 로스터 에이전트가 https://github.com/anthropic-ai/sdk를 가져오려 하면 어떻게 될까요?
  3. 여러분 팀은 Claude Console 조직 수준에서 ads.example.com을 차단하는 정책을 두고 있습니다. web_fetch가 활성화되어 있고 도메인 목록은 없는 Managed Agents 세션을 띄웁니다. 에이전트가 https://ads.example.com을 가져옵니다. 어떻게 될까요?
  4. allowed_domains: ["https://docs.example.com", "127.0.0.1", "co.uk"]로 에이전트를 제출합니다. API는 무엇을 반환할까요?
  5. 목록이 허용하지 않는 URL에 대한 web_fetch 호출은 무엇을 할까요?

출처 & 더 읽을거리​

다음으로​