概览

MCP 服务器安全

本页面面向需要批准将 AI 代理连接到 Docsbook 的人员。页面说明了 MCP 服务器目前实际执行的操作——客户端如何进行身份验证、每个作用域可以访问哪些内容、哪些信息会被记录、哪些数据会离开网络——随后在两个独立的章节中分别列出 Docsbook 与模型上下文协议规范的差距,以及目前尚不存在的合规证明材料。

这里没有任何愿景式描述。缺失的控制措施会明确列为缺失。

你将获得什么#

一个已连接的客户端持有一个不透明的 Bearer 令牌,该令牌绑定到一个 Docsbook 账户,并携带两个作用域中的一个。作用域由用户在同意屏幕上选择,而不是由客户端请求。每个作用于项目的工具都会通过所有者解析该项目,因此,令牌即使指向属于其他人的工作区 ID,也不会获得任何返回结果,而不是获得该工作区:这就是租户之间的边界,并且这一边界适用于每个工具。

读写之间的边界比两个作用域名称所暗示的更窄,下面的部分会准确说明哪些工具会强制执行该边界,哪些不会。在将只读令牌视为隔离措施之前,请先阅读该部分。

每次计量调用都会向你项目自己的调用日志写入一行记录:使用了哪个工具、传入了什么、返回了什么、耗时多久以及消耗了什么。参数和结果在存储之前会按键进行脱敏,因此传递给工具的 API 密钥绝不会被记录下来。

你不会获得的内容:令牌过期机制、刷新令牌、速率限制、账户内的角色或审计报告。

身份验证的工作原理#

授权流程#

Docsbook 既是自己的授权服务器,也是自己的资源服务器。它为自身签发不透明令牌;从不接受、转发或重复使用任何其他方签发的令牌。

步骤 发生的情况
发现 向服务器端点发送未经身份验证的请求,会返回包含 WWW-Authenticate: Bearer resource_metadata="…/.well-known/oauth-protected-resource"401。该文档会指出资源及其授权服务器;/.well-known/oauth-authorization-server 以 RFC 8414 格式携带各端点。
客户端注册 向注册端点发送 POST 会以 RFC 7591 格式返回新的 client_id。客户端不会持久化——ID 以无状态方式生成,授权端点接受任何 client_id
授权 客户端发送 response_type=code、一个 redirect_uri、一个至少包含 8 个字符的 state,通常还会发送 PKCE code_challenge。这些参数会与 state 关联存储,浏览器随后会被发送到同意页面。该记录会在 10 分钟后过期。
同意 同意页面要求用户登录 Docsbook 帐户并进行明确点击。页面包含一个复选框——允许编辑文档——由此决定作用域。不存在“记住此客户端”的 Cookie,也没有静默重新批准路径:每次授权都会显示该页面。
令牌交换 代码会在令牌端点处交换为 Bearer 令牌。当客户端提供了使用方法 S256 的 PKCE 挑战时,系统会验证校验器,若不匹配则拒绝请求。代码只能使用一次:首次成功交换时即会被清除。

已发布的元数据声明采用公共客户端模型——code_challenge_methods_supported: ["S256"]token_endpoint_auth_methods_supported: ["none"]grant_types_supported: ["authorization_code"]。不存在客户端密钥,也不支持客户端凭据授权。

令牌是什么#

令牌是来自平台 CSPRNG 的 48 字节数据,以 96 个十六进制字符的形式呈现。它不包含任何声明:它只是指向一行记录的查找键,该记录保存了账户、作用域和撤销时间戳。

  • 它不会过期。 不会返回 expires_in,也不会签发刷新令牌。令牌在被撤销前一直有效。
  • 撤销会立即生效。 从面板撤销后,系统会为该记录加盖时间戳,之后的每次调用都会在查找时失败——前面没有缓存层。
  • 它以签发时的形式存储,而不会进行哈希处理。 请像对待密码一样对待 Docsbook MCP 令牌:如果持有它的机器遭到入侵,应将其撤销,而不要假设它会自行失效。(静态加密的内容列于离开工作区的内容下。)
  • 每次调用都会记录最后使用时间,因此未使用的令牌也会显示在面板的令牌列表中。

