每个浏览器 IDE 最终都会面对同一个问题:密钥放在哪里?项目需要 API 端点,AI 面板需要提供商密钥,部署需要账户令牌。在桌面环境中,这些值可以放在 shell 配置文件或未被跟踪的文件里。在浏览器标签页中,边界不同。随页面一起发送的内容可以被页面读取,保存在浏览器配置文件中的内容属于该配置文件。本指南给出一个实用模型:哪些值可以公开,哪些绝不能到达客户端,GB Coder 如何处理提供商凭据,以及密钥泄露后该怎么办。它面向希望享受浏览器 IDE 便利、又不把标签页当成秘密保险箱的人。
1. 浏览器标签页是公开的构建目标
第一条规则令人不适但很简单:静态 Web 应用无法保存秘密。浏览器下载 HTML、CSS 和 JavaScript,然后在用户的机器上执行。任何人都可以打开 DevTools、查看网络面板、搜索打包文件,或者设置断点检查变量。压缩代码、拆分成块、把值藏进配置文件,改变的只是难度,不是结果。浏览器 IDE 为运行项目代码增加了沙箱,但 IDE 自身的界面仍运行在同一源上,必须读取它运行所需的内容。沙箱不是界面自身所用值的保险箱。有用的判断标准很直接:如果标签页中运行的代码必须能访问某个值,就假定使用标签页的人也能读取它,并假定同一源上运行的任何脚本也能读取它。这并不意味着浏览器开发不安全,而是在定义边界。公开标识符可以放在那里,服务器凭据不行。
2. 静态应用中的环境变量意味着什么
在 Node.js 服务器中,环境变量在运行时从进程中读取。在 Vite、Create React App、Next.js 或 Astro 的构建中,公开环境变量的工作方式不同:打包器在构建时把引用替换为字面量字符串。Vite 通过 import.meta.env 暴露带 VITE_ 前缀的变量;Create React App 使用 REACT_APP_;Next.js 使用 NEXT_PUBLIC_;Astro 使用 PUBLIC_。前缀是命名约定,不是安全控制。值一旦被内联,就会成为每位访客下载的 JavaScript 的一部分。没有公开前缀的变量通常无法被客户端代码使用,因此仅限服务器的值必须由服务器或无服务器函数读取,而不是由静态页面读取。.env 文件是开发和构建的输入,不是运行时秘密存储。它适合本地配置和让值远离版本控制,但不会在构建后让值变为私有。
# Safe to expose: a public endpoint
VITE_API_URL=https://api.example.com
# Never expose: keep this on a server
STRIPE_SECRET_KEY=REPLACE_WITH_SERVER_SECRET 3. 哪些密钥可以放在浏览器中
有些密钥本来就是公开的。Stripe 可发布密钥用于标识账户并创建支付令牌;秘密密钥真正移动资金,必须留在服务器上。Supabase anon 密钥只有在行级安全策略正确时才安全。Firebase Web 配置标识项目,但不授予管理访问权限。地图和分析密钥通常按域名或 API 限制。这些值可以发送到浏览器,但仍需要限制:允许的来源、API 限制、最小权限角色、配额和告警。相反的类别更容易说明。服务角色密钥、数据库密码、SMTP 凭据、签名密钥和 AI 提供商的私钥绝不能出现在静态打包文件中。属于应用本身的提供商密钥尤其危险:任何找到它的人都能花应用的钱。属于用户的密钥是另一种情况。它仍是 bearer 凭据,但归用户所有,目标是把它留在用户的浏览器中,而不是项目或仓库里。
4. GB Coder 如何处理提供商凭据
GB Coder 的 AI 面板采用 bring-your-own-key 模式。密钥管理器默认将提供商密钥保存在内存中,不写入 localStorage。用户可以明确选择持久化到 sessionStorage,这会把值限制在当前标签页,通常会在标签页关闭时清除。用户清除密钥时,它会从内存和会话存储中移除。管理器还会把每个密钥绑定到已授权的端点源,出站网关会检查凭据不会被发送到未获批准的目标。提供商错误会经过脱敏层,在消息到达界面或日志之前移除密钥模式和活动密钥。自定义提供商元数据保存在 localStorage 中,但标记为秘密的请求头会在持久化前被清除,必须重新输入。请求直接从浏览器发往提供商的端点;GB Coder 不会通过 LadeStack 服务器代理密钥。这些措施减少了意外持久化和跨源泄露,但不会改变基本规则:任何能在同一源上运行的脚本,都能读取页面能读取的内容。处理敏感工作时使用干净的配置文件,不要安装不受信任的扩展程序。
5. 项目秘密、.env 文件与构建时内联
把秘密留在项目目录之外。将 .env 及其本地变体加入 .gitignore,并提交只含占位符名称的 .env.example。如果项目使用 Vite,请记住每个 VITE_ 变量都会被内联到生产打包文件中。本地开发时方便的值,一旦用于生产构建就会公开。部署前检查生成的资源中是否有密钥模式,发现后要当作事件处理,而不是警告。GitHub 的秘密扫描和推送保护可以捕获一些已知令牌格式,但它们只是兜底,不能替代把值留在仓库之外。浏览器 IDE 的 ZIP 导出包含项目文件。如果项目中有 .env 文件,它会随备份一起移动。备份不是加密保险箱。把导出文件存放在私密位置,并在不再需要时删除旧副本。截图、问题报告和聊天消息也是如此:粘贴到其中任何一个地方的密钥都已经离开了浏览器。
# .gitignore
.env
.env.local
.env.*.local 6. GitHub 令牌与部署令牌
GitHub 个人访问令牌和部署令牌比看起来更强大。带有 repository 和 workflow 范围的经典令牌可以读取私有代码、修改文件并触发发布。优先使用细粒度令牌,限定单个仓库、明确的权限列表和到期日期。只给令牌分配任务所需的权限:同步只需要 contents 读写,不需要 administration 或 billing。为不同设备或用途创建不同令牌,完成后撤销。Vercel 或 Netlify 的部署令牌可以发布、替换或删除项目。如果提供商支持项目或团队范围,就使用它;如果支持过期时间,就设置一个。只在需要时把令牌粘贴到部署面板,不要把它保存在项目文件中。在 CI 中,使用仓库或组织秘密,而不是提交 .env,并记住来自 fork 的 pull request 通常不会获得秘密。被截图、在聊天中分享或提交到公开仓库的令牌,即使在下一秒删除,也应视为已泄露。
7. AI 提供商密钥:没有意外的 BYOK
AI 提供商密钥是附带账单的 bearer 凭据。任何持有它的人都可以发送请求、消耗配额并产生费用。使用限定到项目的密钥,在提供商支持时设置支出上限,并使用单独的实验密钥而不是组织的主密钥。定期检查用量,尤其是在共享设备或安装新扩展程序之后。Ollama、LM Studio 和 vLLM 等本地提供商不需要云密钥,但它们的端点仍是机器上的服务。不要为了让演示运行就把本地端点暴露到公网。如果自定义提供商指向代理,代理可以看到密钥;只使用你控制并理解的代理。提示注入是相关风险:文件、网页或粘贴的错误消息可能包含针对助手的指令。把秘密留在提示之外,也不要放进允许助手读取的文件中。如果密钥出现在对话中,请轮换它。
8. 共享电脑、扩展程序与 XSS
共享或实验室电脑需要不同的流程。使用私密浏览器配置文件,不要选择会话持久化,完成后关闭标签页。如果浏览器提出保存密钥,请拒绝。如果怀疑密钥被保留,清除站点存储。浏览器扩展也是边界的一部分:拥有广泛主机权限的扩展通常可以读取页面内容或存储,恶意更新也可能在安装后到来。处理凭据时使用最小化配置文件。在这种场景下,跨站脚本是典型的 Web 风险。如果攻击者能在 IDE 的源上运行脚本,该脚本就能读取 localStorage 和 sessionStorage,并在页面打开期间发送请求。保持依赖更新,避免不受信任的第三方脚本,并考虑在部署站点上使用内容安全策略。剪贴板管理器和屏幕共享工具也会看到你复制和显示的内容。移动密钥后清除剪贴板,在打开提供商设置面板前暂停共享。
9. 轮换泄露的密钥
轮换是应对密钥泄露的唯一可靠方法。先撤销很重要:如果在准备新密钥时旧密钥仍然有效,暴露就会继续。用最窄的可用范围创建新密钥,更新应用或浏览器设置,如果该值是构建的一部分就重新部署,并验证旧密钥已被拒绝。然后检查提供商的使用量和审计日志,寻找意外活动。如果密钥已提交到 Git,仅仅删除文件是不够的,值仍留在历史中。先轮换,再用 git filter-repo 或 BFG 等工具重写历史,与团队达成一致后强制推送,并请协作者重新克隆。托管平台可能缓存旧构建,因此要确保旧值无法从过时的打包文件中提供。如果密钥被粘贴到 AI 聊天、支持工单或截图中,假定它已被保留并轮换。最后,记录发生了什么,添加本可以捕获它的检查,并缩短下一个密钥的有效期。
10. 实用检查清单
在项目离开浏览器之前,按这个顺序检查。第一,对每个值分类:公开标识符、用户凭据或服务器秘密。第二,把服务器秘密留在静态打包文件之外,放到无服务器函数或 API 后面。第三,只暴露需要公开前缀的值,并在部署前检查构建产物。第四,让 .env 文件远离 Git,提交 .env.example,并启用秘密扫描。第五,为 GitHub 和托管创建有范围、会过期的令牌,每个用途一个。第六,在 GB Coder 中,除非在可信设备上,否则让密钥留在内存中;只有理解权衡时才选择会话持久化。第七,绝不把密钥粘贴到提示、问题、截图或项目文件中。第八,有任何疑问就轮换,并在替换前撤销。第九,在共享机器上使用干净的浏览器配置文件。第十,在需要之前写下泄露应对计划。只要把浏览器当作公开客户端而不是私人保险箱,浏览器 IDE 就能负责任地处理凭据。