メインコンテンツへスキップ
ガードレールまたはファイアウォール がリクエストを停止すると、OrcaRouter は曖昧な 400 ではなく、コードが分岐できる 型付きエラーを返します。3 つのセキュリティコードが、目にするケースをカバーします: スクリーニングされたプロンプトまたはレスポンス、拒否されたツール呼び出し、そして 人間による承認のために保留されたツール呼び出しです。 このページは、それらのコードのリファレンスです — それぞれのユースケース、正確な HTTP ステータス、何があなたのコストになるか、そして最も重要なひとつのルール: リトライロジックはこれらを特別扱いしなければなりません。 3 つすべてが skip-retry とマークされています;同じ呼び出しを盲目的に再実行しても、同じ コントロールがまた発火するだけです。
これらは強制コードです — ゲートウェイがあなたの呼び出しを転送しないと 決定したものです。これらは、アップストリームのプロバイダエラー(モデルの 429、 コンテキストオーバーフロー)や認証エラーとは区別されます。特定のリクエストが なぜ停止されたかについては、 なぜブロックされたのか?を参照してください。

1. LLM セキュリティエラーコード一覧

すべてのセキュリティブロックは、OpenAI 形式のエラーボディとともに HTTP 400 を返します(error.code は下記の型付き文字列です)。ネイティブ Claude (/v1/messages)ルートでは、同じコードが Claude のエラー形状で伝わるため、 SDK ルーティングはプロトコルをまたいで決定論的です。
コード停止するものクォータコスト
guardrail_blockedblock ルールにヒットしたプロンプトまたはレスポンスなし
firewall_blocked拒否されたツール呼び出し / アドバタイズモデルトークンなし
firewall_approval_pending人間のレビュアーのために保留されたツール呼び出しモデルトークンなし
メッセージ文字列ではなく、error.code で分岐してください。メッセージは特定の ガードレール、ルール、またはツールを名指しし、変わります;コードは安定した 契約です。

2. guardrail_blocked — スクリーニングされたプロンプトまたはレスポンス

block アクションを持つガードレールルールが発火したときに 返されます — 拒否リストのキーワード、正規表現ヒット、マスクではなくブロックする ことを選んだ PII やシークレットエンティティ、llm_judge 判定、あるいは失敗した グラウンディングチェックです。 HTTP 400。 メッセージは、発火したガードレールとルールを名指しします。
ブロックされたリクエストはクォータを消費しません。入力ステージのブロックは メータリングのに発火するため、何も課金されません。出力ステージのブロックは モデルが応答したに走るため、ゲートウェイはエラーを返す前に事前消費された クォータを返金します。いずれにせよ、ブロックされた呼び出しには何も払いません。
判定はコンテンツのプロパティであり、チャネルのプロパティではありません。同じ プロンプトを — 別のモデルに対してでも — 再実行すると、同じブロックが生じます。 リトライする代わりに、入力(またはポリシー)を修正してください。
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)"
  }
}
このコードの背後にあるルールタイプ、ステージ、アクションについては、 ガードレールを参照してください。フィールド単位の エラーエンベロープについては、 Webhook とエラーペイロードを参照してください。

3. firewall_blocked — 拒否されたツール呼び出し

ファイアウォールがツール呼び出しに対して deny 判定を 解決したときに返されます — 破壊的シェルコマンド、SSRF 形状のフェッチ、拒否リスト 上の egress 宛先、あるいは block モードのスキルです。 deny がどう表面化するかは、強制サーフェス に依存します:

inbound / response / egress

error.code = firewall_blockedHTTP 400。ボディは構造化された error.metadatareason_code、リスク factorsrisk_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 判定にヒットした瞬間に返されます。 ヒューマンインザループのゲートはブロッキングなインラインの待機にはできないため、 ゲートウェイはロングポーリングではなく、即座に保留レスポンスを返します。 HTTP 400。 エラーは承認 id を運ぶため、エージェントはどの保留を解決すべきかを 知ることができます。 これは、終端的な失敗として扱うのではなく、解決して再送信することで反応する 唯一のコードです:
1

保留エラーから承認 id を読み取る

id はエラーボディから回収可能です。まだ呼び出しをリトライしないでください — 素朴なリトライは再び保留するだけです。
2

決定を待つ

レビュアーがコンソール(Developer+)からそれを解決するか、あなたの承認システムが HMAC 署名付き webhook コールバックを受け取ります。エージェントは状態を GET /api/v1/firewall/approvals/:id でポーリングします。
3

承認トークンとともに再送信する

承認されると、単回使用の X-OrcaRouter-Firewall-Approval ヘッダーを携えて元の 呼び出しを再発行します。ゲートウェイは id を認識し、その 1 つの呼び出しを通します。
承認ルート(/api/v1/firewall/approvals/*)は、コンソールセッションではなく ファイアウォールゲートウェイスコープのキー上で動作します。フルループについては 人間による承認(HITL)を、 コールバック署名についてはWebhook ペイロードを 参照してください。

5. なぜ 3 つすべてがリトライをスキップするのか

標準的な SDK リトライロジックは、400 が 2 回目の試行で成功するかもしれないと 仮定します。これらのコードはその仮定を壊します — ブロックは決定論的なので、盲目的な リトライはラウンドトリップを無駄にし、(保留された呼び出しについては)サイレントに 承認を再キューイングします。
OrcaRouter 自身の内部リトライ/フォールバック機構は、これらのコードを返す呼び出しを 別のチャネルに対して再試行することは決してありません。クライアントでもそれを ミラーしてください:セキュリティコードでは、停止して判定に基づいて行動するのであり、 ループしないでください。
  • guardrail_blocked → 入力を修正するかポリシーを緩和する;拒否をユーザーに 表面化する。リトライしない。
  • firewall_blocked → そのアクションは許可されていません;エージェントに別の ツールを選ばせるか、助けを求めさせます。リトライしない。
  • firewall_approval_pending → 保留を解決してから、承認ヘッダーとともに一度だけ 再送信する(§4)。ヘッダーなしのリトライは再保留します。

6. クォータと課金のサマリー

セキュリティブロックは、ブロックされた作業単位についてあなたに課金することは 決してありません。
コードいつ発火するか課金結果
guardrail_blocked(input)モデル呼び出しの前決してメータリングされない
guardrail_blocked(output)モデルが応答した後事前消費されたクォータを返金
firewall_blocked(inbound)モデル呼び出しの前モデルトークンなし
firewall_approval_pendingディスパッチの前モデルトークンなし
ガードレールの llm_judge または grounding ルールは、判定に達するために実際に モデルを呼び出し、それらのジャッジトークンは — 判定がブロックのときでも — 別の ジャッジサブラインとして課金されます。それはチェックのコストであり、ブロックされた リクエストそのもののコストではありません。

7. 関連リファレンス

なぜブロックされたのか?

1 つのブロックを、それを生み出した正確なルール、サーフェス、理由までトレースします。

判定用語集

すべてのファイアウォール判定 — allow、audit、deny、sanitize、pending_approval、 cap_cost — とそれぞれが何を発するか。

Webhook とエラーペイロード

完全なエラーエンベロープ、error.metadata フィールド、そして承認コールバック署名。

強制モード

シャドウ、観察、強制 — 判定が実際にトラフィックを変えるのはいつか。
これらのコードを生み出すコントロールについては、ガードレールファイアウォールを参照してください;用語については、 コンセプト用語集を参照してください。