Anthropic Agent 工程实战笔记(六)安全与生产:把 settings 改到 TaoToken 的权限边界实践 1. 生产环境里 Agent 越权写入的真实场景Anthropic Agent 进入生产环境后最容易被低估的风险不是模型答错而是它真的能改文件、跑命令、调接口。我在一个内部代码助手项目里遇到过这样一幕Agent 为了修复一个测试失败把工作目录外的~/.ssh/config读出来贴进了日志虽然没造成泄露但那一刻我意识到——只靠 system prompt 里写不要访问敏感目录等于没设防。这就是本篇要解决的问题Anthropic Agent 安全治理不是加几句提示词而是把权限边界落到 settings 配置、路径白名单、沙箱隔离和可验证的拦截动作上。适合谁已经跑通 Claude Code 或自建 Agent harness、准备上生产或准生产环境的开发者。你需要的不只是能跑而是跑错时影响可控。核心检索词先明确Anthropic Agent 生产安全、settings 权限边界、最小授权、越权拦截验证。这几个词贯穿全文。我试过的教训是权限提示permission prompt只能拦住模型主动询问的场景一旦 Agent 在长任务里连续调用工具人不可能每次都点确认。Anthropic 官方在 sandboxing 那篇工程博客里也讲得很直白——执行能力必须配执行隔离而不是靠 prompt 约束。所以本文的路线是先把执行环境关进沙箱或受控根目录再用 settings 把工具权限收窄最后用一个越权访问的拦截实验证明边界真的生效。下面按问题场景 → TaoToken 前置 → 可复制配置 → 验证请求 → 常见报错 → 下一步推进。每一段都给可跟做的命令和配置不写空泛原则。2. TaoToken 前置把模型入口和权限入口分开管在讲权限边界之前得先把模型调用这条链路理清楚。很多人的 Agent 项目里模型 Key 和工具权限混在一个配置文件里结果一出问题不知道是模型侧还是执行侧。我的做法是把两者拆开模型走统一的 API 入口权限走本地 settings。模型侧我用 TaoToken 作为统一入口官网是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 地址是 https://taotoken.net/api 。它的价值在于Agent 里可能同时用到 Claude 系列和其他模型做评测对比统一 Base URL 后切换模型只改 Model ID不用动鉴权逻辑。这对安全治理很关键——密钥只在一个地方管泄露面就小。具体操作上你需要在控制台创建 API Key。入口在 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite Key 管理页在 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 。创建后立刻做两件事一是把 Key 写进环境变量而不是代码二是给它起个能追溯用途的名字比如agent-prod-readonly。这里有个权限思路要提前建立模型 Key 的权限 ≠ 工具权限。Key 决定 Agent 能调用哪个模型settings 决定 Agent 能碰哪些文件和命令。两者独立收窄才是最小授权。如果你还在用 Claude Code 形态可以先用模型对话页 https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel_chatutm_campaignrewrite 验证 Key 是否可用再去配 settings。环境变量这样设Linux/macOSexport TAOTOKEN_API_KEYsk-你的key export ANTHROPIC_BASE_URLhttps://taotoken.net/apiWindows PowerShell$env:TAOTOKEN_API_KEYsk-你的key $env:ANTHROPIC_BASE_URLhttps://taotoken.net/api注意 Base URL 不要带 UTM 参数鉴权只认域名和路径。Key 不要提交到 git.env加进.gitignore。这一步做完模型入口就固定了接下来所有权限配置都围绕这个入口能触发哪些本地动作来收。3. 可复制配置settings 权限边界与路径白名单这一节是全文核心给可直接复制的配置片段。Anthropic Agent 的权限边界主要落在两类文件Claude Code 的settings.json以及自建 harness 里的工具白名单。两者思路一致——默认拒绝显式放行。先看 Claude Code 的 settings。路径按你的系统来macOS/Linux 是~/.claude/settings.json项目级是项目根目录的.claude/settings.json。项目级优先级更高生产环境建议用项目级跟着仓库走。{ permissions: { allow: [ Read(./src/**), Read(./tests/**), Edit(./src/**), Bash(python -m pytest:*), Bash(git status:*), Bash(git diff:*) ], deny: [ Read(./.env), Read(./secrets/**), Read(~/.ssh/**), Read(~/.aws/**), Bash(curl:*), Bash(rm -rf:*), Bash(git push:*), WebFetch ], ask: [ Bash(git commit:*), Edit(./package.json) ] } }这份配置的逻辑allow只放读源码、跑测试、看 git 状态这类低风险动作deny把密钥文件、云凭证、外发网络请求、删除命令、推送全部堵死ask留给需要人工确认的提交和依赖变更。注意deny优先级最高即使某个路径被allow覆盖只要命中deny就拒绝。如果你用 Codex 形态配置在~/.codex/auth.json和项目级config.toml。三件套要写全Base URL、Key、Model ID。# ~/.codex/config.toml model claude-sonnet-4-5 model_provider taotoken [model_providers.taotoken] name TaoToken base_url https://taotoken.net/api env_key TAOTOKEN_API_KEYauth.json里只放 Key 引用不要硬编码{ OPENAI_API_KEY: null, TAOTOKEN_API_KEY: env:TAOTOKEN_API_KEY }自建 harness 的话路径白名单用代码兜底。下面这个函数在每次工具调用前校验路径不在允许根下直接抛错import os def resolve_in_allowed_root(path: str, allowed_roots: list[str]) - str | None: abs_path os.path.realpath(os.path.abspath(path)) for root in allowed_roots: abs_root os.path.realpath(root) if abs_path abs_root or abs_path.startswith(abs_root os.sep): return abs_path return None allowed [/workspace, /tmp/agent] p resolve_in_allowed_root(src/main.py, allowed) if p is None: raise PermissionError(Path not under allowed roots)realpath会解析符号链接防止用软链接绕过白名单。Windows 下把根换成C:\\workspace这类实际路径。这套配置和 settings 是互补的settings 管 Claude Code 内置工具代码白名单管你自定义的工具。4. 验证请求一次越权访问的拦截实验配置写完不算数得证明边界真的拦得住。这一节做两个验证先确认模型调用通再确认越权被拦。第一步验证 TaoToken 入口可用。用 curl 发一个最小请求curl https://taotoken.net/api/v1/messages \ -H x-api-key: $TAOTOKEN_API_KEY \ -H anthropic-version: 2023-06-01 \ -H content-type: application/json \ -d { model: claude-sonnet-4-5, max_tokens: 64, messages: [{role: user, content: reply with ok}] }返回里能看到content字段和ok就说明 Key 和 Base URL 都对。如果报 401先查 Key 有没有多余空格再查环境变量有没有 export 成功。第二步越权拦截实验。在项目里放一个敏感文件secrets/token.txt内容随便写。然后让 Agent 执行读取 secrets/token.txt 并打印。按上面的 settingsRead(./secrets/**)在 deny 列表里预期结果是拒绝而不是读出内容。如果你用自建 harness直接调白名单函数验证try: resolve_in_allowed_root(secrets/token.txt, [/workspace]) except PermissionError as e: print(BLOCKED:, e)预期输出BLOCKED: Path not under allowed roots。这一步的意义在于拦截发生在工具执行前而不是模型决定不读。即使模型被诱导去读执行层也会挡住。再补一个沙箱自检确认 Agent 跑在隔离环境里import os def in_docker() - bool: try: with open(/proc/1/cgroup, r) as f: return docker in f.read() or containerd in f.read() except FileNotFoundError: return False print({cwd: os.getcwd(), in_docker: in_docker()})in_docker为 True 说明在容器内影响范围被限制在容器里。Windows 没有/proc/1/cgroup改用检查工作目录是否在预期根下即可。三个验证都过权限边界才算落地。5. 本篇常见错排查401、local proxy failed 与 reading choices配置和验证过程中报错集中在几类。逐个对照。401 Unauthorized。最常见原因是 Key 没生效。检查顺序echo $TAOTOKEN_API_KEY看有没有值确认请求头用的是x-api-key而不是Authorization: BearerAnthropic 协议用前者确认 Base URL 是https://taotoken.net/api且没拼错。如果 Key 是从控制台复制的注意别把前后空格带进去。local proxy failed / connection refused。这类报错通常不是 Key 问题而是本地网络或代理配置。先确认ANTHROPIC_BASE_URL没被其他工具覆盖再检查有没有残留的HTTP_PROXY环境变量指向一个已经关掉的本地端口。清掉即可unset HTTP_PROXY HTTPS_PROXY ALL_PROXYreading choices of undefined。这个报错说明返回体结构和代码预期不一致多半是 Model ID 写错或协议不匹配。Anthropic 协议返回的是content数组OpenAI 协议才是choices。如果你用 OpenAI SDK 去调 Anthropic 端点就会读到 undefined。解决方法是统一协议要么用 Anthropic SDK要么确认 TaoToken 的兼容端点路径。OAuth / auth.json 相关报错。Codex 形态下如果auth.json里写了env:TAOTOKEN_API_KEY但环境变量没设会报鉴权失败。确认三件套齐全Base URL、Key、Model ID。缺任何一个都会在启动时或首次请求时报错。权限配置不生效。settings.json 改了但 Agent 还是能读敏感文件检查两点一是文件路径对不对项目级.claude/settings.jsonvs 用户级~/.claude/settings.json二是 JSON 有没有语法错误用python -m json.tool settings.json校验一下。deny 规则写错一个字符就可能整条失效。排障时建议开 verbose 日志把实际请求的 URL、Header、返回码打出来比猜快得多。接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 里面有各协议的端点说明对照着查。6. 下一步把安全基线接进长期编码流程权限边界配好只是起点。生产环境还需要持续跑质量评测、监控变更影响、保留用户反馈通道。如果你要把这套安全基线用在长期编码或 Agent 任务里建议走 Coding Plan入口在 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite 它更适合持续性的编码场景Key 和额度管理也更集中。如果你还在验证模型能力阶段先用模型对话页 https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel_chatutm_campaignrewrite 跑几个真实任务确认模型输出符合预期再把它接进带权限边界的 harness。Claude Code 形态的接入参考 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentclaudecodeutm_campaignrewrite 里面有 settings 和工具权限的完整说明。最后给一个我实际在用的习惯每次改完 settings先跑一遍越权拦截实验确认 deny 规则生效再让 Agent 接真实任务。配置漂移是安全治理里最隐蔽的坑——某次为了调试临时放开一条规则忘了收回去边界就破了。把验证动作固化成脚本比记在脑子里可靠。