메인 콘텐츠로 건너뛰기
guardrail 또는 firewall이 요청을 중단하면, OrcaRouter는 막연한 400이 아니라 코드가 분기할 수 있는 타입 지정 오류를 반환합니다. 세 개의 보안 코드가 여러분이 마주칠 경우를 모두 다룹니다: 스크리닝된 프롬프트 또는 응답, 거부된 툴 호출, 그리고 사람 승인을 위해 보류된 툴 호출. 이 페이지는 그 코드들의 레퍼런스입니다 — 각각의 사용 사례, 정확한 HTTP 상태, 그것이 무엇을 비용으로 치르게 하는지, 그리고 가장 중요한 한 가지 규칙: 재시도 로직은 이들을 특수 처리해야 합니다. 세 가지 모두 skip-retry로 표시됩니다; 동일한 호출을 맹목적으로 다시 실행하면 그저 동일한 컨트롤을 다시 발동시킬 뿐입니다.
이들은 강제 코드입니다 — 게이트웨이가 여러분의 호출을 전달하지 않기로 결정한 것입니다. 이들은 업스트림 프로바이더 오류(모델 429, 컨텍스트 초과)나 인증 실패와는 구별됩니다. 특정 요청이 왜 중단되었는지는 왜 차단되었나요?를 참조하세요.

1. llm 보안 오류 코드 한눈에 보기

모든 보안 차단은 OpenAI 형태의 오류 본문과 함께 HTTP 400을 반환합니다 (error.code는 아래의 타입 지정 문자열). 네이티브 Claude (/v1/messages) 라우트에서는 동일한 코드가 Claude 오류 형태로 전달되므로, SDK 라우팅이 프로토콜 전반에서 결정적입니다.
Code무엇을 중단하는가쿼터 비용
guardrail_blockedblock 규칙에 걸린 프롬프트 또는 응답없음
firewall_blocked거부된 툴 호출 / 광고모델 토큰 없음
firewall_approval_pending사람 검토자를 위해 보류된 툴 호출모델 토큰 없음
메시지 문자열이 아니라 error.code로 분기하세요. 메시지는 특정 guardrail, 규칙, 또는 툴을 명시하며 변경될 것입니다; 코드는 안정적인 계약입니다.

2. guardrail_blocked — 스크리닝된 프롬프트 또는 응답

block 액션을 가진 guardrail 규칙이 발동할 때 반환됩니다 — 거부 목록 키워드, 정규식 매치, 마스킹 대신 차단을 선택한 PII 또는 시크릿 엔티티, llm_judge 판정, 또는 실패한 그라운딩 검사. HTTP 400. 메시지는 발동한 guardrail과 규칙을 명시합니다.
차단된 요청은 쿼터를 소모하지 않습니다. 입력 단계 차단은 미터링 전에 발동하므로 아무것도 청구되지 않습니다. 출력 단계 차단은 모델이 응답한 후에 실행되므로, 게이트웨이는 오류를 반환하기 전에 사전 소비된 쿼터를 환불합니다. 어느 쪽이든 차단된 호출에 대해 아무것도 지불하지 않습니다.
판정은 채널이 아니라 콘텐츠의 속성입니다. 동일한 프롬프트를 — 심지어 다른 모델에 대해서도 — 다시 실행하면 동일한 차단이 발생합니다. 재시도 대신 입력(또는 정책)을 고치세요.
mask 규칙은 이 코드를 반환하지 않습니다. 마스킹된 매치(예: jane@acme.com[EMAIL])는 제자리에서 편집되고 호출은 정상적으로 진행됩니다 — 민감한 구간이 제거된 채로 200을 받습니다. block 액션만 guardrail_blocked를 표면화합니다. (flag는 트래픽에 대해 아무것도 변경하지 않습니다.)
{
  "error": {
    "type": "openai_error",
    "code": "guardrail_blocked",
    "message": "request blocked by guardrail \"pii-shield\": rule ssn (block)"
  }
}
이 코드 뒤의 규칙 유형, 단계, 액션은 Guardrails를 참조하세요. 필드별 오류 봉투는 웹훅 및 오류 페이로드를 참조하세요.

3. firewall_blocked — 거부된 툴 호출

firewall이 툴 호출에 대해 deny 판정을 해석할 때 반환됩니다 — 파괴적 셸 명령, SSRF 형태의 fetch, 거부 목록상의 egress 목적지, 또는 block 모드의 skill. 거부가 어떻게 표면화되는지는 강제 표면에 따라 다릅니다:

inbound / response / egress

error.code = firewall_blocked와 함께 HTTP 400. 본문은 구조화된 error.metadata(reason_code, 위험 factors, risk_score)를 담으므로, 차단을 그저 보는 것이 아니라 설명할 수 있습니다.

mcp 표면

