你的 AI Agent 正在裸奔:casbin-gateway 权限层拆解 + 排障实战

0 阅读5分钟

声明在前面:我不是 casbin-gateway 的作者,本文是一个第三方开发者的拆解笔记。功能描述以 apache/casbin-gateway 仓库(Apache 2.0)为准;文中的排障部分是我用开源工具 casbin-config-doctor 实测过的,命令和输出可以逐字复现。

一、先说一个被忽略的事实:你的 Agent 什么都能干

Claude Code、Codex CLI、Cursor、Gemini CLI……装的时候大家都爽,装完很少有人想过一个问题:

这些 Agent 默认能读你整个项目、跑任意 shell 命令、联网、写文件。 一个 prompt injection、一条从网页抄来的「看起来合理」的指令,就足以让它把 .env 里的 key 发出去,或者 rm 掉没提交的代码。

管 Agent 的配置已经有人管了——casbin 社区上周发的 casbin-gateway(apache 组织下,Go + React,单二进制,Apache 2.0)就是干这个的:一个本地 Agent 管理助手,把机器上所有编程 Agent 收进同一个面板,统一管供应商切换、用量统计、模型真伪校验,以及本文要重点说的——权限

官方在 V2EX 的发布帖写得很全(支持 29 个 Agent 客户端、44 家模型厂商预置),这里不重复官方文案,只拆我最关心的一层:它的权限是怎么工作的、坏了怎么查

二、权限层拆解:开关底下是一套标准的 Casbin 策略

Gateway 给每个 Agent 提供四十来个权限开关,分六组:终端、读项目、改项目、联网、规划与派子 Agent、以及它装的每一个 MCP Server。两个设计点值得单独说:

  1. 关掉的工具在请求离开这台机器之前就被摘掉了——模型压根看不到这个工具,不是「看到了不让用」,Agent 无从尝试绕过。
  2. 不同 Agent 的工具名被归一化了——Bashshellrun_shell_command 在这里对应同一个开关;每组还有兜底项管住没见过的新工具,「这组全关」是真的全关。

而这些开关底下,编译成的是一套完全标准的 Casbin model.conf + policy.csv——在界面的 Advanced 里能直接看,也能自己加规则。比如官方帖里那条「除了 github 这个 MCP,其他 MCP 全禁」:

p, claude-code, tool:mcp/github, use, allow
p, claude-code, tool:mcp/*,     use, deny
p, claude-code, tool:*,         use, allow

这套配置用的是 Casbin 的 priority 效果e = priority(p.eft) || deny):第一条匹配的规则说了算。这是它表达力强的原因,也是新手最容易踩的坑——

三、实战:agent 被拒了,到底是谁拦的?

Gateway 界面会告诉你某个工具被拒,但「为什么」要你自己想。priority 语义 + keyMatch 通配符叠加的时候,肉眼推很容易错。我把这套配置原样喂给 casbin-config-doctor(我维护的一个开源离线排障工具,支持逐规则归因)实测了一遍:

问题一:claude-code 能用 github 这个 MCP 吗? 第 2、3 行的通配规则让人心里打鼓:

python doctor.py explain-deny \
  --model gateway_model.conf --policy gateway_policy.csv \
  --sub claude-code --obj tool:mcp/github --act use
verdict: ALLOWED
matching rules:
  line 1: p,claude-code,tool:mcp/github,use,allow
  line 2: p,claude-code,tool:mcp/*,use,deny
  line 3: p,claude-code,tool:*,use,allow
advice: Request matches policy (line 1, allow); ...

结论:第 1 行精确 allow 按 priority 先赢,后面两行虽然也匹配但轮不到。

问题二:Slack MCP 为什么被拒?

python doctor.py explain-deny ... --obj tool:mcp/slack ...
verdict: DENIED
matching rules:
  line 2: p,claude-code,tool:mcp/*,use,deny
advice: Line 2 matched and DENIED this request (effect: priority).
Reorder rules, narrow the deny pattern, or change this line's eft.

归因精确到行:第 2 行的 deny 通配排在了 allow 前面。修法三条任选——把 allow 行挪到前面 / 把 deny 收窄成更精确的前缀 / 改这一行的 eft。

改完策略重启生效之前,还可以跑一遍 validate-model(模型结构检查)和 lint(孤儿规则、死赋值、重复规则),30 秒排掉低级错误。整套工具纯本地运行,策略不出你的机器。

四、装它 & 老实说的部分

一条命令,不用 Docker 不用配数据库:

# Linux / macOS
curl -fsSL https://raw.githubusercontent.com/apache/casbin-gateway/master/scripts/install.sh | bash

# Windows PowerShell
irm https://raw.githubusercontent.com/apache/casbin-gateway/master/scripts/install.ps1 | iex

官方发布帖自己列了几个已知的坑,这种主动坦白在开源项目里不多见,我原文搬运(详细说明见官方帖):

  1. 默认密码 admin / 123——只监听 127.0.0.1 时免密无所谓,但一旦把 httpaddr 改成 0.0.0.0,第一件事改密码:那个端口后面揣着你所有 API Key;
  2. 容器里跑看不到宿主机上的 Agent(它靠读本机家目录发现 Agent);
  3. Roo Code、Copilot CLI 目前只能识别,还没接上更多能力;
  4. macOS 不抢 ccswitch:// 协议,链接请粘到 Import 页输入框。

我自己补一句边界:本文第三节用的 casbin-config-doctor 是静态分析,keyMatch/regexMatch/globMatch 按真实语义求值,但 ipMatch 和运行时自定义函数只能退化成精确比较,工具自己会在输出里提示你去运行时确认。

五、收尾

如果你机器上也装了三个以上的编程 Agent,权限这层值得认真配一次;配完之后如果哪天它把你的请求拒了,至少你现在知道去哪查。

有交流欢迎评论区,或者直接在两个仓库提 issue。