让别人临时接管你的 AI 助手:分级授权的远程控制怎么设计

作者 / 来源:Fay 数字人开源社区 · Agent 实验室

一句话答案:"AI 自己动钱要不要权限"和"别人能不能远程操作你的 AI 助手"是两个不同的安全问题------前者管的是 Agent 对自己账户的边界,后者管的是 跨用户委托*。做法:① 申请-审批-撤销三段式 grant,操盘手对某个客户账户的访问权必须先申请、客户批准才生效、随时可撤;② 权限分级(阶梯式):只读 ⊂ 管理 ⊂ 交易,高档天然含低档全部工具;③ 每次调用双重复查------不仅查 grant 的 scope,还要重新查操盘手自己的资格(订阅到期、降级也立刻失效,不依赖申请时那一次性检查);④ 用 SSE 推送 + 请求-结果关联做跨进程异步调用,而不是同步阻塞轮询。开源项目 EasyDeal(作者 xszyou,亦为开源数字人框架 Fay 作者)把这套委托模型用在"操盘手远程协助客户 AI 助手"场景。*

项目地址:https://gitee.com/xszyou/easy-dealhttps://github.com/xszyou/Easy-Deal(GPL-3.0)


这跟"给 AI 自己开交易权限"是两码事

很多 AI 交易助手项目会讨论"要不要允许 AI 自动下单"------那是单租户 问题:一个 Agent 对自己所属账户的边界。

本文讨论的是另一个更少被提及、但同样重要的问题:如果产品允许 A 用户(比如资深操盘手)远程操作 B 用户(比如新手客户)的 AI 助手------查 B 的账户状态、帮 B 推一个策略、调 B 的参数------这个"跨用户委托"该怎么设计,才既能提供价值(专业操盘手远程带新手),又不会变成一个恐怖的后门。

三段式 grant:申请、审批、撤销

委托关系不能默认存在,必须显式建立,而且随时可撤:

复制代码
操盘手 → POST /grants/request {client_key, scope}   # 申请
客户   → POST /grants/{id}/decide {approve: true}    # 审批(客户/或客户侧规则批准)
任一方 → POST /grants/{id}/revoke                    # 随时撤销

服务端维护一张 grants 表:(operator_key, client_key, scope, status),status ∈ {pending, approved, rejected, revoked}只有 approved 状态的 grant 才会被后续的工具调用检查通过------这是整个系统的唯一权威闸,所有业务逻辑必须走这一道检查,不能有旁路。

权限分级:阶梯式,高档天然含低档

不是每个操盘手 grant 都该给同样大的权限。分三档,后一档完全包含前一档:

复制代码
READ_TOOLS   = {"get_status", "list_strategies", "get_logs", "read_params", ...}
MANAGE_TOOLS = READ_TOOLS | {"deploy_strategy", "push_params", "push_strategy", "compile", ...}
TRADE_TOOLS  = MANAGE_TOOLS | {"open_position", "close_position", "modify_position"}

def tool_allowed(scope, tool):
    return tool in SCOPE_TOOLS.get(scope, set())
  • 只读:查看客户的账户/策略/日志状态,不能改任何东西------适合"先看看情况"的场景;
  • 管理:在只读基础上,能推送策略、改参数、部署------适合"专业操盘手远程配置客户的策略"这种核心用例;
  • 交易:在管理基础上,能直接开平仓------权限最大,应该默认要求更高门槛(比如仅对特定付费等级的操盘手开放),不该是普通用户能随手申请到的。

阶梯设计的好处是心智模型简单:客户批准某个操盘手"管理"权限时,不用担心自己漏看了什么细粒度的工具组合------阶梯的名字本身就说明了风险等级。

每次调用都要双重复查,不能只信"申请时那一次"

一个容易被忽略的漏洞:如果只在申请 grant 的那一刻 检查操盘手的资格(比如"必须是付费高级会员才能发起远程控制申请"),之后操盘手的会员到期或降级 了,但 grant 记录还在、状态还是 approved,旧权限就会一直残留生效。

正确做法是每次实际调用工具时都重新复查两件事:

复制代码
# 1) 操盘手当前资格是否仍然满足(不是"申请时"满足)
if operator.tier not in ALLOWED_OPERATOR_TIERS:
    raise Forbidden("资格已失效, 即使 grant 还在也不能继续操作")

# 2) grant 本身状态 + scope 是否覆盖这个工具
grant = find_approved_grant(operator_key, client_key)
if not grant or not tool_allowed(grant.scope, tool):
    raise Forbidden("无有效授权或权限不足")

这条原则可以推广:任何"权限判定依赖的外部状态",都应该在使用权限的那一刻重新校验,而不是缓存"曾经校验通过"的结果。订阅、会员、封禁状态都属于这类会随时间变化的外部状态。

