本文讨论了 Cursor Cloud Agents 在自动化执行任务时面临的密钥暴露风险,指出将长期凭证放入 Secrets UI、.env 或快照中都存在旋转困难、审计缺失和泄露面过大的问题。
当你启动一个 Cursor Cloud Agent 任务时——无论是从 IDE、Slack,还是 GitHub webhook——Cursor 都会为这个特定任务启动一个隔离的 Ubuntu VM。它会从快照恢复,按对应分支 clone 你的 repo,然后按顺序运行环境生命周期:
install —— 在快照恢复后运行一次,并会被缓存。可以理解为 npm install 或 pip sync。start —— 每次启动时都会运行,在 agent 开始工作之前执行。这里适合获取 secrets。这个生命周期在项目根目录下的 .cursor/environment.json 中配置。Cursor 还有一个 Secrets UI(Settings → Background Agents → Secrets),会在运行时将键值对作为加密的环境变量注入。
问题在于:Secrets UI 的能力也就到此为止。 它适合少量静态值,但无法处理 rotation、审计轨迹、团队成员之间的访问隔离,或者你对真正的 secrets management 工作流所期待的其他能力。一旦你的 agent 需要做任何有实际意义的事情(比如连接数据库、访问内部服务、安装私有 registry 包),你就会需要一个更可靠的方案。
Cursor 的 cloud agent 环境带来了一些并不总是显而易见的具体问题:
.npmrc 运行 npm install,然后对磁盘做 snapshot,那么这个 token 就会被冻结进镜像里。environment.json 中的硬编码值:这个文件本来就应该提交到你的 repo,所以任何你直接放进 env 字段的敏感信息都是隐患。最简洁的方式是:只把你的 Infisical machine identity 凭证存到 Cursor Secrets UI 中,然后在运行时用这些凭证从 Infisical 拉取其他一切。你的真实 secrets 永远不会接触 Cursor 的存储。
首先,在 Infisical 中创建一个专门面向 agent 环境的 machine identity——只授予它该 agent 所需 secrets 的访问权限,不多不少。
## 使用 Universal Auth 以非交互方式认证
export INFISICAL_TOKEN=$(infisical login \
--method=universal-auth \
--client-id=<identity-client-id> \
--client-secret=<identity-client-secret> \
--silent \
--plain)
将 INFISICAL_CLIENT_ID 和 INFISICAL_CLIENT_SECRET 存入 Cursor Secrets UI。这里只有这两个值会存放在那里——其他所有内容都来自 Infisical。
infisical run - 将 Secrets 直接注入你的进程这是最简单的模式。在你的 start 脚本中使用 infisical run,把 secrets 作为环境变量注入到你启动的进程中。
## .cursor/start.sh
export INFISICAL_TOKEN=$(infisical login \
--method=universal-auth \
--client-id=$INFISICAL_CLIENT_ID \
--client-secret=$INFISICAL_CLIENT_SECRET \
--silent --plain)
infisical run --env=production --projectId=<project-id> -- node server.js
{
"snapshot": "snapshot-...",
"install": "npm install",
"start": "bash .cursor/start.sh"
}
由 infisical run 启动的进程会获得所有 secrets,并以环境变量的形式注入。不会写入磁盘,不会泄露到 snapshot 中,而且凭证会在每次 agent 启动时重新获取。
infisical export - 将 Secrets 写入文件有些工具要求 secrets 以文件形式存在,而不是环境变量——比如 .env 文件、YAML 配置、JSON blob。infisical export 可以处理这种情况。
## 写入 .env 格式
infisical export --env=production --projectId=<project-id> --output-file=.env
## 写入 JSON
infisical export --format=json --env=production --projectId=<project-id> --output-file=./config/secrets.json
## 写入 YAML
infisical export --format=yaml --env=production --projectId=<project-id> --output-file=./config/secrets.yaml
下面是一个适用于 Node 项目的实用 start.sh,它需要在安装依赖之前先写入私有 .npmrc:
##!/bin/bash
## .cursor/start.sh
export INFISICAL_TOKEN=$(infisical login \
--method=universal-auth \
--client-id=$INFISICAL_CLIENT_ID \
--client-secret=$INFISICAL_CLIENT_SECRET \
--silent --plain)
## 为私有 registry 访问写入 .npmrc
infisical export \
--env=production \
--projectId=<project-id> \
--path=/npm-config \
--format=dotenv \
--output-file=.npmrc
echo "Secrets ready"
下面是一个典型 web 项目的完整且安全的 environment.json 配置:
{
"snapshot": "snapshot-20250309-xxxxxxxx",
"install": "bash .cursor/install.sh",
"start": "bash .cursor/start.sh"
}
## .cursor/install.sh
## 进行认证,以便安装私有包
export INFISICAL_TOKEN=$(infisical login \
--method=universal-auth \
--client-id=$INFISICAL_CLIENT_ID \
--client-secret=$INFISICAL_CLIENT_SECRET \
--silent --plain)
## 为私有 registry 写入 .npmrc
infisical export --env=production --projectId=<project-id> --path=/npm-config --output-file=.npmrc
npm install
## .cursor/start.sh
export INFISICAL_TOKEN=$(infisical login \
--method=universal-auth \
--client-id=$INFISICAL_CLIENT_ID \
--client-secret=$INFISICAL_CLIENT_SECRET \
--silent --plain)
sudo service docker start
infisical run --env=production --projectId=<project-id> -- node server.js
Cursor Secrets UI 只保存 INFISICAL_CLIENT_ID 和 INFISICAL_CLIENT_SECRET。其他所有 secret 都会在每次 agent 启动时重新获取,随时可轮换,并且完全可审计。
还有一件值得做的事:不要给你的 agent 一个可以访问所有内容的 machine identity。创建一个专用的 Infisical identity,只授予它访问该 agent task 实际所需 secrets 的权限。
cursor-agent-dev → 仅可访问 /dev secrets
cursor-agent-prod → 仅可访问 /production secrets,需要审批
cursor-agent-ci → 可访问 /ci secrets,只读
这样一来,如果 agent 因 prompt injection 而被入侵——而这对会自动执行终端命令的自主 agent 来说确实是一个真实风险——那么影响范围就会被限制在该 identity 可访问的内容内,而不是整个 secret store。
Cursor Cloud Agents 的强大之处正在于它们可以自主行动,而这种自主性如果不加小心,就会带来真实的凭证暴露风险。把 secrets 烘焙进 snapshots、在 Secrets UI 中存储长生命周期 token,或者在 environment.json 里硬编码值,这些做法最终都会引发问题。
核心原则很简单:在 Cursor 中尽可能少地存储内容,并使用这些最小化凭证在运行时从 Infisical 获取其他一切。每次启动都获取新的 secrets、拥有完整的审计轨迹,并且 rotation 无需触碰环境配置。
- 原文链接: infisical.com/blog/secur...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!