전송 실패가 아니라 툴 오류(firewall deny: <reason>)로 반환되므로 — 모델이 거부를 보고 다른 툴을 선택하거나, 사용자에게 묻거나, 중단할 수 있습니다, 실행을 크래시시키는 대신.
sanitize는 차단이 아닙니다. sanitize 판정은 툴 호출 인자에서 매치된 부분 문자열을 편집하고 정화된 호출을 전달합니다 — 결코 firewall_blocked를 반환하지 않습니다. (한 가지 예외: 아직 호출 시점 인자가 없는 inbound 표면에서는 sanitize가 deny로 격상됩니다.)
{
  "error": {
    "type": "openai_error",
    "code": "firewall_blocked",
    "message": "tool \"shell.exec\" blocked by firewall: denied tool",
    "metadata": {
      "reason_code": "FW-TOOL-001",
      "risk_score": 92,
      "factors": ["denied_tool"]
    }
  }
}
쿼터 측면에서, inbound 차단은 업스트림 모델 호출 전에 발동하므로 모델 토큰을 소모하지 않습니다. 모든 판정은 판정 용어집을, 이 코드가 방어하는 위협은 위험한 툴 호출을 참조하세요.

4. firewall_approval_pending — 사람을 위해 보류됨

툴 호출이 pending_approval 판정에 걸리는 즉시 반환됩니다. human-in-the-loop 게이트는 인라인 블로킹 대기일 수 없으므로, 게이트웨이는 롱 폴링 대신 즉시 held 응답을 반환합니다. HTTP 400. 오류는 승인 id를 담아 에이전트가 어떤 보류를 해결해야 할지 알 수 있게 합니다. 이것은 종료 실패로 취급하는 것이 아니라 해결하고 재제출함으로써 대응하는 유일한 코드입니다:
1

held 오류에서 승인 id를 읽는다

id는 오류 본문에서 복구 가능합니다. 아직 호출을 재시도하지 마세요 — 순진한 재시도는 그저 다시 보류시킵니다.
2

결정을 기다린다

검토자가 콘솔에서 해결하거나(Developer+), 여러분의 승인 시스템이 HMAC 서명 웹훅 콜백을 받습니다. 에이전트는 상태를 위해 GET /api/v1/firewall/approvals/:id를 폴링합니다.
3

승인 토큰과 함께 재제출한다

일단 승인되면 일회용 X-OrcaRouter-Firewall-Approval 헤더를 담아 원래 호출을 재발행하세요. 게이트웨이는 id를 인식하고 그 한 번의 호출을 통과시킵니다.
승인 라우트(/api/v1/firewall/approvals/*)는 콘솔 세션이 아니라 firewall-gateway-scoped 키에서 실행됩니다. 전체 루프는 Human approval (HITL)을, 콜백 서명은 웹훅 페이로드를 참조하세요.

5. 셋 모두가 재시도를 건너뛰는 이유

표준 SDK 재시도 로직은 400이 두 번째 시도에서 성공할 수도 있다고 가정합니다. 이 코드들은 그 가정을 깨뜨립니다 — 차단은 결정적이므로, 맹목적 재시도는 왕복을 낭비하고 (보류된 호출의 경우) 조용히 승인을 다시 큐에 넣습니다.
OrcaRouter 자체 내부 재시도/폴백 메커니즘은 이 코드 중 하나를 반환하는 호출을 결코 다른 채널에 대해 재시도하지 않습니다. 클라이언트에서도 이를 미러링하세요: 보안 코드에서는 멈추고 판정에 따라 행동하고, 루프를 돌지 마세요.
  • guardrail_blocked → 입력을 고치거나 정책을 완화하세요; 거부를 사용자에게 표면화하세요. 재시도하지 마세요.
  • firewall_blocked → 액션이 허용되지 않습니다; 에이전트가 다른 툴을 선택하거나 도움을 요청하게 하세요. 재시도하지 마세요.
  • firewall_approval_pending → 보류를 해결한 뒤, 승인 헤더와 함께 한 번 재제출하세요(§4). 헤더 없는 재시도는 다시 보류시킵니다.

6. 쿼터 및 청구 요약

보안 차단은 차단된 작업 단위에 대해 결코 청구하지 않습니다.
Code언제 발동하는가청구 결과
guardrail_blocked (input)모델 호출 전결코 미터링되지 않음
guardrail_blocked (output)모델이 응답한 후사전 소비된 쿼터 환불
firewall_blocked (inbound)모델 호출 전모델 토큰 없음
firewall_approval_pending디스패치 전모델 토큰 없음
guardrail의 llm_judge 또는 grounding 규칙은 판정에 도달하기 위해 실제로 모델을 호출하며, 그 judge 토큰은 — 판정이 차단일 때조차 — 별도의 judge 하위 라인으로 청구됩니다. 그것은 검사의 비용이지, 차단된 요청 자체의 비용이 아닙니다.

7. 관련 레퍼런스

왜 차단되었나요?

단일 차단을 그것을 생성한 정확한 규칙, 표면, 이유로 추적하세요.

판정 용어집

모든 firewall 판정 — allow, audit, deny, sanitize, pending_approval, cap_cost — 과 각각이 무엇을 방출하는지.

웹훅 및 오류 페이로드

전체 오류 봉투, error.metadata 필드, 그리고 승인 콜백 서명.

강제 모드

Shadow, observe, enforce — 판정이 실제로 트래픽을 변경하는 시점.
이 코드들을 생성하는 컨트롤은 GuardrailsFirewall을; 용어는 개념 용어집을 참조하세요.