如何限制一个 Skill 的执行权限?比如禁止访问文件系统或网络。

面试官:“在 Agent 框架里,怎么限制一个 Skill 的执行权限?比如不让它访问文件系统或随便调网络?”

候选人:

“限制 Skill 权限,本质上是在信任但验证,尤其当 Skill 来自第三方时。我的设计原则是:默认什么都没有,显式声明才授权,运行时隔离不越界。 我把整个方案分成四道防线,从开发声明到硬件隔离,层层收紧。


第一道防线:元信息权限声明

Skill 开发者必须在元信息里显式声明这个 Skill 需要哪些能力,比如:

{
  "permissions": {
    "network": {
      "allowed": true,
      "domains": ["api.weather.com", "smtp.company.com"],
      "protocols": ["HTTPS"]
    },
    "file_system": {
      "allowed": false
    },
    "exec": {
      "allowed": false
    },
    "environment_variables": ["DATABASE_URL_READONLY"]
  }
}

如果元信息里没声明某权限,默认就是禁止。审核阶段就会检查这些声明是否合理——一个天气 Skill 申请文件系统权限会被直接打回。这一步在提交时就能拦截大部分过度申请。


第二道防线:API 网关 / 能力代理

Skill 不能直接调用系统 API 或网络,而是必须通过 Agent 框架提供的一个能力网关(Capability Gateway)。

这个网关的工作机制是:

  • Skill 执行时,所有的外部调用(比如发 HTTP 请求、读文件)都不是直接操作,而是向网关请求。

  • 网关拿到请求后,检查该 Skill 的元信息权限声明。如果 Skill 声明了可以访问 api.weather.com,且请求确实是这个域名,就放行;如果它偷偷请求 http://internal-admin:8080/secrets,网关直接拒绝并告警。

  • 对于文件系统,网关只暴露一个虚拟的临时目录,Skill 写入的文件实际被重定向到沙箱内的存储,无法触碰宿主机真实文件。

实际上,这就是把操作系统的系统调用层面拦截下来,换成一套可控的代理。类似手机系统里 App 不能直接调摄像头,必须通过系统 API,系统弹出权限提示。


第三道防线:沙箱隔离

API 网关防的是明面上的调用,但如果 Skill 代码里有恶意逻辑想绕过网关怎么办?比如它直接用 JNI 调本地方法,或者通过反射攻击框架。这时候需要沙箱隔离。

常见的沙箱方案有三个层次,根据安全等级选择:

查看内嵌表格

我更倾向用 WASM(WebAssembly)沙箱,因为它启动快(微秒级)、体积小,而且天然不允许访问文件系统、网络等宿主机资源,除非宿主机显式导入函数给它。把 Skill 编译成 WASM 字节码,在 wasmtime 这类运行时里跑,它就只能调用我们白名单里注入的几个函数,连系统调用层都碰不到。

如果 Skill 是 Python 或 Shell 写的,可以放进一个最小化的 Docker 容器,去掉所有 CAP 权限,文件系统只读挂载,网络仅开放声明过的域名。


第四道防线:资源限制与审计

即便 Skill 权限合规,也可能滥用资源,比如疯狂发请求或写满磁盘。所以要加资源配额:

  • CPU 时间限制:单次执行最长 5 秒。

  • 内存限制:最大堆内存 64MB。

  • 网络速率:每秒最多 10 次外部请求。

  • 磁盘写入:最多 10MB 临时数据。

所有 Skill 的行为都记录审计日志:谁在什么时间、调用了哪个 Skill、访问了哪些资源、结果如何。异常行为(比如越权尝试)实时告警。