OpenRouter 安全与可观测

OpenRouter 安全与可观测

护栏概览

1 分钟阅读

护栏

控制组织的支出和模型访问

护栏让组织可以控制其成员和 API 密钥如何使用 OpenRouter。你可以设置支出上限、限制可用的模型和模型服务提供商,并强制执行数据隐私策略。

任何现有的账户级设置仍会继续生效。护栏用于对单个 API 密钥或用户施加更严格的限制。

启用护栏

要为账户或组织创建和管理护栏:

  1. 在 OpenRouter 控制台中前往 设置 > 隐私(Settings > Privacy)
  2. 滚动到护栏(Guardrails)部分
  3. 点击「新建护栏(New Guardrail)」创建第一条护栏

如果使用的是组织账户,必须是组织管理员才能创建和管理护栏。

护栏设置

每条护栏可以包含以下任意组合:

  • 预算上限 - 以美元计的支出上限,按日、周或月重置。达到上限后请求会被拒绝。默认只有 OpenRouter 积分支出计入该上限;启用 计入 BYOK 支出(Include BYOK spend)include_byok_in_budgets)后,也会计入 BYOK 推理支出。
  • 模型允许列表 - 限制为特定模型。留空表示允许全部。
  • 模型服务提供商允许列表 - 限制为特定模型服务提供商。留空表示允许全部。
  • 零数据保留(ZDR) - 按模型组强制执行 ZDR(Anthropic、OpenAI、Google、SpaceXAI 以及非前沿模型)。详见零数据保留
  • 安全 - 通过基于正则表达式的检测防范提示词注入和越狱攻击。
  • 敏感信息 - 使用内置预设和基于 NLP 的检测,检测并遮蔽或阻止 API 请求中的敏感信息(个人身份信息,PII)。
  • 自定义内容过滤器 - 定义自己的正则表达式模式,对传入请求中的匹配内容进行遮蔽或阻止

单个 API 密钥的预算仍然生效。以更低的上限为准。

分配护栏

护栏可以在多个层级分配:

  • 成员分配 - 分配给特定组织成员。为其所有 API 密钥和聊天室用量设定基线。
  • API 密钥分配 - 直接分配给特定密钥,以实现更细粒度的控制。叠加在成员护栏之上。

每个用户或密钥只能直接分配一条护栏。组织成员创建的所有 API 密钥会隐式遵循该用户的护栏分配,即使该 API 密钥还被另一条护栏进一步限制。

护栏层级

账户级隐私和模型服务提供商设置始终作为默认护栏强制执行。当额外护栏作用于某次请求时,按以下规则合并:

  • 模型服务提供商允许列表:所有护栏取交集(仅所有护栏都允许的模型服务提供商可用)
  • 模型允许列表:所有护栏取交集(仅所有护栏都允许的模型可用)
  • 零数据保留:按模型组使用或逻辑(若任一条护栏对给定范围强制执行 ZDR,例如 Anthropic、OpenAI、Google、SpaceXAI 或非前沿模型,则对该范围强制执行)
  • 敏感信息:所有护栏取并集(合并所有适用护栏中的过滤器)。若同一实体类型或模式出现不同操作,阻止优先于遮蔽。
  • 预算上限:每条护栏的预算独立检查。详见预算执行

这意味着多条护栏同时生效时,更严格的规则始终胜出。例如,若成员护栏允许模型服务提供商 A、B 和 C,但 API 密钥护栏只允许 A 和 B,则该密钥只能使用 A 和 B。

可用性预览

查看护栏时,可以看到可用性预览,显示该护栏与账户设置合并后可用的模型服务提供商和模型。这有助于你在分配护栏前了解实际限制。

预算执行

护栏预算按用户和按密钥执行,不会在共用该护栏的所有用户之间共享。当 API 密钥发起请求时,其用量会同时计入该密钥的预算和所属成员的预算。

默认只有 OpenRouter 积分支出计入护栏预算。将 include_byok_in_budgets 设为 true(或在控制台中打开 计入 BYOK 支出),也会把 BYOK 推理支出(即若请求未使用你自己的模型服务提供商密钥,OpenRouter 本应收取的金额)计入同一上限。

示例 1:带有每天 $50 上限的成员护栏

你为三名团队成员 Alice、Bob 和 Carol 分配一条每天 $50 预算的护栏。每位成员各自拥有每天 $50 的额度。如果 Alice 花了 $50,她会被阻止,但 Bob 和 Carol 仍可各自花费最多 $50。

示例 2:API 密钥用量累计到成员用量

Alice 创建了两个 API 密钥,都分配了每天 $20 上限的护栏。密钥 A 花费 $15,密钥 B 花费 $10。每个密钥都未超过自己的 $20 上限,但 Alice 的成员总用量是 $25。如果 Alice 还有一条每天 $20 上限的成员护栏,她的请求会被阻止,因为合计用量($25)超过了成员上限($20)。

示例 3:分层护栏

