Claude Code封号机制,源码里到底写了什么

hi,我是南哥。
昨晚我把一份 Claude Code 泄露出来的源码翻到很晚。
本来只是想找一个很直接的东西,比如 ban()、suspendUser() 这种函数。
结果翻了几轮之后,我发现自己想简单了。
Claude Code 这套东西,压根不是“本地写了一个封号开关”那么朴素。
它更像一条完整的风控流水线。
客户端负责持续采集身份、环境、行为。
服务端再把这些信号揉在一起,决定你是正常用户,还是高风险用户,还是该限流、该限权、该封。
讲真的,这种设计一看就不是临时拼出来的。
有点企业级。
先说结论
如果你问我,这份源码能不能直接证明“Claude Code 怎么封号”。
答案是,不能百分百。
因为真正拍板的地方,大概率在服务端,不在客户端。
但如果你问,它能不能证明 Claude Code 具备一整套封号前置能力。
答案是,能,而且证据不少。
我看完后的判断很明确:
Claude Code 的核心不是“检测一次异常就封”。
而是先把你这台机器、这个账号、这次会话、这类使用方式,全部稳定标记出来。
等这些标签积累到一定程度,服务端想做限流、限功能、限账号,都会非常顺手。
我最先找的,其实是 ban 函数
没找到。
这事挺有意思。
源码里没有一个特别显眼的“封号模块”摆在那里。
但你顺着请求链路往下看,会发现另一种东西。
它不是直接写“封你”。
它写的是:
你是谁。
你从哪台机器来。
你是不是官方客户端。
你现在是不是在 CI 里跑。
你是不是非交互模式。
你这一轮花了多少 token,多久,多少钱。
你最近是不是一直在高频打。
你这台机器以前是不是还绑过别的账号。
这就很吓人了。
因为这类系统一旦拼起来,封号只是最后一个动作,不是最难的动作。
一. 它先给你打一个长期设备标识
在 src/utils/config.ts 里,有个 getOrCreateUserID()。
逻辑很直接,第一次运行时生成 randomBytes(32).toString('hex'),也就是 32 字节随机值,转成十六进制字符串。
这个值会被持久化。
不是一次性的。
这意味着什么?
意味着只要你不主动清掉对应配置,客户端就会一直带着同一个设备身份跑。
这里还有个小坑。
网上有些转述会把这个文件写成 ~/.claude/config.json。
但我翻这份代码时看到的实现,更接近家目录下的 .claude*.json 这一套,同时兼容更早的 .config.json。
另一边,session_id 是每次会话新建时重新生成的 UUID。
也就是说,Claude Code 把“这台设备”和“这次会话”分得很清楚。
一个长期。
一个短期。
长期的方便做设备归因。
短期的方便做会话级追踪。
这种组合,太适合做风控了。
二. 每次请求都在做来源归因
这个地方我看得有点头皮发麻。
在 src/services/api/claude.ts 里,请求 metadata 会带一个 user_id。
它不是单纯一个字符串。
里面塞了 device_id、account_uuid、session_id。
也就是说,服务端拿到一次请求,就已经知道:
这次请求来自哪台设备。
这台设备当前绑定哪个账号。
它属于哪个会话。
还没完。
src/utils/fingerprint.ts 里还做了一个 3 位指纹。
算法也写得很直白:拿首条用户消息的第 4、7、20 个字符,再拼一个固定 salt 和版本号,做 SHA256,截前 3 位。
别小看这个指纹只有 3 位。
它不是拿来当主身份的。
它更像一个“请求归因标签”。
因为这个指纹会继续塞进 x-anthropic-billing-header 的 cc_version 里。
src/constants/system.ts 甚至还留了一个 cch=00000 的原生客户端 attestation 占位。
代码注释写得很明白,底层 HTTP 栈会把它替换成校验值,服务端用来确认“这是不是一个真的 Claude Code 客户端”。
这就不是普通埋点了。
这已经有点像客户端验明正身。
所以,很多人说“我改个壳、伪造几个 header 不就行了”。
真要这么想,就把这套校验链路想得太浅了。
三. 环境会被摸得很细
如果只是设备 ID,其实还不够。
真正让我意识到它在做风控的,是环境枚举这一层。
src/services/analytics/metadata.ts 和 src/utils/env.ts 里,环境采集做得很重。
系统层面会拿平台、架构、Node 版本、Linux 发行版、WSL 版本、VCS 类型。
运行环境这边会看终端、IDE、tmux、screen、SSH、Cursor、JetBrains、VS Code。
CI 和云环境也没放过。
GitHub Actions、GitLab CI、CircleCI、Buildkite、Codespaces、Gitpod、Replit、Vercel、Railway、Kubernetes、Docker,基本都做了识别。
甚至 GitHub Actions 的 actor、repository、owner 这些字段也有专门埋点。
你把这些信号和前面的 device_id 一拼,服务端看到的就不再是“一次 API 调用”。
它看到的是一个带背景资料的人。
这人在哪跑。
怎么跑。
是不是自动化跑。
是不是共享环境跑。
是不是一直在远程容器里跑。
是不是和它期望的官方交互方式不太一样。
四. 行为数据不是记一点点,是一直记
这里有个容易被忽略的点。
很多人会以为遥测只是“记录打开了几次”。
不是。
tengu_init、tengu_api_success、tengu_exit 这些事件,信息量都很大。
尤其是 tengu_api_success。
我顺着 src/services/api/logging.ts 看过去,里面会带模型名、输入输出 token、缓存 token、耗时、TTFT、costUSD、是否非交互、请求来源这些字段。
简单说,你这一轮调用贵不贵,猛不猛,快不快,系统都知道。
还有个细节。
我本地用 rg 扫了一下,这个仓库里 tengu_* 事件名超过 1000 个。
注意,是超过 1000 个,不是网上很多文章里写的 640 多个。
当然,这不代表 1000 多个事件都直接拿来封号。
但它至少说明一件事:
Claude Code 的行为遥测覆盖面非常大。
再配合 firstPartyEventLoggingExporter 里的批量上报逻辑,默认就是 5 秒一批,单批最多 200 条,失败了还会落地到本地 telemetry 目录,下次继续补发。
这套东西,一看就不是拿来做“产品感觉一下用户活跃不活跃”的。
它更像一套长期行为画像系统。
五. 真正危险的,不是埋点,是远程开关
如果只有采集,其实还只是“看见你”。
真正让我觉得它封控能力很强的,是另外两条接口:
/api/claude_code/settings
/api/claude_code/policy_limits
这两个都在源码里,而且都支持轮询。
默认频率是一小时。
什么意思?
意思就是,服务端不光能观察你。
它还能改你。
比如远程下发 managed settings,改客户端行为。
比如下发 policy limits,直接限制某些能力能不能用。
源码里已经能看到类似 allow_remote_sessions、allow_remote_control、allow_product_feedback 这种策略键。
换句话说,服务端不是只能说“你以后别用了”。
它也可以先说“你这个号接下来不能跑某个能力了”。
这就很像成熟产品的处置路径:
先观测。
再限权。
再限流。
必要时再封。
六. 那最可能因为什么出事
如果只根据这份源码,不去编故事,我觉得风险最高的几类场景,大概是这样。
一个是账号共享。
因为 device_id + account_uuid 这个组合太适合做多设备关联了。
你同一个账号,今天在这台机器,明天在另一台机器,环境特征还完全不一样,服务端不可能看不见。
另一个是异常高频消耗。
源码里有专门的 quota_check,也会解析 429 限流头。
说明配额、速率、overage 这些东西,本来就是系统重点盯的。
再一个是非官方客户端或者魔改客户端。
因为它有固定的 User-Agent,有固定的 header 组合,有 attribution header,有消息指纹,还有原生 attestation 这一层。
你改得太离谱,被标异常并不奇怪。
还有自动化滥用。
这个源码里虽然没有写“检测到 CI 就封号”。
但它明确会上报 is_ci、is_interactive、entrypoint、部署环境、GitHub Actions 元数据。
这些字段单看没什么。
一旦跟高频请求、大量 token 消耗、长时间非交互调用拼在一起,就很容易组成风控规则。
还有个坑,很多人已经看漏了
这份仓库里有几层 OSS stub。
比如 analytics 入口、Datadog、1P event logger,在 open build 里被做成了空实现。
所以你如果只搜一圈,看到“这不是没上报吗”,很容易误判。
更接近真实的理解应该是:
开源构建把总闸关了。
但元数据结构、事件命名、导出器、批处理、重试、远程配置这些骨架,基本还在。
这说明官方产品原本的设计方向,就是重身份、重归因、重策略。
我自己的判断
我看完这份源码后的感觉很简单。
Claude Code 的封号,不像“踩一条线立刻炸”。
更像“你一路上的行为都被记着,等服务端觉得画像够完整了,再决定怎么处理你”。
所以别把它理解成一个孤零零的 ban 按钮。
它更像一整套风控工厂。
客户端负责采集。
服务端负责裁决。
中间再夹一层远程策略控制。
这也是为什么,很多人明明没觉得自己干了什么特别出格的事,号却突然不对劲了。
问题可能不是某一次请求。
而是前面那一串行为,被系统拼起来了。
我就不展开“怎么绕”了。
真没必要为了省点钱,把号一起玩没。
如果你后面还想看,我可以继续把这份源码里和遥测、限流、远程策略有关的部分,再拆成一篇更细的图解版。
感兴趣的评论区聊。
ps:最近粉丝破 1w,准备了 500 张 gpt 月卡,目前发了 200 张,进粉丝群抽奖
夜雨聆风