
用 Claude Code 写代码写得越顺手我心里反而越没底。模型生成代码的速度是按“秒”算的可它并没有一个内置的“安全意识开关”经常会在某个工具函数里顺手写下一段硬编码的密钥或者在拼接 SQL 的时候少了一层转义。后来我花了两天时间给自己维护的一套 Claude Code 工作流补齐了一块短板整理出一个由 6 个开箱即用的安全扫描工具组成的“安全技能包”。这篇文章就把这套技能包的选型、接入、规则调优和踩坑过程完整写出来给同样在用 Claude Code 干活、又不想让 AI 把安全问题带进代码库的开发者做个参考。这套技能包解决的其实就三件事把密钥挡在提交之前把已知漏洞拦在合并之前把配置错误消灭在部署之前。它可以接在 Claude Code 的普通对话流程里也可以挂到 CI 里做强制门禁适合个人项目、小团队协作和已经有一定代码规模、但还没有完整安全流程的中型项目。下面从设计思路开始讲再到每个工具的具体用法和接入配置。1. 为什么要在 AI 编程工作流里加一层“安全技能包”1.1 AI 生成代码放大了哪几类安全问题传统开发流程里代码安全主要靠两个环节兜底评审人肉眼扫一遍加上 CI 里的静态扫描。但 Claude Code 这类 AI 编程助手把代码生产的节奏一下子拉快了模型生成的代码量可能比人写的还多评审环节就会变成瓶颈而 CI 里的扫描工具又往往只覆盖了编译和测试没有覆盖安全维度。我实际遇到的三类典型问题最有代表性。第一类是敏感信息硬编码模型特别喜欢在示例代码或者工具函数里写api_key sk-xxx这样的默认值如果代码被推到远端仓库密钥基本等于直接送人。第二类是依赖版本滞后Claude 会根据它训练数据里的记忆推荐依赖那些版本可能已经存在公开漏洞而项目的锁文件又不会自动提醒。第三类是配置姿势不对比如把数据库连接池的超时时间设置得过短、把调试开关留在生产环境、对上传文件没有做类型校验这类问题静态分析工具比人眼扫得准。所以我的思路很直接不是指望 Claude Code 自身“学会安全”而是在它生成代码的入口和出口各加一道扫描关卡。入口关卡是规则约束通过 CLAUDE.md 告诉模型哪些能写、哪些不能写出口关卡是扫描工具不管模型怎么生成最终交付之前必须过一遍安全技能包。1.2 技能包的设计目标与选型原则选工具之前我给自己定了几个硬性标准。首先必须是命令行工具因为 Claude Code 本身就跑在终端里只有 CLI 才能被脚本调用、被模型读取输出才有办法无缝集成。其次是输出格式要机器可读JSON 输出是标配这样 Claude 可以直接解析结果、自己判断要不要修。最后是社区活跃度和规则可扩展性工具本身扫得准不准是一回事能不能让我自定义规则才是长期价值所在。基于这三条标准我最终选了 6 个工具分别覆盖密钥泄露、静态代码分析、依赖漏洞、Python 专项、基础设施配置和历史提交深挖这几个维度。工具扫描对象核心能力输出格式集成难度Gitleaks密钥与敏感信息提交前快速扫描、规则丰富、支持全局白名单JSON / SARIF低Semgrep多语言静态代码支持 30 语言、可自定义规则、兼容常见安全规则库JSON / SARIF中Trivy依赖与容器镜像锁定文件漏洞、镜像漏洞、IaC 文件扫描JSON / SARIF中BanditPython 代码AST 级安全分析、针对 Python 的漏洞模式库JSON / 文本低CheckovIaC 配置Terraform、K8s、Dockerfile 配置扫描JSON / SARIF中TruffleHogGit 历史与密钥深挖历史提交、密钥活跃校验、范围比 Gitleaks 更大JSON中这套组合的逻辑是Gitleaks 负责最容易出事的入口Semgrep 负责日常代码体检Trivy 负责供应链依赖Bandit 和 Checkov 各自补齐语言和配置层面的专业死角TruffleHog 负责处理那些已经“脏”了的历史仓库。六个工具扫的东西几乎没有重叠但组合起来能覆盖一条代码从生成到部署的完整链路。1.3 技能包的目录结构与工作流程技能包不是把六个工具装完就结束而是要让 Claude Code 能一键调用它们。我的目录结构是这样的security-skill/ ├── bin/ │ └── security-scan.sh # 一键扫描入口脚本 ├── rules/ │ ├── gitleaks.toml # 密钥扫描自定义规则 │ ├── semgrep/ │ │ └── no-hardcoded-secret.yml │ └── trivy-skip.list # 依赖漏洞忽略列表 ├── .claude/ │ └── skills/ │ └── security-scan/ │ └── SKILL.md # 给 Claude 看的技能说明 ├── CLAUDE.md # 项目级规则声明 └── README.md实际工作流程分三层。第一层是 Claude Code 每次生成代码时由 CLAUDE.md 里的规则进行约束第二层是模型写完之后我手动触发security-scan技能跑一遍快速扫描第三层是 CI 里的强制门禁任何合并请求都必须让完整版扫描通过。我大概计算过这套流程的成本一个小型项目在改动 20 个文件以内时Gitleaks 全量扫描不到 10 秒Semgrep 增量扫描 20 秒左右Trivy 依赖扫描如果之前已经拉过数据库最快 3 秒出结果。整体控制在 1 分钟以内比人工审查快得多关键是它不会累。2. 6 个开箱即用的安全扫描工具逐个拆解2.1 Gitleaks先把密钥挡在提交之前Gitleaks 是我对密钥问题设置的第一道封锁线。它的原理说白了就是正则匹配加上规则引擎内置了几百条密钥模式覆盖 AWS、GitHub、Slack、数据库连接串等常见敏感信息也会自己计算熵值来抓那些不在规则表里的高随机字符串。安装很简单Mac 上可以直接用包管理器装Linux 服务器上可以拉编译好的二进制文件brew install gitleaks # 或者从 GitHub Releases 拉二进制后放进 /usr/local/bin日常使用我最常跑的命令是gitleaks detect --source . --no-banner --exit-code 1 --report-path gitleaks.json--exit-code 1的意思是扫到问题就以退出码 1 结束这样脚本拿到非零退出码就能判断“该拦下来了”。--report-path指定 JSON 报告输出位置Claude Code 可以直接读这个文件。我踩过的一个坑是 Gitleaks 对测试数据特别敏感。项目里用了类似test-token-123456这样的占位符Gitleaks 有时候也会报这时候不要直接删工具而是用.gitleaks.toml里的 allowlist 做边界声明title project-gitleaks-config [extend] useDefault true [allowlist] description 排除测试文件和模拟数据 paths [ tests/**, testdata/**, **/*.mock.* ] regexes [ test-token-[0-9] ]这样既保留默认规则又不会让测试数据把真正的密钥淹没在一堆误报里。2.2 Semgrep多语言静态扫描的瑞士军刀Semgrep 是我这六个工具里使用频率最高的一个。它和传统静态分析工具最大的区别是它不是在模拟执行代码而是在语法树层面做模式匹配所以速度快、误报率低而且规则用 YAML 写任何开发人员都能看懂。安装pip install semgrep # 或者 brew install semgrep日常扫描命令semgrep scan --config auto . --json --output semgrep.json--config auto会自动选择一组社区维护度最高的规则包第一次扫描会花一点时间下载规则之后走缓存就快了。如果只想扫自己关心的安全问题可以自定义规则。下面这条规则专门抓硬编码密码是我在技能包里默认启用的rules: - id: no-hardcoded-password languages: [python, javascript, typescript, go] severity: ERROR message: 发现硬编码密码或密钥请改为从环境变量读取 pattern-either: - pattern: | password ... - pattern: | secret_key ... - pattern: | $VAR ... metadata: cwe: CWE-798这里的$VAR是 Semgrep 的元变量会匹配任何标识符再配合“值看起来像高熵字符串”的条件就能覆盖多种硬编码场景。规则文件放进技能包的rules/semgrep/目录后执行时用--config rules/semgrep/就能加载。我实际用得最多的用法不是全量扫描而是让 Claude Code 在生成代码后只扫新增文件。在脚本里把 git diff 的文件列表传给 SemgrepCHANGED_FILES$(git diff --name-only HEAD~1 | grep -E \.(py|js|ts|go)$ | tr \n ) semgrep scan --config rules/semgrep $CHANGED_FILES --json这样每次模型生成完一批代码我能在一分钟左右得到结果而不是全仓库扫描的好几分钟。2.3 Trivy依赖与容器的“体检报告”Trivy 名义上是容器镜像漏洞扫描器但它的实际能力远超镜像范畴可以直接扫项目的锁文件、扫描文件系统里的漏洞依赖甚至可以扫 Terraform 配置。对我来说它最大的价值是解决了 Claude Code 推荐依赖版本滞后的问题。安装brew install trivy # 或者下载二进制包后自解压最常用的命令是对当前目录做一次文件系统漏洞扫描trivy fs . --scanners vuln --severity HIGH,CRITICAL --ignore-unfixed --format json --output trivy.json几个参数值得解释一下。--severity HIGH,CRITICAL是为了把噪音压下去低危和中危漏洞先不看集中力量处理高危。--ignore-unfixed的意思是那些官方还没有出修复补丁的漏洞就不报了报了也修不了徒增焦虑。--format json是为了让输出结果能被 Claude Code 读取。Trivy 第一次运行会拉取漏洞数据库大约几百 MB之后每天增量更新一次。我在 CI 里会让它启用缓存大概能省掉 80% 的运行时间。这个工具我跟很多同事安利过因为它有三个用法其实很隐蔽一是配合--scanners misconfig可以扫 Dockerfile 和 Kubernetes 配置二是trivy repo url可以直接扫远端仓库三是它支持生成 SBOM 清单做供应链合规会用到。对一个安全技能包来说它相当于给依赖和部署配置都做了个体检报告。2.4 BanditPython 代码的专项安检如果你的项目以 Python 为主Bandit 是必须装的一个。它是基于 Python 抽象语法树工作的静态分析工具不会执行代码因此速度极快专门检测 SQL 注入、shell 注入、弱哈希算法这类 Python 项目里常见的安全问题。安装与基本使用pip install bandit bandit -r src/ -f json -o bandit.json-r表示递归扫描目录-f json指定输出格式-o指定报告文件。如果不指定它默认只会在终端里打印一个汇总报告。Bandit 的规则分级很有意思ID 从 B101 到 B608每一条都有明确的问题说明和建议改法。比如 B608 是 SQL 注入风险它会检测到字符串拼接进 SQL 查询语句的写法B602 是检测subprocess调用是否传了shellTrue。模型生成代码时如果出现os.system()处理外部输入Bandit 基本都能抓出来。我在技能包里会给它定制一个策略文件bandit.yaml只保留安全相关的规则skips: - B101 # assert 语句测试代码里常见 exclude_dirs: - tests - .venv这里B101是把 assert 当安全检查的规则生产代码里建议保留但测试代码里用 assert 是正常行为所以我选择跳过。Bandit 最让我放心的是它的判定结果很稳误报率比很多商业工具低。如果某条警告确实是被误报误伤的可以在代码行尾加# nosec BXXX注释明确声明“这里是安全边界我已经考虑过了”。这个注释方式对 Claude Code 也有效模型在生成代码后如果看到# nosec就不会再反复提示同一个问题。2.5 Checkov基础设施即代码的配置审查队伍里很多人写 Claude Code 时只关注应用层代码看到 Checkov 会问一句“这也算安全扫描工具”实际上现在的项目里都有 Dockerfile、有 CI 配置、有云资源声明文件这些“基础设施即代码”文件的配置错误造成的后果往往比应用代码漏洞更严重。Checkov 就是专门干这个的。它内置了上千条策略覆盖 Terraform、CloudFormation、Kubernetes、Dockerfile、GitHub Actions 等。比如它会检测到你的 Dockerfile 使用了默认 root 用户运行、没有固定镜像 tag、容器没有设置资源限制等。安装和使用pip install checkov checkov -d . --quiet --compact --output json checkov.json-d指定目录--quiet只输出失败结果--compact压缩输出格式。Checkov 的 JSON 输出结构很清晰每一条结果都有check_id、check_name、file和resource字段Claude Code 读起来非常方便。Checkov 的检查项分 CKV 系列编号看到CKV_DOCKER开头的就是 Dockerfile 相关CKV_AWS开头的是 AWS 资源相关。我一般先按severity过滤HIGH 以上的问题直接阻塞合并。有一个很实用的技巧Checkov 支持在资源定义里用注释跳过检查#checkov:skipCKV_AWS_123:该资源允许临时运维调试下线后移除 resource aws_security_group debug { # ... }注释里的格式是checkov:skip规则ID:原因原因必须写清楚既方便自己以后复查也方便 Claude Code 理解当初跳过的理由。我要求团队里跳过的每一条必须写原因否则宁可让它报着。2.6 TruffleHog历史提交里的“漏网之鱼”Gitleaks 扫的是当前工作区对已经被推到远端仓库的历史提交它是无能为力的因为旧提交里的密钥早就不在当前文件里了普通扫描器根本看不到。而 TruffleHog 干的就是这种“考古”的活它会遍历 Git 提交历史扫描每个 diff 中的敏感信息并且能做密钥验证确认这个密钥是否还能用。安装# 从源码安装 go install github.com/trufflesecurity/trufflehog/v3/cmd/trufflehoglatest # 或者用包管理器 brew install trufflehog扫描当前仓库的完整历史trufflehog git file://. --only-verified --json --output trufflehog.json--only-verified是 TruffleHog 最值钱的一个参数它会把扫描到的密钥拿去和对应的云服务 API 做验证只有验证通过的才会报告。这样能过滤掉大量“看起来像密钥但已经失效”的测试数据。当然这个参数会拉长扫描时间因为它要做网络请求。我在技能包里用 TruffleHog 通常不是每次全盘扫而是每周做一次定时任务或者在新项目接进来的时候对历史提交做一次摸底。有一次我在一个内部模拟项目的旧提交里扫出一个已经失效的数据库连接串那个连接串在当前分支里早就被删掉了但历史里一直躺着。如果不是 TruffleHog这个问题永远不会被找到。需要提一下的是TruffleHog 和 Gitleaks 之间的分工经常被误解。我的经验是Gitleaks 用在“预防”每次提交前跑TruffleHog 用在“发现”定期对历史做核验。两个工具配合使用才算完整覆盖了密钥泄露的整个生命周期。3. 在 Claude Code 中接入技能包的完整实操3.1 先搭目录技能包、脚本、规则三件事很多人在本地装好工具以后直接就在终端里手动敲命令扫描这也能用但对 Claude Code 来说不够“顺”。要让模型自动识别并调用扫描工具最好把扫描动作封装成技能包让模型只需要通过一句话就能触发。我的做法分成三步。第一步把所有工具二进制和包管理器装好确认gitleaks、semgrep、trivy、bandit、checkov、trufflehog六个命令全局可用。第二步写一个统一的入口脚本bin/security-scan.sh把六个工具的调用顺序、参数和输出文件路径管理起来。第三步写一个 SKILL.md 文件告诉 Claude Code 这个技能包是干什么的、怎么用、输出到哪里。入口脚本的核心逻辑是先把结果全都扫出来然后统一汇总成一个汇总文件#!/usr/bin/env bash set -euo pipefail SCAN_DIR${1:-.} REPORT_DIR${SECURITY_REPORT_DIR:-./.security-reports} mkdir -p $REPORT_DIR echo 1/6 Gitleaks gitleaks detect --source $SCAN_DIR --no-banner --exit-code 0 \ --report-path $REPORT_DIR/gitleaks.json || true echo 2/6 Semgrep semgrep scan --config auto $SCAN_DIR --json \ --output $REPORT_DIR/semgrep.json 2/dev/null || true echo 3/6 Trivy trivy fs $SCAN_DIR --scanners vuln --severity HIGH,CRITICAL \ --ignore-unfixed --format json --output $REPORT_DIR/trivy.json || true echo 4/6 Bandit bandit -r $SCAN_DIR -f json -o $REPORT_DIR/bandit.json 2/dev/null || true echo 5/6 Checkov checkov -d $SCAN_DIR --quiet --compact --output json \ $REPORT_DIR/checkov.json 2/dev/null || true echo 6/6 TruffleHog trufflehog git file://$SCAN_DIR --only-verified --json \ --output $REPORT_DIR/trufflehog.json || true echo 全部扫描完成报告目录$REPORT_DIR脚本里每个工具的退出码都被|| true拦住了因为扫描出问题不等于脚本执行失败我们要的是报告文件真正的门禁逻辑放在汇总那一步。这个脚本虽然不是特别复杂但它把六个工具的参数选择、输出路径和容错处理都固化了Claude Code 只需要调用它不需要重新理解每个工具的用法。3.2 用 CLAUDE.md 给模型立规矩Claude Code 在进入项目时会自动读取 CLAUDE.md 作为上下文的一部分所以这个文件是给模型“立规矩”的最佳位置。我在项目的 CLAUDE.md 里加了一段安全规则内容大致如下## 安全要求在与本仓库代码交互时必须遵守 1. 禁止在代码中硬编码密钥、口令、Token 等敏感信息所有敏感值一律通过环境变量或配置文件注入。 2. 生成代码时如果涉及数据库操作、文件上传、外部命令执行必须考虑输入校验和注入风险。 3. 在完成代码修改后如果用户提出“安全检查”“扫描一下”“查泄漏”等请求必须运行 bin/security-scan.sh 并阅读生成的报告。 4. 所有安全扫描发现的问题在未确认是否修复之前不得声称“安全”。 5. 如果某个警告确实不适用需要在代码注释或报告中写明原因不得直接删除报告。这五条规则实际上是给模型一个“安全感知”。我特意在第三条里用了“安全检查”“扫描一下”这类自然语言作为触发词因为 Claude Code 的指令理解能力很强它看到这些词后会自动调用脚本。有朋友会问为什么不让模型每次生成完代码都自动扫描我的经验是那样扫描次数太多噪音太大反而不利于发现问题用户明确要求时再扫效果最好。3.3 定义可复用的扫描技能SKILL.mdClaude Code 支持 Agent Skills本质是一个带 frontmatter 的 Markdown 文件里面描述技能的名称、触发条件和具体操作流程。我在.claude/skills/security-scan/SKILL.md里写的核心内容是这样的--- name: security-scan description: 对当前项目执行完整的安全扫描包括密钥泄露、静态分析、依赖漏洞、配置扫描和历史密钥检测。当用户要求做安全审查、检查密钥、扫描漏洞时使用。 --- ## 执行步骤 1. 确认当前目录是项目根目录如果不是先定位到根目录。 2. 运行 bin/security-scan.sh . 执行完整扫描。 3. 依次读取 .security-reports/ 目录下生成的 JSON 报告文件。 4. 根据扫描结果输出问题清单包括文件名、行号、问题类型、风险等级、建议修复方案。 5. 修复建议应该具体到可以直接执行的代码修改而不是只说“请使用安全方式”。Skill 文件最重要的地方是让模型知道扫描之后的产出物是什么。它不能只是跑完脚本就结束而是必须输出一份“问题清单修复建议”的报告这才是对开发人员最有价值的输出。Claude Code 读完 JSON 报告后会自己判断哪些是该优先修复的高危问题哪些是可以忽略的噪音这个判断能力本身就是这套技能包最大的杠杆。3.4 用 Hooks 和 CI 兜底避免“说了不做”CLAUDE.md 和 SKILL.md 解决的是“模型知道要扫描”的问题但现实中还有一个问题开发者自己也会忘记跑扫描。所以我给技能包加了第三道保险Hooks 和 CI。Claude Code 的 Hooks 机制可以在特定事件发生时自动执行脚本。我在配置里加了一个PreToolUsehook在模型执行git push或者创建提交之前自动跑一遍 Gitleaks{ hooks: { PreToolUse: [ { matcher: git push|Git Push, hooks: [ { type: command, command: gitleaks protect --staged --no-banner } ] } ] } }这样即使我忘记主动触发模型想要 push 时也会被拦截下来。当然这个 hook 只处理了密钥完整的扫描还是要靠 CI。我的 CI 流程里加了一个安全门禁任务跑的就是同一个security-scan.sh然后让报告里出现 MEDIUM 以上级别问题时构建失败。这样三层保险叠下来密钥基本不可能流出去依赖漏洞也撑不过合并请求。4. 规则调优与误报处理实操4.1 扫描结果一片红先别急着杀工具把六个工具全跑一遍第一次的结果大概率让很多人血压升高。一上来的 Gitleaks 报告可能有几十条Semgrep 的 auto 规则可能给你报上百条看起来好像整个代码库都是窟窿。这时候千万别直接把工具从流程里删掉大多数“问题”其实只是噪音需要做的是调规则和设边界。我的处理顺序是先按严重级别过滤只看高危和严重然后把同一规则、同一文件路径的重复问题归并最后把确实属于测试代码、示例代码或第三方生成代码的路径加进白名单。这个过程大概需要反复两三轮之后扫描结果才会稳定在“一天 0 条意外告警”的水平。这里有个关键认知安全扫描工具的价值不是让告警数量变成 0而是让每一条告警都是真实的、可解释的。如果一个工具天天报一堆假阳性开发者就会习惯性忽略它那么它将来真发现问题时也没人信了。4.2 白名单与边界配置示例每个工具都支持通过配置文件声明白名单我建议把白名单规则放进技能包统一管理而不是分散在各个工具的参数里。Gitleaks 的白名单写在.gitleaks.tomlSemgrep 的白名单写在规则文件里加metadata或者用path排除Trivy 的忽略列表写在.trivyignore。.trivyignore文件的格式很简单# 等待上游修复临时忽略 CVE-2024-XXXXX # 仅内网使用不受公开攻击影响 CVE-2023-XXXXX每一行写一个漏洞 ID注释写清楚为什么忽略。这种文件的维护成本很低但价值很高因为它记录了团队的每一次“风险评估决策”。我在技能包里还专门维护了一个semgrep-ignore-paths.txt里面放的是没有必要扫描的目录node_modules、.venv、vendor、dist、build。原因很简单这些目录里的代码不是项目自己写的扫描结果没有参考意义还拖慢整体速度。4.3 让 Claude 参与结果研判把误报变学习样本这是我实操下来最惊喜的一个环节。Claude Code 在读了六个工具的 JSON 报告之后它对“这条告警是否合理”的判断远超我的预期。我会在触发扫描技能后直接问它哪些问题值得修哪些是误报误报的原因是什么它的回答通常会结合上下文分析比如指出某个变量虽然名字叫password但实际是数据库字段名不是敏感信息。这种情况下我不会每次都手动去改白名单而是会把这轮对话的结论反馈到 CLAUDE.md 或者规则文件里。比如 Claude 告诉我“Semgrep 报了三个password变量但其中两个只是 ORM 字段名不是硬编码密钥”我就会在 Semgrep 规则里加一条路径排除或者模式细化让后续扫描不再重复报同样的内容。这个流程把工具扫描和模型理解结合了起来误报率会随着使用时间越来越低整个技能包也越用越准。实际上Claude Code 在这里的角色不仅是“执行扫描的助手”更像是“安全报告的初步分析师”它把六个工具的结果交叉对比后给出一份带优先级的处理清单这是传统安全工具链很难做到的。5. 常见问题与排查技巧实录跑这套技能包跑了几个月我整理了一张高频问题速查表遇到问题先对号入座。现象可能原因排查与解决扫描耗时太长扫了虚拟环境或依赖目录在全量脚本的路径参数里排除node_modules、.venv、vendorGitleaks 扫出测试数据测试密钥在 allowlist 之外在.gitleaks.toml的 regexes 里加对应的测试前缀Semgrep 自定义规则不生效规则文件语言标记与项目语言不匹配检查languages字段是否包含实际文件扩展名Trivy 扫不出漏洞本地漏洞数据库太旧运行trivy image --download-db-only更新数据库Bandit 对 async 代码误报AST 规则对动态调用不友好用# nosec加注释或者调整策略文件跳过Checkov 报告无法解读输出内容太多加上--compact参数只保留失败项TruffleHog 卡在验证阶段网络请求慢去掉--only-verified只扫不验证或者增加超时时间5.1 扫描太慢学会给扫描工具划边界扫描工具跑得慢八成的瓶颈都出在扫描范围上。很多项目的根目录下会有一堆自动生成的依赖目录它们加起来几万个文件扫描器一个个读肯定会慢。我的处理方式是在security-scan.sh里给每个工具都加排除项而不是只依赖工具自带的默认排除。以 Semgrep 为例默认虽然会跳过.git但不会跳过node_modules我得显式指定semgrep scan --config rules/semgrep/ . \ --exclude node_modules --exclude .venv --exclude dist \ --json --output semgrep.json另外Trivy 扫描耗时主要在漏洞数据库的更新上。它的数据库文件大约是几百 MB如果每次运行都在下载那会非常痛苦。建议在 CI 里把它挂到缓存里或者单独跑一个定时任务每日更新数据库。5.2 漏扫检查 .gitignore 和文件编码有一种“坏情况”是扫描器根本没扫到某些文件。最常见的两个原因一是文件在.gitignore里且扫描器默认跳过被忽略文件二是文件编码不是 UTF-8工具读不出来。比如 Gitleaks 默认跳过.gitignore里列出的文件如果你的密钥恰好写在了一个被忽略的临时文件里Gitleaks 就不会报。所以我在技能包里会额外跑一遍gitleaks detect --no-git专门扫描工作区里所有文件包括被忽略的。当然这个命令适合本地排查CI 里就不需要了。文件编码的问题主要出现在 Windows 上有些编辑器会把新文件存成 UTF-16导致 Semgrep 和 Bandit 解析失败。遇到这类问题先把文件统一转成 UTF-8 再扫顺便还能避免跨平台协作时出现乱码。5.3 密钥扫描把测试数据当成真实泄露这是 Gitleaks 类工具最典型的误报场景。项目里总会有一些模拟用的 token、假 API key、示例数据库连接串它们的格式和真实密钥几乎一样Gitleaks 不认识上下文就会全部报出来。我的建议不是把整条路径全部塞进 allowlist那样可能会把将来真实的问题也忽略掉。更好的做法是限定一个正则范围比如测试 token 固定以test-开头那就在gitleaks.toml里声明[allowlist] regexes [ test-[A-Za-z0-9]{16,}, example-api-key-[a-z0-9]{8,} ]这样既保留了对真实密钥的扫描能力又屏蔽了测试数据的噪音。5.4 修复之后如何验证真的修好了扫描工具报告了问题Claude Code 也改了代码但“改完没改对”也是常见问题。我习惯在修复之后重新跑一遍单个工具的扫描而不是全量重跑这样反馈更快。例如 Gitleaks 报了一条硬编码密钥修复后我会跑gitleaks detect --source . --no-banner --exit-code 0 --report-path gitleaks-after.json然后对比前后的报告文件确认同样的规则 ID 和文件路径已经不再出现。对于 Semgrep 的规则修复后我会直接跑对应文件的单文件扫描确认规则不再触发。最后的收尾操作是和模型对一遍“修复确认”让 Claude 总结改了哪些位置、用了什么方式、为什么原来的写法有风险。这个过程对我来说已经成了常规动作它让每一次扫描不只是“抓问题”还成了团队安全常识的沉淀。这套技能包用到现在我的体验是它并不是一个“装完就跑一次”的工具集而是一个给 AI 编程工作流做的安全底座。我最深的体会是不要指望某个单一工具包打天下六种工具的配合关系远大于单工具能力之和也不要担心一开始的误报率花两三天调好白名单后面就稳定了。如果你也在用 Claude Code 写真实项目我建议先把 Gitleaks 和 Semgrep 接进去跑通一轮之后再加后面的工具逐个引入排查起来也更清楚。最后再分享一个小技巧在 CLAUDE.md 里给模型加一条“完成代码修改后必须说明本次改动涉及哪些敏感操作”的规则这个轻量约束基本不占成本但能有效降低密钥硬编码的发生频率。