每个范围可以执行的操作#

范围是一个进行精确比较的单一字符串。任何不是写入范围的值都会被视为只读值——无法识别的值默认拒绝。

调用方 可执行的操作
无令牌、无范围的端点 什么也不能做。使用发现标头的 401
无令牌、仓库范围的端点(/{owner}/{repo}/api/mcp/server 五个工具:get_infofind_skillfind_widgetlist_content_widgetssearch,作用于那个已发布的网站。永远不计量,永远不向任何人收费。
只读令牌 所有报告、搜索、大纲、分析和调用历史工具,以及 list_memory —— 并且目前还包括下方列出的设置写入工具
读写令牌 账户可以执行的所有操作

范围检查目前并未涵盖所有写入工具,你应据此进行规划。它只对四个工具强制执行:write_docscreate_issueconnect_sourceconfigure_source。这些工具会在执行任何操作前拒绝只读令牌。

其他所有会改变状态的工具——update_*set_* 设置写入工具、update_access、webhook 注册和移除、目标与漏斗创建、翻译上传、审批和删除、create_workspace——仅由项目所有权控制,而不受范围控制。因此,只读令牌可以更改其账户所拥有项目的设置、启用 webhook,或删除该项目中的翻译。但它仍无法提交页面、提交问题、连接来源或启用代理。

将只读范围视为“无法发布或接入新能力”,而不是“无法更改任何内容”。如果隔离比这更重要,请使用一个单独的 Docsbook 账户,该账户只拥有你愿意公开的项目。这是一个缺陷,在限制部分会再次列出,而不是设计如此。

强制执行检查的工具会向只读令牌返回结构化的 READ_ONLY_TOKEN 错误,其中会指出工具名称并说明如何重新授权——不是一个单独的 403,也不是静默无操作。当项目余额为空时(INSUFFICIENT_BALANCE,其中会指出项目、价格和剩余金额),以及计划不包含相应能力时(PLAN_RESTRICTION,其中会指出层级),也会采用相同的结构。

匿名的 search 是唯一一个无需令牌即可读取项目的工具,它会在三种情况下被拒绝:端点未绑定任何项目时、项目可见性为私有时(这也涵盖计划失效的情况),以及项目没有剩余余额来支付查询嵌入时。它不接受项目参数,因此始终只能读取其所绑定的网站。

单个令牌无法触及的内容#

每个工具都会根据显式的 workspace_idrepo 参数或端点自身的固定值来解析目标工作区,而在这三种情况下,查找都会受令牌所属账户的限制。该账户不拥有的工作区会被解析为空,工具则会回答“未找到工作区”。计费解析器也应用相同的过滤条件,因此指定他人项目的 id 同样无法扣用他人的余额。

还有两个值得说明的边界,因为它们常常令人意外:

  • write_docs 使用 Docsbook 自己的 GitHub 凭据向 Docsbook 托管的仓库提交。 来自你自己的 GitHub 账户中某个仓库的网站会被拒绝,并返回 NO_GITHUB_ACCESS,而不会提交到该仓库。因此,MCP 令牌并不是向你的 GitHub 组织推送内容的方式。
  • 以审计模式运行的技能无法执行变更。 当一个 audit 模式的技能处于活动状态时,显式的写入工具列表,以及所有名称以 update_set_register_webhook_enable_disable_ 开头的工具,都会在执行前被拒绝。过去用于为一次完整的服务器端运行设置该模式的运行器已于 12.09.2026 移除,因此现在该保护机制只保护预加载了一个 audit 技能且没有其他内容的轮次。

记录了什么#

每次 MCP 调用(无论是否计量、是否成功)都会向项目的调用记录中写入一行,项目所有者可以在 Feeds 面板中读取这些记录。

已记录 未记录
工具名称、计费类别、价格、实际扣除的分数、持续时间、成功标志、后台运行 ID,以及请求者(代理、面板、计划任务、事件) 调用者的 IP 地址
调用的参数及其结果,经过序列化、脱敏和截断处理 原始负载 — 仅存储经过脱敏和截断的呈现内容
发起调用的账户以及调用所针对的项目 键名中包含 apikeyapi_keyauthorizationcredentialpasswordpasswdsecrettokenprivate_keyprivatekeysessioncookie 的任何值

脱敏处理中有两个细节对审查很重要。它匹配的是,匹配时不区分大小写并按子字符串匹配,而不是根据值的形状匹配 — 猜测机密内容的外形会遗漏某些情况。并且它不仅在传入时运行,也在传出时运行,因此会回显自身输入的工具无法通过其结果泄露密钥。每一侧都会在 8 000 个字符处截断,并附带一个标记,说明删除了多少字符。

读者级分析不会向 MCP 客户端传递身份信息。访客使用的是一个伪名:sha256(salt | repository | ip),截断为 16 个十六进制字符,盐值由服务器端持有。get_top_visitorsget_page_journeysget_visitor_activity 会返回该伪名、国家/地区以及页面级事件;没有任何工具会返回 IP 地址、姓名或电子邮件地址。该伪名限定于单个代码库,因此同一位读者访问你的两个站点时,会对应两个互不相关的 ID。

哪些内容会离开您的工作区#

数据 去向 静态加密
页面文本、标题和页眉 复制到 Docsbook 的 Postgres 中用于全文搜索,并嵌入为向量用于语义搜索 否 — 作为内容存储
发送用于嵌入、聊天和代理处理的页面文本 OpenRouter、使用 Docsbook 的密钥或您设置的自有密钥所对应的模型提供商 不适用 — 仅在传输过程中
读者事件 Docsbook 的分析存储,包括原始 IP(任何 API 都不会返回这些 IP) 不适用
用于私有文档的 OIDC 客户端密钥 Docsbook 的 Postgres — AES-GCM,密钥由平台密钥派生
您为私有仓库源连接的 GitHub 令牌 Docsbook 的 Postgres — 使用相同方案;API 只会回答令牌是否存在
您自己的模型 API 密钥(自带密钥) Docsbook 的 Postgres,以及每次使用该密钥付费调用的提供商 否 — 按原样存储,并从 API 返回的每个工作区负载中剥离
MCP Bearer 令牌 Docsbook 的 Postgres 否 — 见上文
fetch_urlread_source 和爬虫获取的页面 发送到您指定的地址 不适用

以下是对文档供应商安全页面通常提出的两项声明的更正:

  • “您的内容永远不会离开您的仓库”在这里并不属实。 Docsbook 会存储页面文本的可搜索副本及其向量嵌入,并将页面文本发送给模型提供商,以构建这些嵌入以及响应聊天和代理调用。确实如此的是,GitHub 仍然是事实来源,因此停止付费会停止按量计费的工作,但不会删除您的 Markdown。
  • 出站获取受到防护,而不仅仅是被信任。每次获取之前都会检查方案、解析主机名,并拒绝解析到私有或保留地址范围的地址;每次重定向跳转都会重新执行检查,因此公共 URL 无法跳转到内部 URL。robots.txt 会被遵守,并且响应大小受到限制。技能获取器的范围更加狭窄:它只会从目录自身的主机和路径前缀获取内容,因此无法被变成任意 URL 代理。

Webhook 与聊天钩子并不是一回事#

出站 webhook 传送经过签名。该签名是对 所发送的确切字节 计算的 HMAC-SHA256,位于 X-Docsbook-Signature-256: sha256=<hex> 中,并与 X-Docsbook-Event 一同发送。Discord 或 Slack 的入站 webhook URL 会在签名前针对相应平台进行重塑,因此签名始终涵盖你的端点实际接收到的内容。密钥在注册时设置,长度至少为 16 个字符,此后绝不会以明文形式返回。传送尝试会在 15 秒后超时,响应会以截断形式存储。

聊天钩子不携带签名。文档助手的前置、后置和流式钩子是普通的 JSON POST,超时时间为 5 秒,且没有 HMAC 标头。不要在此处重复使用 webhook 验证代码,并假定它验证了某些内容。前置钩子还可以返回 inject_context,其文本会进入助手的提示词——因此,你将聊天钩子指向的端点可以影响助手的回答,所以应将其视为受信任的基础设施,使用其他方式对其进行身份验证,并且不要将其指向你无法控制的 URL。

为什么这是正确的做法(证据)#

Docsbook 遵循的规则 这对使用它的对象为何重要 来源
自行生成不透明令牌;绝不接受或转发由其他方签发的令牌 “MCP 服务器不得接受任何并非明确为该 MCP 服务器签发的令牌” MCP 安全最佳实践,令牌透传
使用 WWW-Authenticate 响应未认证调用,并指明受保护资源元数据 “MCP 服务器必须实现 OAuth 2.0 受保护资源元数据(RFC9728)” MCP 授权
在令牌端点验证 PKCE S256 验证器,并发布 code_challenge_methods_supported “如果缺少 code_challenge_methods_supported,则授权服务器不支持 PKCE,MCP 客户端必须拒绝继续” 授权安全注意事项
每次授权都显示同意页面,而不是记住某个客户端 混淆代理攻击通过到达一个被跳过的同意页面来实现:“存在 Cookie,跳过同意” MCP 安全最佳实践,混淆代理
将 scope 保持为两个由用户选择的范围,而不是客户端请求的范围目录 糟糕的范围设计意味着“攻击面扩大:被窃取的广泛令牌会启用无关的工具/资源访问权限” MCP 安全最佳实践,范围最小化
拒绝解析到的私有或保留 IP,并在每次重定向时重新检查 客户端和服务器应当阻止“链路本地地址:169.254.0.0/16(包括云元数据端点)” MCP 安全最佳实践,SSRF
将每个工具的目标绑定到调用者的所有权,而不是绑定到调用者提供的 ID 服务器“不得将持有状态句柄视为身份验证”,并且应将状态绑定到已验证的主体 MCP 安全最佳实践,状态句柄劫持
审查代理加载的技能,包括我们的技能 “从外部 URL 获取数据的技能尤其存在风险,因为获取的内容可能包含恶意指令” Anthropic,代理技能

还有一点属于你的客户端,而不是我们:MCP 规范要求客户端“除非工具注释来自受信任的服务器,否则应将其视为不可信”,并“让人类参与其中,且能够拒绝工具调用”(MCP 工具)。可读写的 Docsbook 令牌正是值得让人类参与的情况。

Docsbook 当前不符合 MCP 规范的方面#

这些内容以 2026-07-28 修订版为基准。每一项都是 Docsbook 的缺口,而非对规范的异议。

要求 Docsbook 的行为 对审查者的重要程度
“授权服务器必须根据预注册值验证精确的重定向 URI” 验证 redirect_uri协议方案 是否在允许列表中——HTTPS、回环地址以及固定的编辑器深层链接方案列表——由于客户端不会持久化,在交换时不会将其与已注册值进行比较 这是首先应提出的一项。结合不显示重定向目标的同意屏幕,点击精心构造链接的用户可能会批准一个最终落到其他位置的授权。该屏幕确实每次都要求用户主动点击;无法跳过。
授权服务器应当签发短期访问令牌,并为公共客户端轮换刷新令牌 签发没有过期时间且没有刷新令牌的令牌 泄露的令牌会一直有效,直到有人将其撤销
服务器必须“限制工具调用的速率” 不进行速率限制。项目余额是唯一的限制因素,而未计量的发现调用完全没有任何限制 应以金钱而不是请求次数来评估风险预算
授权码中的 PKCE 当客户端使用方法 S256 提供质询时会进行验证;未提供质询的客户端仍可完成流程 所有主流 MCP 客户端都会发送 PKCE;服务器目前并不强制要求
协议修订版 服务器通过无状态 HTTP 传输,使用当前 SDK 支持的基于初始化的修订版,最新版本为 2025-11-25 仅支持 2026-07-28 的客户端无法连接
WWW-Authenticate 质询中的 scope 和元数据中的 scopes_supported 两者都未发布;作用域在同意屏幕上选择 客户端无法以编程方式发现这两个作用域

Docsbook 目前尚不具备的功能#

列出这些内容,是为了让评审能够在一小时内,而不是第三周时,排除 Docsbook。

功能 状态
SOC 2 Type II 不提供 — 没有可供分享的报告
数据处理协议 不提供 — 目前没有双方签署的数据处理协议
合同服务级别协议 不提供
用于登录 Docsbook 的 SAML SSO 不提供 — 账户登录使用 GitHub OAuth
团队账户、角色、RBAC 不提供 — 访问权限按账户设置,任何能够登录某个账户的人都可以执行该账户能够执行的所有操作
账户事件审计日志 不提供 — 登录、令牌签发和计划变更不会作为事件日志公开。MCP 工具调用会被完整记录,并按项目分别记录;内容提交可通过变更历史读取
渗透测试报告 不提供

有一项功能经常与第二行和第四行混淆:在所有计划中,私有工作区都可以通过密码或你自己的 OIDC 提供商,经由 update_access 进行保护。这是为你的文档网站的读者提供的单点登录。它不是为你的 Docsbook 账户成员提供的单点登录,也不会授予 MCP 访问权限。

如果你的组织需要某项特定材料 — GDPR 数据处理协议、BAA 或已完成的问卷 — 请写信至 support@docsbook.io,询问现有哪些材料。今天得到的答复很可能是:目前没有。

限制与未决问题#

  • 托管区域尚无定论。 本页面有意不说明数据库或分析存储所在的区域。两者都是托管服务,其区域属于部署设置,读者无法仅凭 Docsbook 的行为进行验证;而且本页面的早期版本在没有来源的情况下列出了区域。如果数据驻留是您审核的一部分,请向支持团队索取当前的书面答复。
  • 假名访客 ID 是假名化标识,而非匿名化标识。 它是经过加盐处理并截断为 64 位的 IP 地址哈希。任何同时持有盐值和原始事件存储的人都可以重新推导出该 ID;其保证在于盐值不包含在数据中,且没有任何 API 返回 IP。是否满足您的监管机构要求,应由您的监管机构决定。
  • 读写令牌是完整的管理凭据。 无法授予“可以编辑页面但不能更改设置”的权限,也无法授予“可以读取分析数据但不能读取聊天记录”的权限。权限范围层级只有两档。
  • 只读权限范围的强制执行并不完整。 有八个工具会检查该权限;设置、Webhook、目标和翻译写入工具不会检查,而且其中一些工具自身的描述声称需要读写令牌,实际上却没有任何检查。在这一问题解决之前,可靠的边界是账户所有权,而不是权限范围——因此请按账户隔离,并参阅上方列出的已强制执行项目,而不要仅依据工具描述。
  • 这里没有任何内容经过独立鉴证。 上述每一项陈述都可以通过 Docsbook 的行为进行检查——签发一个只读令牌,观察写入工具拒绝操作;连接一个您不拥有的项目,观察它无法解析——但没有任何第三方对其进行审计。请将本页面视为可供测试的规范,而不是认证声明。
  • 可用性和价格请参见定价页面 此处不提供任何具体数字,因为写入文档中的价格会在不知不觉中变得过时。
  • MCP 服务器 — 工具本身,以及一次调用所依据的内容
  • 面向代理的内容 — 四个机器接口,以及它们如何协同工作
  • 文档技能 — 技能运行时能够做什么以及不能做什么
  • Webhook — 完整的事件架构和签名验证
  • AI 聊天钩子 — 未签名的前置/后置/流式钩子
  • 来源 — 代理可以代表你读取哪些内容

Updated

此页面对您有帮助吗?