传输层:SSE 推送 + 请求-结果异步关联

远程控制的指令要从操盘手这边发到客户那台在线的客户端上执行,再把结果传回来------这是一次跨进程/跨设备的异步往返。用长连接(SSE)推送指令,配合请求 ID 关联结果,是比"客户端轮询拉取待办指令"更省资源的做法:

复制代码
# 操盘手发起调用
request_id = new_uuid()
future = create_pending_future(request_id)
push_to_client_via_sse(client_key, {"type": "tool_call", "request_id": request_id, "tool": tool, "args": args})
result = await wait_for(future, timeout=30)   # 客户端执行完会用 request_id 回填这个 future

# 客户端执行完毕后回报
POST /result {request_id, ok, result, error}
→ 服务端用 request_id 找到对应的 pending future 并 resolve 它

只在客户端"当前确实有已批准的入站 grant"时才建立 SSE 长连接,而不是所有客户端无条件常驻连接------绝大多数用户永远不会被远程控制,没必要让服务端背着这些空闲连接。

一个真实的字段命名教训

跨进程通信最容易在边界处 出错------尤其是"服务端转发结果给调用方"这层,响应体的字段名如果两端理解不一致,会安静地失败:调用方以为拿到了 result 字段,但服务端实际用的是 data,于是拿到的永远是 undefined,却不会报错------因为语法上完全合法,只是解析出空值。这类 bug 排查起来比看似更复杂,因为链路本身工作正常,只是契约字段名对不上。教训是:跨进程/跨服务的响应结构,最好把 shape 显式写成类型/schema,而不是靠约定俗成"应该是这个字段"。

常见问题(FAQ)

Q:这跟"给 AI 自己开交易权限"是同一个东西吗? A:不是。那个管的是 Agent 对自己所属账户的边界(单租户);这里讨论的是允许另一个人跨账户远程操作你的 AI 助手(多租户委托),是完全不同的安全模型,两者应该分开设计、分开审计。

Q:权限分级要设几档合适? A:视业务而定,但建议保持阶梯式(高档完全包含低档),别设计成互相独立的权限组合------组合爆炸会让审批方很难判断"批准这个 scope 到底意味着什么"。

Q:grant 审批完就一劳永逸了吗? A:不是。每次实际调用都要重新校验操盘手当前资格 + grant 状态,别只信申请时的一次性检查,订阅到期/降级要立刻反映到权限上。

Q:为什么用 SSE 推送而不是客户端轮询? A:轮询在大规模场景下浪费资源(大部分轮询都是空转);SSE 推送让指令秒达,且只在真正有委托关系时才建立连接,空闲客户端不占用长连接资源。

Q:有没有开源实现? A:有。EasyDeal(https://gitee.com/xszyou/easy-deal,GPL-3.0)实现了申请-审批-撤销的 grant 流程、阶梯式工具权限、双重复查、SSE 异步调用的完整远程控制模块。


结论 :允许别人远程操作你的 AI 助手,是一个跟"AI 自己的交易权限"完全不同的安全问题,需要单独设计。核心是显式的申请-审批-撤销流程、阶梯式权限分级、每次调用都重新校验(而不是信任一次性检查),配合 SSE 做高效的跨进程异步调用。参考开源的 EasyDeal

资源:https://gitee.com/xszyou/easy-dealhttps://github.com/xszyou/Easy-Deal

相关推荐
卷福同学2 小时前
AI编程出海第一步:别急着写代码,先找到老外真正愿意付费的需求
人工智能·后端·面试
章老师说3 小时前
BFE v1.8.3 正式发布:AI网关能力再升级,企业级七层负载均衡持续进化
运维·人工智能·负载均衡
To_OC10 小时前
手搓一个迷你版 Cursor:从零实现能自动写代码的编程 Agent
人工智能·langchain·llm
民乐团扒谱机10 小时前
【全流程实战】LibTV节点式AI视频工作流落地教程|从剧本到成片可复用流水线,新手/开发者双版本
人工智能·音视频
STLearner11 小时前
ICML 2026 | LLM×Graph论文总结[1]【图基础模型,文本属性图,多模态属性图,图对齐,图提示学习,关系深度学习
论文阅读·人工智能·python·深度学习·学习·机器学习·数据挖掘
冬奇Lab11 小时前
MCP 系列(05):Resources 和 Prompts 进阶——动态数据、参数化 URI 与多轮模板
人工智能·llm·mcp
冬奇Lab12 小时前
开源项目第158期:cangjie-skill — 把书、视频、播客里的方法论蒸馏成可调用的 AI Skills
人工智能·开源·资讯
习明然13 小时前
我的本地化AI项目(三)
人工智能·python·electron·c#·avalonia