ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

IronClaw Google Drive 权限清单:list_permissions 工具的参数、Schema 与 WASM 实现解析

IronClaw Google Drive 权限清单:list_permissions 工具的参数、Schema 与 WASM 实现解析 人工智能AI 应用交互助手AI Agent【免费下载链接】ironclawIronClaw is an Agent OS focused on privacy, security and extensibility项目地址https://gitcode.com/gh_mirrors/iro/ironclaw点击查看免费下载IronClaw 以「扩展即包package」的方式把 Google Drive 能力打包成 12 个独立工具其中google-drive.list_permissions负责回答一个关键问题这个文件/文件夹当前被分享给了谁、各持有什么角色。本文以 list_permissions.md 为线索结合输入 Schema、manifest 配置与 WASM 客端源码完整拆解该工具的调用约定、安全模型与底层实现读完即可理解如何在 Agent 会话中正确触发它以及它背后「host 注入凭据、客端零接触令牌」的设计逻辑。工具定位由 host 按 capability id 选择操作的声明式调用在 IronClaw 的扩展体系中工具提示词prompt doc不是给用户看的操作手册而是给模型Agent看的「能力声明」。list_permissions.md全文只有两句约束List file permissions.—— 工具职责列出文件权限。The host selects this operation from the capability id. Provide only the parameters described by the input schema; do not include an action field.—— 关键调用约定操作选择权在 host 侧Agent 只需要按输入 Schema 提供参数严禁自行添加action字段。这与 lib.rs 中的运行时逻辑一一对应WASM 客端通过action_from_context从 host 注入的ToolContext.capability_id解析出具体操作google-drive.list_permissions→list_permissions随后params_with_action会把action以内部方式合并进参数并主动拒绝用户侧提交的action字段返回invalid_parameters。也就是说Agent 永远不会直接选择「我要执行 list_permissions」它只会响应 host 基于 capability 暴露的调用请求。该工具属于 google-drive 包 12 个工具之一google-drive.list_files…google-drive.list_shared_drives整个包是data-only package不包含 Rust crate工具实体以 WASM 客端形式随包分发。输入参数唯一必填项 file_id工具的全部入参定义在 list_permissions.input.v1.json这是一个 JSON Schema draft-07 描述{ $schema: http://json-schema.org/draft-07/schema#, title: Google Drive list_permissions, description: List file permissions., type: object, required: [file_id], properties: { file_id: { type: string, description: The file ID. } }, additionalProperties: false }要点拆解字段类型必填说明file_idstring是Google Drive 文件或文件夹的 ID来自list_files/get_file等操作返回结果additionalProperties: false意味着传任何未声明字段都会被 Schema 拒绝这与「不要传action」的提示词约束形成双保险。与 types.rs 中的GoogleDriveAction::ListPermissions { file_id }变体一致——这是整个 12 个操作中仅有的几个「单必填字段」操作之一比list_files全部可选参数更严格。值得注意的还有包内的 raw_output.v1.json它声明「Google API response serialized by the WASM tool」即本工具以及同包其他工具的响应由 WASM 客端序列化后直接上送 hosthost 不做二次解释。从 manifest 看安全与凭据模型工具级声明位于 manifest.tomlgoogle-drive.list_permissions一节完整定义了它的安全边界[[tools]] origin_gate_matrix { loop_run gated_unless_granted, product forbidden, automation forbidden } id google-drive.list_permissions description List file permissions. effects [network, use_secret] default_permission ask visibility model input_schema_ref schemas/google-drive/list_permissions.input.v1.json prompt_doc_ref prompts/google-drive/list_permissions.md [[tools.credentials]] handle google_runtime_token vendor google scopes [https://www.googleapis.com/auth/drive.readonly] audience { scheme https, host www.googleapis.com } injection { type header, name authorization, prefix Bearer }这些字段的实际含义origin_gate_matrix工具按调用来源设置访问门槛。loop_run下为gated_unless_grantedAgent 主循环中默认需要显式授权/批准才能执行而product、automation场景一律forbidden——这意味着该工具只面向 Agent 会话开放禁止在产品/自动化入口直接调用。effects声明副作用为networkuse_secret。对比同包share_file/delete_file等写操作多出的external_writelist_permissions是纯读操作不会产生外部写入。default_permission ask首次调用需要用户确认结合 origin gate属于典型的「敏感能力需批准」模式。credentials 注入使用 vendor 为google的google_runtime_token作用域仅为https://www.googleapis.com/auth/drive.readonly只读无法改权限host 会以Authorization: Bearer token请求头形式注入。WASM 客端永远看不到 OAuth 令牌本体——api.rs 头部注释明确写道「All API calls go through the hosts HTTP capability, which handles credential injection and rate limiting. The WASM tool never sees the actual OAuth token.」这正是 IronClaw「凭据不出沙箱」的隐私设计核心。OAuth 流程本身由[auth.google]段配置oauth2_code授权码模式 PKCE S256授权端点https://accounts.google.com/o/oauth2/v2/auth令牌端点https://oauth2.googleapis.com/token应用级 client_id/client_secret 由部署方在[admin_configuration]的google_oauth_client_id/google_oauth_client_secret中提供并被所有google-*扩展共享group_id vendor.google。WASM 实现一次 GET 请求与精确的字段裁剪核心实现在 api.rs 的 list_permissions 函数pub fn list_permissions(file_id: str) - ResultListPermissionsResult, GuestFailure { let path format!( files/{}/permissions?fieldspermissions(id,role,type,emailAddress,displayName)supportsAllDrivestrue, url_encode(file_id) ); let response api_call(GET, path, None)?; let parsed: serde_json::Value serde_json::from_str(response).map_err(|e| serialization_failure(e))?; let permissions parsed[permissions] .as_array() .map(|arr| { arr.iter() .map(|p| Permission { id: p[id].as_str().unwrap_or().to_string(), role: p[role].as_str().unwrap_or().to_string(), permission_type: p[type].as_str().unwrap_or().to_string(), email_address: p[emailAddress].as_str().map(|s| s.to_string()), display_name: p[displayName].as_str().map(|s| s.to_string()), }) .collect() }) .unwrap_or_default(); Ok(ListPermissionsResult { permissions }) }实现要点端点GET https://www.googleapis.com/drive/v3/files/{file_id}/permissionsfile_id经url_encode处理见 url_encodeAPI 基址常量DRIVE_API_BASE https://www.googleapis.com/drive/v3。fields 裁剪fieldspermissions(id,role,type,emailAddress,displayName)精确限定响应字段避免拉取无关大字段减少带宽与 token 消耗。supportsAllDrivestrue与同包其他操作保持一致使查询对共享盘shared drive中的文件同样生效。解析容错对缺失字段一律回退为空值/None避免上游字段缺失导致整个工具失败permissions数组缺失时返回空列表而非报错。统一错误映射所有 HTTP 调用经由api_call走 host 的http_request能力非 2xx 状态码会进入api_status_error——401 映射为ErrorKind::AuthRequired并携带稳定错误码google_api_error_status_401其余状态映射为ErrorKind::Client与api_status_{status}api.rs 测试 验证了 401 与 429 两条路径。响应结构一条权限记录包含哪些信息工具返回 JSON 形如{ permissions: [ { id: 0B12345..., role: writer, type: user, emailAddress: aliceexample.com, displayName: Alice } ] }对应 types.rs 的 Permission 结构字段类型说明idstring权限记录 ID是后续remove_permission撤销权限时必需的回执标识rolestring角色如reader、commenter、writer、organizertypestring权限主体类型序列化为permission_type字段名保留关键字type如user、group、domain、anyoneemailAddressstring?主体邮箱用户/群组类型时存在displayNamestring?主体显示名idrole的组合是完整权限审计的最小信息单元list_permissions负责「看清现状」而修改现状由同包的两个写操作完成——share_filePOSTfiles/{file_id}/permissions以typeuserroleemailAddress创建新权限与remove_permissionDELETEfiles/{file_id}/permissions/{permission_id}按权限 ID 撤销三个工具构成完整的权限生命周期闭环且写操作都携带external_writeeffect 与drive非只读作用域安全级别与只读的list_permissions明确区分。测试与交付Schema 一致性由 schemars 保证types.rs 的测试 揭示了本项目一个值得借鉴的工程实践工具对外公布的 Schema 不再手写而是通过schemars::JsonSchema派生自GoogleDriveAction枚举每个操作变体生成oneOf分支并带各自的required数组。测试明确断言get_file分支的required必须包含file_id此前手写 Schema 把所有字段声明为可选导致 Agent 频繁构造出缺字段的非法调用list_files分支不得要求file_id它本来就没有该参数只要求判别字段action。这意味着list_permissions的「file_id必填」约束同时存在于声明 Schema、serde 反序列化层与运行期校验三层杜绝了「Schema 说可选、代码说必填」的漂移问题。在交付侧该包由 ironclaw_extension_support 的 gsuite.rs 以include_str!/include_bytes!方式内嵌 manifest 与 google_drive_tool.wasm 编译产物仓库 CI 通过python3 scripts/ci/check-wasm-artifact-freshness.py校验 WASM 产物与源码一致性manifest 投影则由cargo test -p ironclaw_extension_registry覆盖。常见问题与排查指引误传action字段提示词与 Schema 双重禁止WASM 客端会以invalid_parameters拒绝——Agent 调用时只传{file_id: ...}即可。401 / 令牌失效返回AuthRequired与google_api_error_status_401说明drive.readonly作用域令牌缺失或过期需要重新走[auth.google]的 OAuth 授权流程。找不到任何权限可能原因包括file_id不属于当前账户可访问范围或文件从未被分享permissions为空数组结合supportsAllDrivestrue对共享盘文件同样可用。想查共享盘先使用google-drive.list_shared_drives拿到共享盘 ID再配合list_filescorporadrive、drive_id...定位具体文件最后用list_permissions审计其权限。小结google-drive.list_permissions是 IronClaw 扩展体系中「只读审计型工具」的典型样本声明式提示词把操作选择权交给 host、JSON Schema 用requiredadditionalProperties: false约束入参、manifest 以drive.readonly作用域 gated_unless_grantedask默认权限层层设防而 WASM 客端仅凭 host 注入的 Bearer 令牌完成一次字段精确裁剪的 GET 请求。理解了它也就理解了整个google-drive包乃至 IronClaw 扩展框架「最小权限 凭据隔离 Schema 一致性」的设计哲学。赞分享人工智能AI 应用交互助手AI Agent【免费下载链接】ironclawIronClaw is an Agent OS focused on privacy, security and extensibility项目地址https://gitcode.com/gh_mirrors/iro/ironclaw点击查看免费下载相关推荐IronClaw 中使用 github.list_releases 工具查询仓库发布版本参数规范、WASM 实现与鉴权机制IronClaw 中使用 github.list_releases 工具查询仓库发布版本参数规范、WASM 实现与鉴权机制 本篇技术指南围绕 IronClaw人工智能AI 应用交互助手AI AgentIronClaw google-docs 扩展完全指南语义化文档工作流与 WASM 工具实现解析IronClaw google docs 扩展完全指南语义化文档工作流与 WASM 工具实现解析 本文以 IronClaw 开源仓库中 google docs人工智能AI 应用交互助手AI AgentIronClaw 谷歌日历提醒设置工具 google-calendar.set_reminder 实战指南事件提醒配置的权限、参数与源码实现IronClaw 谷歌日历提醒设置工具 google calendar.set_reminder 实战指南事件提醒配置的权限、参数与源码实现 本文以 Iron人工智能AI 应用交互助手AI Agent创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进