Docsbook
概览

MCP 服务器安全

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

本文不包含任何理想化描述。缺失的控制措施会明确列为缺失。

你将获得什么#

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

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

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

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

身份验证的工作原理#

授权流程#

Docsbook 同时是自己的授权服务器和资源服务器。它为自身签发不透明令牌;绝不接受、转发或重复使用由其他方签发的令牌。

步骤 发生的情况
发现 向服务器端点发送未经身份验证的请求会返回 401,其中包含 WWW-Authenticate: Bearer resource_metadata="…/.well-known/oauth-protected-resource"。该文档指明资源及其授权服务器;/.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 challenge 时,系统会校验 verifier,不匹配则拒绝。代码只能使用一次:首次成功交换时即会被清除。

已发布的元数据声明采用公共客户端模型——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,作用于该唯一已发布的网站。绝不计量,也绝不向任何人收费。
只读令牌 所有报告、搜索、大纲和分析工具,以及 run_docs_analyze;该工具以审计模式运行——并且目前还包括下面列出的设置写入工具
读写令牌 账户可以执行的所有操作

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

其他所有会更改状态的工具——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_ 开头的工具,都会在执行前被拒绝。run_docs_analyze 会为其整个运行过程设置该模式,这也是它可以安全用于只读令牌的原因。

记录了什么#

每次 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 无法跳转到内部地址。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 安全最佳实践,混淆代理
将作用域集合保持为两个,由用户选择,而不是使用客户端请求的作用域目录 糟糕的作用域设计意味着“攻击面扩大:被盗的宽泛令牌会启用无关的工具/资源访问权限” 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 不提供 — 没有可供分享的报告
数据处理协议 不提供 — 目前没有双方签署的 DPA
合同约定的 SLA 不提供
用于登录 Docsbook 的 SAML SSO 不提供 — 账户登录使用 GitHub OAuth
团队账户、角色、RBAC 不提供 — 访问权限按账户划分,任何能够登录某个账户的人都可以执行该账户能够执行的所有操作
账户事件审计日志 不提供 — 登录、令牌签发和套餐变更不会作为事件日志公开。MCP 工具调用按项目完整记录;内容提交可通过变更历史查看
渗透测试报告 不提供

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

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

限制与悬而未决的问题#

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

Updated

此页面对您有帮助吗?