Bob 有一条每天 $100 上限的成员护栏。他的 API 密钥另有一条每天 $30 上限的护栏。该密钥每天最多只能花 $30(其自身上限),但 Bob 所有密钥的总用量不能超过每天 $100。每次请求都会独立检查这两项上限。

自定义内容过滤器

每条护栏可以携带一组 自定义内容过滤模式。 每条模式都是带有对应操作的正则表达式:

  • 遮蔽(Redact) - 匹配片段在请求转发到模型之前被替换为占位符。
  • 阻止(Block) - 请求在到达模型之前以 403 被拒绝。

模式会在本地对每条用户消息求值,因此给请求增加的延迟可以忽略不计。

支持的正则特性

模式是 JavaScript 风格的正则表达式。以下常见构造均受支持:

  • 字符类([a-z]\d\w\s 等)
  • 量词(*+?{n,m}
  • 选择(foo|bar
  • 非捕获组((?:…)
  • 命名捕获组((?<name>…)
  • 锚点(^$\b
  • 转义序列(\.\(\\ 等)

不支持的正则特性

为保持对所有请求的求值快速且可预测,新建或编辑的模式中 不允许 使用以下特性:

  • 先行断言 - (?=…)(?!…)
  • 后行断言 - (?<=…)(?<!…)
  • 反向引用 - 数字形式(\1\2 等)和命名形式(\k<name>
  • 过度回溯 - 带有嵌套量词的模式,例如 (a+)+

API 会在创建和更新时以 invalid_regex_pattern 错误拒绝违规模式。

限制

  • 每条模式最多 100,000 个字符
  • 每条护栏可以有多条模式;每条独立求值。

请求被阻止时

当护栏的运行时检查阻止请求(例如内容过滤器或提示词注入检测器)时,OpenRouter 返回 HTTP 403 Forbidden 响应。请注意,预算上限和允许列表限制也会产生 403 响应,但只有运行时内容检查会包含 openrouter_metadata 的阶段详情。

{
  "error": {
    "code": 403,
    "message": "Request blocked: prompt injection patterns detected",
    "metadata": {
      "patterns": ["ignore all previous instructions"]
    }
  }
}

如果你通过 X-OpenRouter-Experimental-Metadata: enabled 请求头选择加入路由器元数据,403 响应还会包含完整的 openrouter_metadata 对象,其中有路由上下文以及显示已运行的每个护栏阶段的 pipeline 数组:

{
  "error": {
    "code": 403,
    "message": "Request blocked: prompt injection patterns detected",
    "metadata": {
      "patterns": ["ignore all previous instructions"]
    }
  },
  "openrouter_metadata": {
    "requested": "openai/gpt-4o",
    "strategy": "direct",
    "region": "iad",
    "summary": "available=1",
    "attempt": 1,
    "is_byok": false,
    "endpoints": {
      "total": 1,
      "available": [
        { "provider": "OpenAI", "model": "openai/gpt-4o", "selected": false }
      ]
    },
    "pipeline": [
      {
        "type": "guardrail",
        "name": "regex_pi_detection",
        "guardrail_id": "grd_abc123",
        "guardrail_scope": "api-key",
        "summary": "Blocked: prompt injection detected (1 pattern matched)",
        "data": {
          "action": "blocked",
          "detected": true,
          "engines": ["regex"],
          "patterns": ["ignore all previous instructions"]
        }
      }
    ]
  }
}

完整响应结构和流水线阶段说明,见路由器元数据,错误响应错误,护栏错误

API 访问

你可以使用 OpenRouter API 以编程方式管理护栏。这样可以直接从代码中创建、更新、删除护栏,并将其分配给 API 密钥和组织成员。

可用端点和用法示例见 护栏 API 参考

通过 API 更新工作区默认护栏

每个工作区都有一条 默认护栏,应用于该工作区的全部流量,无需显式分配给单个密钥或成员。要通过 API 更新工作区默认护栏:

  1. 列出护栏,以找到该工作区的默认护栏:
curl https://openrouter.ai/api/v1/guardrails?workspace_id=YOUR_WORKSPACE_ID \
  -H "Authorization: Bearer YOUR_MANAGEMENT_KEY"
  1. 在响应中识别默认护栏。它名为 Workspace <workspace-id> Default(其中 <workspace-id> 是工作区的 UUID)。

  2. 使用护栏的 id 更新它

curl -X PATCH https://openrouter.ai/api/v1/guardrails/GUARDRAIL_ID \
  -H "Authorization: Bearer YOUR_MANAGEMENT_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "allowed_providers": ["openai", "anthropic"],
    "limit_usd": 100,
    "reset_interval": "monthly",
    "include_byok_in_budgets": true,
    "enforce_zdr_anthropic": true,
    "enforce_zdr_openai": true
  }'

所有护栏设置都可以通过这种方式配置,包括预算上限、模型服务提供商/模型允许列表、零数据保留强制执行和内容过滤器。