Skip to content

[Ghost] 同域公开与鉴权端点无法分别控制凭证注入 #1714

Description

@FIERsity

问题

Ghost 的 network.secrets[].inject.hosts 当前按 hostname 匹配。若同一服务在同一 hostname 下同时提供公开端点和需要 API Key 的端点,manifest 无法表达“只对鉴权端点注入凭证”。

例如:

  • https://example.com/mcp:公开、无需认证
  • https://example.com/v1/convert:需要 Authorization: Bearer ...

以下声明会让两个端点都命中同一个 Secret:

{
  "network": {
    "hosts": ["example.com"],
    "secrets": [{
      "key": "api_key",
      "inject": {
        "header": "Authorization",
        "format": "Bearer {value}",
        "hosts": ["example.com"]
      }
    }]
  }
}

实际表现

在一个文件转换 Ghost 中,/mcp 原本是免登录接口,但因为可选 API Key 的 inject.hosts 命中了整个域名:

  1. 未配置 Key 时,调用公开 /mcp 会在 Host 网络层直接失败,提示凭证未配置;
  2. 删除未使用的 Secret/全域注入声明后,同一个 list_conversions 请求立即成功;
  3. 实测 docx 查询成功返回 14 条转换路线。

插件当前可通过删除未使用的 Secret 规避,但如果后续同时启用同域的 /mcp/v1/convert,插件侧没有安全、准确的表达方式。

期望

希望确认当前 host-only 行为是否为预期设计,并考虑为凭证注入增加更细粒度的显式 allowlist,例如:

  • path 精确匹配或前缀匹配;
  • 可选的 HTTP method 限定;
  • 或 manifest 中独立的 endpoint/request profile。

安全语义建议:未匹配时不注入;重定向逐跳重新判断;不根据远端 401/403 自动重试并携带凭证。

需要考虑的兼容与安全项

  • 旧 manifest 未声明新字段时保持当前行为;
  • path 前缀边界(如 /api 不应误匹配 /api-public);
  • URL 编码、query 是否参与匹配;
  • 同域和跨域重定向时重新匹配;
  • 未匹配端点绝不携带 Secret;
  • 权限展示、安装批准状态和插件升级行为;
  • Secret 不进入日志、返回值、沙箱或会话历史。

这是 manifest/权限边界变更,建议先讨论 schema,再决定是否实现核心 PR。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions