OpenClaw.NET 外部 CLI 连接器 (External CLI Connectors) 详细技术总结

📅 2026/6/24 2:20:07
OpenClaw.NET 外部 CLI 连接器 (External CLI Connectors) 详细技术总结
一、架构概述External CLI Connectors是 OpenClaw.NET 的一个受控原生工具 (external_cli)用于将官方平台 CLI如 GitHub CLI、Azure CLI、kubectl、Stripe CLI、Lark/Feishu CLI 等包装为可被 AI Agent 安全调用的工具。核心设计哲学默认禁用— 功能不会自动启用需要显式配置不是通用 Shell— 不接受任意命令字符串只允许预配置的具名命令深度防御— 通过命名命令白名单、风险评分、预览、审批、脱敏、超时、审计记录和运行时事件实现多层安全控制二、安全模型 (Security Model)2.1 核心安全原则外部 CLI 可以在强大的用户、机器人、云、集群或支付身份下运行因此所有变更性命令 (mutating commands)被视为高风险使用最小权限原则 (least privilege)支持dry-run 预览、审批流程和审计日志2.2 命令调用方式连接器不接受原始命令字符串。Agent 通过指定连接器名、命令名和命名参数来调用{ action: execute, connector: gh, command: issue_list, parameters: { repo: clawdotnet/openclaw.net } }运行时通过配置化的参数模板直接展开为ProcessStartInfo.ArgumentList不经过 Shell 解释器且拒绝缺失或未知参数除非命令显式允许。2.3 关键安全默认值配置项默认值含义Enabledfalse默认不注册工具AllowFreeformCommandsfalse拒绝自由形式命令RequireApprovalForMutatingCommandstrue非只读命令需要审批RiskLevelhigh默认高风险总是需要审批ReadOnlyfalse默认可变操作三、配置系统详解3.1 顶层配置结构{ OpenClaw: { ExternalCli: { Enabled: true, // 总开关 DefaultTimeoutSeconds: 60, // 默认超时 MaxStdoutBytes: 262144, // stdout 最大字节数 (256KB) MaxStderrBytes: 65536, // stderr 最大字节数 (64KB) RedactSecrets: true, // 启用密钥脱敏 AllowFreeformCommands: false, // 禁止自由命令 RequireApprovalForMutatingCommands: true, // 变更命令需审批 Connectors: { // 连接器配置 // 各平台CLI连接器定义 } } } }3.2 连接器配置结构以GitHub CLI (gh)为例{ gh: { Enabled: true, DisplayName: GitHub CLI, Executable: gh, DefaultOutputFormat: json, StatusCommand: { Args: [auth, status], TimeoutSeconds: 20 }, VersionCommand: { Args: [--version], TimeoutSeconds: 10 }, Commands: { repo_view: { Description: View repository metadata, ArgsTemplate: [ repo, view, {{repo}}, --json, name,owner,description,url,isPrivate ], RiskLevel: low, ReadOnly: true, StructuredOutput: json, Parameters: { repo: { Required: true, Pattern: ^[A-Za-z0-9_.-]/[A-Za-z0-9_.-]$ } } }, issue_create: { Description: Create a GitHub issue, ArgsTemplate: [ issue, create, --repo, {{repo}}, --title, {{title}}, --body, {{body}} ], RiskLevel: medium, ReadOnly: false, RequiresApproval: true, StructuredOutput: text, Parameters: { repo: { Required: true }, title: { Required: true, MaxLength: 200 }, body: { Required: true, MaxLength: 16000 } } } } } }3.3 命令配置选项说明字段类型说明Descriptionstring命令描述ArgsTemplatestring[]参数模板{{param}}占位符将被替换RiskLevelstring风险等级:low/medium/highReadOnlybool是否为只读操作RequiresApprovalbool是否需要审批覆盖默认策略StructuredOutputstring输出格式:json/ndjson/csv/table/textDryRunArgsTemplatestring[](可选) Dry-run 模式的参数模板Parametersdict参数定义含 Required/MaxLength/Pattern/AllowedValuesRedactionRulesstring[](可选) 平台特定的密钥脱敏规则RequiredScopesstring[](可选) 所需身份/权限范围RequiredIdentitystring(可选) 所需身份标识TimeoutSecondsint(可选) 命令级别超时覆盖WorkingDirectorystring(可选) 工作目录Environmentdict(可选) 环境变量3.4 参数验证选项每个参数可配置Required— 是否必填Description— 参数描述MaxLength— 最大长度限制Pattern— 正则表达式验证AllowedValues— 允许值列表四、预览与审批流程 (Preview Approval)4.1 预览命令openclaw external preview gh repo_view --param repoclawdotnet/openclaw.net4.2 预览返回信息字段说明可执行文件路径解析后的 CLI 路径参数列表展开的参数已脱敏风险等级low / medium / high操作类型只读 (ReadOnly) 或变更 (Mutating)是否需要审批true / false输出格式json / ndjson / csv / table / text所需身份/权限范围如配置了 RequiredScopes审批指纹 (Approval Fingerprint)稳定的指纹值用于审批匹配4.3 执行审批流程# 1. 先预览 openclaw external preview gh issue_create \ --param repoclawdotnet/openclaw.net \ --param titleExample \ --param bodyExample body # 2. 确认后加 --yes 执行自动携带指纹 openclaw external execute gh issue_create \ --param repoclawdotnet/openclaw.net \ --param titleExample \ --param bodyExample body \ --yes指纹安全机制如果命令模板、解析参数或策略在审批和执行之间发生变化指纹不匹配将导致执行被阻止。4.4 Dry-Run 支持预览时加上--dry-run可执行 dry-run 模式需命令配置了DryRunArgsTemplateopenclaw external preview gh issue_create \ --param repoclawdotnet/openclaw.net \ --param titleTest \ --param bodyTest body \ --dry-run注意运行时不会猜测dry-run 标志必须在模板中显式配置。五、审计、事件与脱敏 (Audit, Events Redaction)5.1 审计记录 (Append-Only Audit)每次执行写入不可篡改的审计记录包含连接器名和命令名可执行文件路径已脱敏的命令行预览参数和参数哈希执行者、会话、频道、发送者审批指纹如有退出码、执行时长、超时标志stdout/stderr 截断标志风险等级和工作目录5.2 运行时事件触发以下事件类型status_check— 状态检查previewed/dry_run_previewed— 预览dry_run_executed— Dry-run 执行command_executed— 命令执行command_failed— 命令失败command_timed_out— 超时truncation— 输出截断redaction— 密钥脱敏command_blocked_by_policy— 策略阻止5.3 密钥脱敏 (Redaction)脱敏应用于参数预览、stdout、stderr、审计记录、运行时事件、错误消息。可为连接器或命令配置RedactionRules支持平台特定的密钥格式。六、输出解析 (Output Parsing)按命令配置StructuredOutput格式处理方式json解析 stdout 为 JSON返回解析后的 JSON 脱敏 stdoutndjson解析换行分隔 JSON 为 JSON 数组csv/table/text作为脱敏文本返回注意连接器不会注入全局--json标志需要在每个命令模板中显式放置输出标志。七、推荐配置预设 (Conservative Presets)7.1 GitHub CLI (gh)类别命令示例只读auth status,repo view,issue list,pr list,pr view,release list需审批issue create,issue comment,pr review,pr merge,release create7.2 Azure CLI (az)类别命令示例只读account show,group list,resource list,webapp list需审批resource create/update/delete,deployment create,role assignment changes7.3 kubectl类别命令示例只读config current-context,get pods/services/deployments -o json,describe高风险需审批apply,delete,scale,rollout restart,exec,port-forward日志可能暴露密钥建议至少 medium 风险等级。7.4 Stripe CLI类别命令示例只读listen status,fixtures/list,customers/list最小权限凭证高风险需审批payment mutations,refunds,customer/subscription mutations,webhook trigger,event replay7.5 Lark / Feishu CLI类别命令示例只读auth status, schema inspection,calendar agenda, docs search/read, sheets read, mail search/read, meeting minutes query需审批send messages, write docs, write sheets, send email, approve/reject workflows, create/update OKRs, raw API calls八、管理 API (Admin API)网关暴露以下 RESTful 端点方法端点说明GET/admin/external-cli/connectors列出所有连接器GET/admin/external-cli/connectors/{connector}获取连接器状态GET/admin/external-cli/connectors/{connector}/commands列出连接器命令POST/admin/external-cli/preview预览命令需 CSRFPOST/admin/external-cli/execute执行命令需 operator 角色 匹配审批元数据九、CLI 命令# 列出所有连接器 openclaw external list # 查看连接器状态 openclaw external status gh # 列出连接器命令 openclaw external commands gh # 预览命令 openclaw external preview gh repo_view --param repoclawdotnet/openclaw.net # 执行命令 openclaw external execute gh repo_view --param repoclawdotnet/openclaw.net # 使用 --json 获取机器可读输出 openclaw external list --json十、代码实现架构 (Commit bde72ea)10.1 项目结构本次 Commit 共修改29 个文件2,966 行代码涉及以下模块docs/ EXTERNAL_CLI_CONNECTORS.md # 新增完整文档 (278行) README.md # 添加文档链接 SITE_MAP.md # 添加站点地图 src/OpenClaw.Agent/ OpenClawToolExecutor.cs # 工具执行器集成 (29/-4) Tools/ExternalCliTool.cs # 新增 External CLI 工具实现 (251行) src/OpenClaw.Client/ OpenClawHttpClient.cs # HTTP 客户端新增 Admin API 方法 (51行) src/OpenClaw.Cli/ CliArgs.cs # CLI 参数解析扩展 ExternalCliCommands.cs # 新增 CLI 命令实现 (250行) OpenClawHttpClient.cs # CLI HTTP 客户端包装 (15行) Program.cs # 注册 external 子命令 (3行) src/OpenClaw.Core/ Abstractions/IToolActionDescriptorProvider.cs # 抽象接口 ExternalCli/ ExternalCliServices.cs # DI 服务注册 ExternalCliConnectorRegistry.cs # 连接器注册表 ExternalCliRunner.cs # 命令执行器 Models/ ExternalCliModels.cs # 数据模型 (284行) GatewayConfig.cs # 配置集成 (1行) Session.cs # JSON 序列化 (26行) ToolingPolicyModels.cs # 策略模型 (4行) Pipeline/ToolActionPolicyResolver.cs # 策略解析 (27/-1) Validation/ConfigValidator.cs # 配置验证 (78行) src/OpenClaw.Gateway/ Composition/ # DI 组合注册 Endpoints/AdminEndpoints.ExternalCli.cs # Admin API 端点 (264行) Endpoints/ExternalCliStores.cs # 存储抽象 OpenClaw.Tests/ ExternalCliTests.cs # 单元测试10.2 核心类型与接口// 连接器注册表 public interface IExternalCliConnectorRegistry { ExternalCliPreparedInvocation BuildPreview(ExternalCliPreviewRequest request, bool dryRun); } // 命令执行器 public interface IExternalCliRunner { TaskExternalCliExecutionResult ExecuteAsync(ExternalCliPreparedInvocation prepared, CancellationToken ct); } // 审计 Sink public interface IExternalCliAuditSink { void Record(ExternalCliAuditEntry entry); } // 事件 Sink public interface IExternalCliEventSink { void Record(ExternalCliRuntimeEvent evt); }10.3 关键数据模型// 连接器配置选项 public sealed class ExternalCliConnectorOptions { public bool Enabled { get; set; } false; public string DisplayName { get; set; } ; public string Executable { get; set; } ; public string DefaultOutputFormat { get; set; } json; public ExternalCliStatusCommandOptions? StatusCommand { get; set; } public ExternalCliStatusCommandOptions? VersionCommand { get; set; } public Dictionarystring, ExternalCliCommandOptions Commands { get; set; } new(); // ... } // 命令配置选项 public sealed class ExternalCliCommandOptions { public string Description { get; set; } ; public string[] ArgsTemplate { get; set; } []; public string[]? DryRunArgsTemplate { get; set; } public string RiskLevel { get; set; } ExternalCliRiskLevel.High; public bool ReadOnly { get; set; } false; public bool RequiresApproval { get; set; } false; public string StructuredOutput { get; set; } ExternalCliOutputFormat.Text; public Dictionarystring, ExternalCliParameterOptions Parameters { get; set; } new(); // ... } // 执行结果 public sealed class ExternalCliExecutionResult { public ExternalCliInvocationPreview Preview { get; init; } new(); public int ExitCode { get; init; } public double DurationMs { get; init; } public bool TimedOut { get; init; } public bool Failed { get; init; } public bool StdoutTruncated { get; init; } public bool StderrTruncated { get; init; } // ... } // 审计记录 public sealed class ExternalCliAuditEntry { public string Id { get; init; } ; public DateTimeOffset TimestampUtc { get; init; } public string SessionId { get; init; } ; public string Connector { get; init; } ; public string Command { get; init; } ; public string RedactedArgsPreview { get; init; } ; public string? ApprovalFingerprint { get; init; } public int ExitCode { get; init; } // ... }10.4 执行流程Agent 调用→ExternalCliTool接收工具请求策略解析→ToolActionPolicyResolver解析操作描述符含 IsMutation、RequiresApproval、ApprovalFingerprint、RiskLevel、ReadOnly预览构建→ExternalCliConnectorRegistry.BuildPreview()解析模板、验证参数、计算指纹审批检查→ 如需审批比较指纹是否匹配执行命令→ExternalCliRunner.ExecuteAsync()通过ProcessStartInfo.ArgumentList启动进程输出解析→ 按StructuredOutput设置解析输出记录审计→ 写入ExternalCliAuditEntry不可篡改发送事件→ 通过ExternalCliEventSink发送运行时事件10.5 策略解析增强ToolActionDescriptor新增字段RequiresApproval— 是否需要审批ApprovalFingerprint— 审批指纹RiskLevel— 风险等级ReadOnly— 是否只读OpenClawToolExecutor中的审批逻辑增强支持指纹匹配验证如模板、参数或策略在审批后变更指纹不匹配将阻止执行十一、飞书 (Feishu/Lark) CLI 配置详细教程11.1 理解架构OpenClaw 通过外部 CLI 连接器调用lark-cli官方 npm 包larksuite/cli来操作飞书。这需要在飞书开放平台创建自建应用并获取凭证安装并配置lark-cli完成用户授权OAuth 2.0 设备授权流程在 OpenClaw 中配置 External CLI 连接器11.2 步骤一创建飞书自建应用1. 访问飞书开放平台国内版: https://open.feishu.cn国际版 (Lark): https://open.larksuite.com2. 创建应用登录后点击右上角「开发者后台」点击「创建应用」→ 选择「企业自建应用」填写应用名称如「我的AI助手」和描述点击「确认创建」3. 开启机器人能力左侧菜单 →「应用能力」→「机器人」点击「开启」4. 获取凭证左侧菜单 →「凭证与基础信息」复制以下信息备用App ID格式如cli_xxxxxxxxxApp Secret点击「查看」显示完整内容请妥善保管5. 开通权限左侧菜单 →「权限管理」搜索并开通以下权限权限用途docx:document:readonly查看、评论和导出云文档docx:document:write创建和编辑云文档drive:drive:readonly获取文件元信息drive:folder:write管理云空间中所有文件im:message发送/接收消息im:message.group_at_msg接收群聊 消息im:message:send_as_bot以机器人身份发送消息im:chat群聊管理im:resource消息资源search:docs:read搜索文档6. 发布应用左侧菜单 →「版本管理与发布」「创建版本」→ 填写版本说明 →「提交」等待审批企业内部应用通常自动通过11.3 步骤二安装与配置 lark-cli1. 安装 lark-cli# 全局安装 npm install -g larksuite/cli # 验证安装 lark-cli --version2. 配置凭证交互式lark-cli config init --new按提示输入 App ID 和 App Secret。3. 配置凭证非交互式/自动化echo 你的App Secret | lark-cli config init \ --app-id 你的AppID \ --app-secret-stdin \ --brand feishu--brand feishu用于国内版飞书国际版 Lark 使用--brand lark。4. 验证配置lark-cli doctor应显示配置正确、凭证有效。11.4 步骤三用户授权 (OAuth 2.0 设备授权)1. 发起授权请求lark-cli auth login --no-wait --recommend --json输出示例{ device_code: ABC123XYZ, user_code: ABCD1234, verification_url: https://open.feishu.cn/open-apis/authen/v1/scan?qrcode... }2. 完成授权复制verification_url到浏览器打开使用飞书 App 扫码确认。3. 完成登录扫码确认后执行lark-cli auth login --device-code ABC123XYZ4. 补充搜索权限如需文档搜索能力lark-cli auth login --no-wait --scope search:docs:read --json重复扫码授权流程。11.5 步骤四验证 lark-cli 功能# 搜索文档 lark-cli docs search --query 文档 --as user # 创建文档 lark-cli docs create --title 测试文档 --markdown # 你好世界 # 查询日历 lark-cli calendar agenda --as user # 发送消息 lark-cli message send --to-user user_open_id --text Hello from CLI11.6 步骤五在 OpenClaw 中配置 Feishu External CLI 连接器在 OpenClaw 配置文件中添加{ OpenClaw: { ExternalCli: { Enabled: true, DefaultTimeoutSeconds: 60, MaxStdoutBytes: 262144, MaxStderrBytes: 65536, RedactSecrets: true, AllowFreeformCommands: false, RequireApprovalForMutatingCommands: true, Connectors: { lark: { Enabled: true, DisplayName: Lark/Feishu CLI, Executable: lark-cli, DefaultOutputFormat: json, StatusCommand: { Args: [auth, status], TimeoutSeconds: 20 }, VersionCommand: { Args: [--version], TimeoutSeconds: 10 }, Commands: { auth_status: { Description: Check lark-cli auth status, ArgsTemplate: [auth, status], RiskLevel: low, ReadOnly: true, StructuredOutput: text, Parameters: {} }, docs_search: { Description: Search Feishu documents, ArgsTemplate: [docs, search, --query, {{query}}, --as, user, --json], RiskLevel: low, ReadOnly: true, StructuredOutput: json, Parameters: { query: { Required: true, MaxLength: 200 } } }, docs_read: { Description: Read a Feishu document, ArgsTemplate: [docs, get, {{doc_id}}, --as, user], RiskLevel: low, ReadOnly: true, StructuredOutput: json, Parameters: { doc_id: { Required: true } } }, docs_create: { Description: Create a Feishu document, ArgsTemplate: [docs, create, --title, {{title}}, --markdown, {{content}}], RiskLevel: medium, ReadOnly: false, RequiresApproval: true, StructuredOutput: json, Parameters: { title: { Required: true, MaxLength: 200 }, content: { Required: true, MaxLength: 50000 } } }, calendar_agenda: { Description: Query calendar agenda, ArgsTemplate: [calendar, agenda, --as, user], RiskLevel: low, ReadOnly: true, StructuredOutput: json, Parameters: {} }, message_send: { Description: Send a Feishu message, ArgsTemplate: [message, send, --to-user, {{to}}, --text, {{text}}], RiskLevel: medium, ReadOnly: false, RequiresApproval: true, StructuredOutput: text, Parameters: { to: { Required: true }, text: { Required: true, MaxLength: 2000 } } } } } } } } }11.7 步骤六验证 OpenClaw 集成# 查看连接器状态 openclaw external status lark # 列出可用命令 openclaw external commands lark # 预览搜索文档命令 openclaw external preview lark docs_search --param query项目计划 # 执行搜索如需要审批先预览再加 --yes openclaw external execute lark docs_search --param query项目计划 --yes # 预览创建文档变更命令需要审批 openclaw external preview lark docs_create \ --param title会议纪要 2026-05-10 \ --param content# 会议纪要\n\n## 参与人\n- ... # 审批后执行 openclaw external execute lark docs_create \ --param title会议纪要 2026-05-10 \ --param content# 会议纪要\n\n## 参与人\n- ... \ --yes11.8 懒人方式让 AI 助手自动配置你也可以让 AI 助手自动完成大部分配置工作帮我配置飞书云文档能力。请按以下步骤做 1. 检查是否安装了 lark-cli如果没有则执行 npm install -g larksuite/cli 2. 运行 lark-cli doctor 检查当前状态 3. 如果显示缺少凭证配置问我 App ID 和 App Secret 4. 拿到凭证后完成配置 echo AppSecret | lark-cli config init --app-id AppID --app-secret-stdin --brand feishu 5. 运行 lark-cli auth login --no-wait --recommend --json 把返回的 verification_url 发给我告诉我扫码授权 6. 我扫码确认后用返回的 device_code 执行登录 7. 如果缺少搜索权限按上面的方式再走一遍授权流程补充 search:docs:read 8. 全部完成后用以下命令验证各项能力 - lark-cli docs search --query 文档 --as user - lark-cli docs create --title 测试文档 --markdown # 你好 - lark-cli calendar agenda --as user十二、完整 lark-cli 能力一览模块能力docs搜索文档、创建文档、读取文档、更新文档、分享文档sheets读取表格、写入单元格、添加行/列message发送文本消息、卡片消息、图片消息calendar查询日程、创建日程mail搜索邮件、读取邮件、发送邮件contact搜索用户、查询部门wiki搜索知识库、读取知识库页面meeting查询会议纪要drive文件上传、下载、管理bitable多维表格操作approval审批流程查询/操作okrOKR 查询/创建十三、最佳实践与注意事项13.1 安全最佳实践最小权限原则— 只开通实际需要的权限审批变更操作— 所有写入/变更命令应设置RequiresApproval: true使用只读预设— 初始配置只启用读操作按需开启写操作监控审计日志— 定期检查external_cli的审计记录配置密钥脱敏— 为涉及敏感凭证的命令添加RedactionRules设置合理超时— 根据命令特性设置TimeoutSeconds13.2 常见问题排查问题排查方法命令执行失败检查lark-cli doctor输出确认凭证和授权状态权限不足在飞书开放平台检查应用权限是否已开通并发布审批指纹不匹配命令参数或模板可能在审批后发生变化重新预览获取新指纹输出为空检查StructuredOutput设置是否与 CLI 实际输出格式匹配超时增加TimeoutSeconds设置