我们如何保护您的 Bot Token
关于您托付给 BotShade 的 Bot Token,我们将坦诚说明它被保管在何处、如何存储、以及我们守护它的边界在哪里。
|
|
最后更新: 2026年6月15日在使用 BotShade 时,您最关心的恐怕就是 Bot Token。一旦泄露,机器人可能被劫持,服务器也可能被破坏。正因如此,我们想坦率地告诉您:我们把它存放在哪里、如何存储、守护的边界在哪里,以及 我们决定不做哪些事。
谈论安全时,如果只罗列结论往往会显得枯燥乏味。本文中,我们会尽量连同 “为什么这样设计” 的思路一起分享。
本文涉及以下内容:
- 究竟什么是 Bot Token
- 当您托付 Token 时会发生什么
- 存储时如何保护
- 不同 Bot 之间如何隔离
- 传输过程中的防护
- 谁能接触到 Token
- 万一出事的应对
- 我们刻意不做的事
- 我们无法覆盖的部分,以及希望您配合的事
究竟什么是 Bot Token
Bot Token 是您在 Discord 开发者门户创建机器人时获得的一串长字符串。它是机器人向 Discord 表明 “我就是这个 Bot” 的凭据,可以理解为 专属于这个机器人的密码。
任何持有该 Token 的人,都能以这个机器人的身份做任何事:发送消息、分配身份组、封禁成员、修改服务器设置——只要在机器人被授予的权限范围内,全部可以做到。这正是 Token 被称为 “Discord 机器人中最敏感的一项信息” 的原因。
使用 BotShade 这类机器人平台,本质上就是把这个 Bot Token 托付给一项服务。想了解它到底经历了什么、是如何被保护的,是非常合理的问题。
当您托付 Token 时会发生什么
当您在控制台粘贴 Token 并点击 “保存” 的那一刻,内部会按以下顺序处理:
- Token 通过 经 TLS 加密的通道 从浏览器发送到 BotShade 的服务器
- 服务器端收到后,会 向 Discord API 发起一次性的查询,确认 Token 是否有效,以及它对应的是哪个机器人
- 确认通过后,Token 当场使用 AES-256-GCM 加密,再写入数据库
- 解密所需的密钥保存在 另一个位置(云端的 Secret Manager),与数据库相隔离
- 留存在内存中的明文 Token,会在请求处理结束后立即销毁
浏览器输入框中显示的 ”●●●●●●“,在保存后便无法再被还原。控制台之后展示的,仅是您本人识别 “这是我的哪个 Bot” 所需的最少信息,通常是 “最后 4 位字符” 等。
存储时如何保护
数据库中存储的所有 Bot Token,都使用 AES-256-GCM 进行加密。AES-256-GCM 是一种内置 篡改检测 机制的认证加密方案,“让数据不可读” 与 “判断是否被改动过” 这两件事,由同一个机制同时承担。
解密所需的密钥,存放在与数据库分离的 云端 Secret Manager 中进行管理。密钥本身也设置为只能从拥有特定权限的运维基础设施中读取。
也就是说,即使有人拿到了数据库的备份,仅凭这一点也无法解密 Token。只有当攻击者同时握住 密文 与 密钥侧的访问权限,才有可能还原出明文 Token。这是典型的 纵深防御 结构——“一层被攻破,仍有下一层兜底”。
技术细节:AES-256-GCM 的认证标签与 nonce
AES-256-GCM 中的 “GCM” 是 Galois/Counter Mode 的缩写,它在加密的同时会生成一段被称为 认证标签 (authentication tag) 的短 MAC。解密时会比对这一标签,只要密文或关联数据中有 1 个比特被篡改,解密就会直接失败。“让数据不可读” 与 “判断是否被改动过” 之所以能由同一个机制同时完成,正是因为这一点。
GCM 要求每条记录使用 唯一的 nonce(仅使用一次的值)。在同一密钥下复用 nonce 会让密码本身的安全性严重崩溃,因此我们为每条记录嵌入了独立且不冲突的 nonce。
此外,我们还会将希望关联的上下文信息作为 AAD(Additional Authenticated Data) 纳入认证范围。这样,“这段密文是否真的属于这个 bot” 之类的上下文错配,也能在解密阶段被检测出来。
不同 Bot 之间如何隔离
BotShade 会在同一个数据库中承载许多用户的机器人。这里关键的性质在于:A 的机器人,永远无法触及 B 的机器人 Token。
我们通过 PostgreSQL 的 Row Level Security (RLS) 在数据库层强制保证了这一点。RLS 是一种机制,将 “哪些行可以被哪些主体看到” 作为数据库侧的策略写入,并在每次查询时自动应用。即便应用层代码出现了某种失误,数据库自身也会判断 “只返回属于您的 Bot 的数据” 并将不属于的部分挡在外面。
之所以特地把隔离放在数据库层而不是应用层,是因为我们 希望从结构上彻底消除 “因代码 bug 或发布事故,不小心看到了别的机器人的数据” 这种事故的可能性。应用代码每天都在变化,而数据库侧的策略则极少调整。把守护的根基放在变化更少的位置,更为安全。
我们还在此之上叠加了复合主键,让 “跨 Bot 引用” 这种查询形态本身,从结构上就无法成立。
技术细节:Row Level Security 的工作方式
PostgreSQL 的 Row Level Security 是一项功能,它允许针对每张表,将 “哪些行对哪个主体可见” 作为数据库侧的策略来声明。每次请求时,应用通过安全的路径告知数据库 “当前的 bot 是谁”,策略便会被自动织入查询中。
哪怕应用层发出的是看似 “全表读取” 的查询,数据库自身也会在背后静默地附加 “只返回当前 bot 拥有的行” 这一过滤条件。这正是把隔离放在 数据库层 而非应用层所带来的效果。
更进一步,我们让应用连接数据库时所用的角色(DB 用户)不具备绕过策略的权限。“无法不小心关闭策略” 是系统的默认状态,而不是每次变更时都要靠人去记的约束。
传输过程中的防护
Token 流转的路径,大致可以分为三段:
- 浏览器 ↔ BotShade 的控制台
- BotShade ↔ Discord
- 内部服务之间的通信
这三段全部使用 TLS 加密。入口由 Cloudflare 作为前置承担,SSL 模式设置为 Full (Strict)。所谓 “Full (Strict)“,是指即便在用户看不见的、Cloudflare 与源站之间的链路上,也用有效证书来保护通信。我们在设计阶段就消除了 “悄悄降级到 HTTP 而导致信息外泄” 的可能性。
在边缘侧,我们启用了 WAF 与 DDoS Protection,明显可疑的请求会在到达应用之前就被丢弃。在此之上,重要的 API 请求还会附加 HMAC 签名,服务器端会在每次处理之前校验 “发送方是否是合法的客户端” 以及 “是否在途中被篡改”。
通信途中的窃听、冒充、篡改——针对这些威胁,我们在不同的层面同时部署了不同的防护措施。
技术细节:HMAC 签名与防重放攻击
对于重要的 API 请求,我们使用共享密钥进行 HMAC-SHA256 签名。客户端会基于请求的关键要素(方法、路径、请求体、时间戳等)生成签名,服务器侧用相同的步骤重新计算。若两者不一致,该请求会被立即拒绝。
签名密钥是 可轮换的,新旧密钥可以在一段时间内并行接受。这样即便怀疑密钥已经泄漏,也能在不中断服务的情况下完成切换。
针对重放攻击——即攻击者将过去的合法请求原样重发——我们将 时间戳 纳入签名对象,服务器侧通过 “拒绝时间戳过旧的请求” 这一阈值来应对。必要时,还会叠加一个短时有效的唯一 nonce,确保即便在阈值窗口内,同一请求的第二次提交也会被挡掉。
谁能接触到 Token
坦白说,我们 基本上不会去接触解密后的 Token。解密路径本身没有被接入日常运维链路,因此无论是控制台开发还是客户支持工作,都不会出现需要面对明文 Token 的场景。我们不想看,也无意去看。
不过,加密状态下的字符串(ciphertext)本身,我们在运维侧出于存储完整性校验或篡改检测的目的,可能需要处理。这是为了在不解密的前提下确认 “是不是同一个值”、“有没有被破坏”,而不是用来窥探其内容。
运维上执行的管理操作都会记录到 审计日志 中。谁、在何时、做了什么,都会留下记录,目前的保留期为 7 天。
万一出事的应对
不存在完美的防御。因此,“事情真的发生时如何处理”,我们认为同样重要。
- 可疑访问、与平常不同的登录尝试模式,都属于我们检测和复盘的对象
- 如果出现 Token 可能泄露的情况,我们会通知受影响的用户
- Token 可以通过控制台 随时重新生成,旧 Token 会被立即作废
- 安全相关的报告请发送至 help@botshade.com。我们会认真对待每一份善意的报告(详情见 负责任的披露 一节)
我们会把 Token 重新生成功能,作为 “紧急出口” 告知用户。一旦感觉哪里不对劲,第一件事就是重新生成、让旧 Token 失效——仅此一步,就能在绝大多数情况下显著遏制损害扩散。
我们刻意不做的事
一个设计的意图,不仅体现在它做了什么,也体现在它 决定不做什么 上。我们在 BotShade 中明确决定 “不做” 的事,例如下面这些:
- 不把 Token 输出到日志中:错误日志、调试日志、指标、链路追踪等,全部都不会留下 Token 本身或它的任何片段
- 不在工单或聊天中向您索要 Token:我们不会因客户支持的需要请您出示 Token。如果您收到了 “请把 Token 发给我” 这样的消息,那不会是我们
- 不在控制台之外展示 Token:无论是邮件、Discord 消息,还是任何外部服务集成,都不会让明文 Token 离开控制台界面
- 不把解密密钥常驻在运维基础设施上:密钥访问被严格收口,只在真正需要时才从受限位置获取,避免 “随手可得” 的状态
这些 “不做的事” 并不只是一纸政策,而是同时落到了代码与运维流程中。
我们无法覆盖的部分,以及希望您配合的事
我们坦诚地告诉您,我们能守护的范围是有边界的。下面这些情况,我们这一侧无法完全覆盖:
- 用户自己不小心把 Token 提交到了公开的代码仓库
- 控制台的登录账号被第三方接管
- 用户自己的设备被恶意软件感染
要降低后两种风险,最有效的请求是 请把控制台的入口加固起来。BotShade 的控制台采用无密码设计,您需要通过 Discord 等外部账号登录,或使用 Passkey 登录。
因此,我们希望您能配合做到以下几点:
- 为用于登录的关联账号(Discord、Google 等)启用双重身份验证 (2FA)。由于 BotShade 自身没有密码,入口的强度,直接取决于您所关联账号的强度
- 如果条件允许,请 注册 Passkey。Passkey 与设备绑定,对钓鱼攻击具有较强的抵抗力
而面对第一种风险(不小心把 Token 提交到公开仓库等),一旦察觉,请立刻前往 Discord 开发者门户,从 “Reset Token” 重新生成新的 Token。旧 Token 会当场失效。把新的 Token 重新注册到 BotShade 控制台后,您的机器人就能继续正常运行。
安全无法只靠我们一方,也无法只靠您一方独自完成。只有两侧都尽到本分,才能让设计真正收敛到 “把损害压到最小” 的状态。我们的那一份,会诚实地坚守下去。