实战笔记:Go 项目 的 安全配置最终版 settings.json
{
"permissions": {
"allow": [
"Read(go.mod)",
"Read(go.sum)",
"Read(Makefile)",
"Read(README.md)",
"Read(CLAUDE.md)",
"Read(constitution.md)",
"Read(spec.md)",
"Read(plan.md)",
"Read(cmd/**)",
"Read(internal/**)",
"Read(pkg/**)",
"Read(testdata/**)",
"Read(*.md)",
"Grep",
"Glob",
"LS",
"Bash(go version:*)",
"Bash(go env:*)",
"Bash(go list:*)",
"Bash(go test:*)",
"Bash(go vet:*)",
"Bash(go build:*)",
"Bash(gofmt:*)",
"Bash(goimports:*)",
"WebFetch(domain:pkg.go.dev)",
"WebFetch(domain:golang.org)",
"WebFetch(domain:go.dev)",
"WebFetch(domain:github.com)"
],
"deny": [
"Read(.env)",
"Read(.env.*)",
"Read(**/.env)",
"Read(**/.env.*)",
"Read(~/.ssh/**)",
"Read(/etc/passwd)",
"Read(/etc/shadow)",
"Bash(rm:*)",
"Bash(sudo:*)",
"Bash(chmod:*)",
"Bash(chown:*)",
"Bash(curl:*)",
"Bash(wget:*)",
"Bash(nc:*)",
"Bash(ssh:*)",
"Bash(scp:*)",
"Bash(rsync:*)",
"Bash(docker:*)",
"Bash(kubectl:*)",
"Bash(git push:*)",
"Bash(git tag:*)",
"Bash(git reset:*)",
"Bash(git rebase:*)",
"Bash(git clean:*)"
],
"ask": [
"Write",
"Edit",
"MultiEdit",
"Bash(go mod tidy:*)",
"Bash(go get:*)",
"Bash(golangci-lint:*)",
"Bash(git add:*)",
"Bash(git commit:*)",
"Bash(git diff:*)",
"Bash(git status:*)"
],
"defaultMode": "default"
},
"sandbox": {
"enabled": true,
"autoAllowBashIfSandboxed": false
}
}
这版配置的核心思路
你前面的总结其实已经很对了,可以浓缩成一句话:
permissions 是立法,sandbox 是执法。
所以这份配置的目标不是“让 AI 什么都能做”,而是:
- 默认只允许低风险读操作
- 允许安全的 Go 项目分析与验证命令
- 所有改代码、改依赖、改 Git 状态的动作都需要确认
- 对敏感文件、危险命令、外部系统操作直接封死
- 即使在 sandbox 中,Bash 仍然不能绕过权限审查
为什么我对你给的版本做了调整
1. 修正了 Bash 命令匹配写法
你给的例子里同时出现了:
"Bash(go:version)"
"Bash(go:list:*)"
"Bash(go list:*)"
"Bash(go version:*)"
这里风格不统一,而且前两种写法通常不如后两种直观稳定。
更推荐统一成这种:
"Bash(go version:*)"
"Bash(go list:*)"
"Bash(go test:*)"
"Bash(go vet:*)"
这样更像真实 shell 命令模式,更容易维护。
2. 增加了项目关键文档读取权限
对于 issue2md 这种你正在做 AI 原生工作流治理 的项目,AI 经常需要读这些文件:
CLAUDE.mdconstitution.mdspec.mdplan.md
如果不显式允许,很多“先审查再计划”的工作流会卡住。
所以我把它们放进了 allow。
3. 增加了代码目录的只读放行
你原例只允许读取少数根文件,但没有明确允许:
cmd/**internal/**pkg/**testdata/**
对于 Go 项目来说,这些目录通常是高频审查对象。
如果团队想让 AI 做代码 review、测试分析、实现建议,就应该允许只读访问。
4. 把 go vet 加进 allow
你前面刚设计了 /review-go-code,它明确依赖:
go vet
所以如果 settings 不允许 go vet,这个命令就会打架。
因此我补上:
"Bash(go vet:*)"
5. 对危险 Bash 做了更严格 deny
你原来只 deny 了:
rmgit push
但从安全角度,最好再补几类:
系统破坏类
sudochmodchown
外部网络与数据外传类
curlwgetncsshscprsync
基础设施类
dockerkubectl
高风险 Git 历史改写类
git resetgit rebasegit cleangit tag
这样更适合团队环境。
6. 把“写代码”和“改仓库状态”统一放进 ask
这几类动作本质上都属于“改变世界”,应该要求人工确认:
WriteEditMultiEditgo mod tidygo getgit addgit commit
我还额外把:
git diffgit status
放进了 ask。
这里有两种选择:
方案 A:放 allow
优点:更丝滑
缺点:AI 可自由读取 Git 工作区状态
方案 B:放 ask
优点:更保守
缺点:略微影响流畅度
因为你这次主题是“安全配置”,我偏向保守策略,所以先放 ask。
每一段怎么理解
allow:安全绿灯区
这些是默认可以做的,主要是:
1. 只读上下文
"Read(...)"
"Grep",
"Glob",
"LS"
作用:让 AI 能看项目、搜代码、理解结构,但不改动任何东西。
2. 安全的 Go 命令
"Bash(go version:*)"
"Bash(go env:*)"
"Bash(go list:*)"
"Bash(go test:*)"
"Bash(go vet:*)"
"Bash(go build:*)"
"Bash(gofmt:*)"
"Bash(goimports:*)"
这些通常用于:
- 环境识别
- 包分析
- 编译验证
- 测试验证
- 静态检查
- 格式化
它们风险较低,适合作为默认放行项。
3. 受控 WebFetch
"WebFetch(domain:pkg.go.dev)"
"WebFetch(domain:golang.org)"
"WebFetch(domain:go.dev)"
"WebFetch(domain:github.com)"
允许 AI 查:
- Go 官方文档
- 包文档
- GitHub 仓库页面
但只开放这些域名,避免无限制联网。
deny:绝对禁区
这些属于“明确不允许碰”的内容。
1. 敏感文件
"Read(.env)"
"Read(.env.*)"
"Read(**/.env)"
"Read(**/.env.*)"
"Read(~/.ssh/**)"
"Read(/etc/passwd)"
"Read(/etc/shadow)"
目标:防止读取密钥、环境变量、系统敏感信息。
2. 破坏性命令
"Bash(rm:*)"
"Bash(sudo:*)"
"Bash(chmod:*)"
"Bash(chown:*)"
3. 外连/传输命令
"Bash(curl:*)"
"Bash(wget:*)"
"Bash(nc:*)"
"Bash(ssh:*)"
"Bash(scp:*)"
"Bash(rsync:*)"
4. 基础设施命令
"Bash(docker:*)"
"Bash(kubectl:*)"
5. 危险 Git 操作
"Bash(git push:*)"
"Bash(git tag:*)"
"Bash(git reset:*)"
"Bash(git rebase:*)"
"Bash(git clean:*)"
ask:需要人工审批的变更区
这些不是绝对禁止,而是:
AI 可以提议,但必须你点头。
包括三类:
1. 文件改动
"Write",
"Edit",
"MultiEdit"
2. 依赖变化
"Bash(go mod tidy:*)"
"Bash(go get:*)"
3. Git 状态变化
"Bash(git add:*)"
"Bash(git commit:*)"
这最符合你前面建立的流程观:
- AI 先审查
- 再计划
- 最后实现
- 关键动作由人确认
sandbox 为什么这样配
"sandbox": {
"enabled": true,
"autoAllowBashIfSandboxed": false
}
含义是:
1. enabled: true
所有 Bash 命令都默认在沙箱里跑。
即使执行了命令,也先被限制在受控环境中。
2. autoAllowBashIfSandboxed: false
关键点在这里。
它的意思不是:
在沙箱里就自动安全了
而是:
即使在沙箱里,也仍然必须通过 permissions 审查
这就形成了你说的“双保险”:
- permissions:决定能不能做
- sandbox:限制怎么做
这份配置特别适合哪些场景
非常适合你现在这种 Go 项目团队化 AI 工作流:
1. 代码审查
允许:
- 读代码
- 跑
go vet - 跑
go test - 读
constitution.md
但不允许它自己乱改。
2. 先分析再实现
AI 可以先大量读取和分析,形成计划。
真正写代码时,会触发 ask,由你确认。
3. 安全分享给团队
因为它把高风险动作都放在 ask 或 deny,所以比较适合团队统一下发。
如果你更追求“开发流畅度”,可以放宽哪些项
如果后面你进入高频编码阶段,可以考虑把以下命令从 ask 调到 allow:
"Bash(git diff:*)"
"Bash(git status:*)"
"Bash(golangci-lint:*)"
甚至在你信任当前工作区时,也可以把:
"Edit",
"Write"
做更细粒度放宽。
但对于“团队默认配置”,我不建议一开始就这么开。
一个更稳妥的实践建议
你题目里也提到了 settings.json 和 settings.local.json。
我的建议是:
团队共享:./.claude/settings.json
放保守版,也就是我上面给你的这版。
目标:安全、统一、可审计。
个人机器:./.claude/settings.local.json
你自己可以覆盖部分策略,比如:
- 允许
git status - 允许
git diff - 允许更频繁的格式化命令
- 对某些低风险 edit 降低交互成本
这样就形成:
团队共享基线 + 个人本地优化
这是最稳的。
一句话总结
这份配置的本质不是“限制 AI”,而是:
把 AI 纳入一个“可读、可跑低风险命令、但关键变更必须审批、危险操作绝不放行”的工程治理框架。