尧图精选

iii 引擎 worker-manager 完全指南:WebSocket 监听器、RBAC 访问控制与中间件审计

🕒 发布时间:2026/9/14 22:19:48 📁 来源:尧图网络
iii 引擎 worker-manager 完全指南WebSocket 监听器、RBAC 访问控制与中间件审计【免费下载链接】iiiEffortlessly compose, extend, and observe every service in real-time for the first time ever.项目地址: https://gitcode.com/GitHub_Trending/mo/iiiiii-worker-manager是 iii 引擎中一个强制mandatory运行的引擎级 worker它为 SDK worker 提供 WebSocket 接入点并将引擎能力安全地暴露给受信任内部与不受信任外部 RBAC 保护两类 worker。本篇指南以 SKILL.md 为核心结合 README.md 的字段级说明与 rbac_config.rs 的源码决策逻辑完整讲解监听器配置、认证函数、中间件、注册钩子与函数过滤器的实战用法。读完你将能够独立搭建「内部主端口 外部 RBAC 监听器」的双监听器架构为每类连接定制访问策略、审计日志与多租户命名空间隔离。一、iii-worker-manager 是什么iii-worker-manager是引擎内置的强制 worker职责是打开 WebSocket 监听器供 SDK worker 连接。其 worker 清单定义在 iii.worker.yamliii: v1 name: iii-worker-manager type: engine description: WebSocket listener that SDK workers connect to. Supports RBAC, middleware, registration hooks, and channels.关键机制配置中第一个engine.workers.iii-worker-manager条目设定引擎主端口默认49134承载内部 worker 之间的可信流量通过#instance形式如iii-worker-manager#rbac可开启独立的监听器每个监听器拥有自己的端口、主机、RBAC 配置、中间件与注册钩子Channels通道WebSocket 端点挂载在每一个监听器上路径为/ws/channels/{channel_id}。从源码结构看engine/src/workers/worker/目录下的 ws_handler.rs 实现了 channel 端点升级请求通过access_key校验 channel 是否存在不存在返回 404随后按dirread/write方向把 channel 数据流桥接到 WebSocket。这是所有监听器共享的通道能力。二、何时使用 iii-worker-manager将引擎暴露到不受信任的网络不要直接开放主引擎端口而是新增一个带rbac块与auth_function_id的iii-worker-manager条目用独立端口对外服务。限制连接的 worker 可调用哪些函数组合使用操作员侧的expose_functions过滤器与认证函数返回的forbidden_functions按会话生效、硬性拒绝。审计、限流或富化每一次调用在监听器上配置middleware_function_id由中间件决定是否调用目标函数以及返回什么内容。按租户或按会话隔离命名空间在认证函数中返回function_registration_prefix该会话注册的所有函数/触发器会被透明地加上前缀worker 代码完全无感知。门控动态注册通过on_function_registration_function_id、on_trigger_registration_function_id或on_trigger_type_registration_function_id对注册请求进行校验或改写。三、监听器配置内部主端口 外部 RBAC 端口以下双监听器配置是生产环境的典型形态——一个内部监听器49134服务可信 worker一个外部 RBAC 监听器49135绑定0.0.0.0服务不受信任客户端engine: workers: iii-worker-manager: port: 49134 iii-worker-manager#rbac: host: 0.0.0.0 port: 49135 middleware_function_id: my-project::middleware rbac: auth_function_id: my-project::auth on_function_registration_function_id: my-project::on-fn-reg on_trigger_registration_function_id: my-project::on-trig-reg on_trigger_type_registration_function_id: my-project::on-trig-type-reg expose_functions: - match(api::*) - match(*::public) - metadata: public: true监听器与 RBAC 块的字段语义详见 README.md字段类型说明portinteger绑定端口默认49134第一个条目决定主引擎端口hoststring绑定主机默认0.0.0.0middleware_function_idstring该监听器上每次 worker 调用前都会先调用此函数收到MiddlewareFunctionInput且必须自行调用目标函数并返回结果。有无 RBAC 均可使用rbac.auth_function_idstring每个 WebSocket 升级时调用一次收到AuthInput返回AuthResult。未设置时所有连接都放行仅靠expose_functions把关rbac.expose_functionsFunctionFilter[]过滤器列表任一过滤器命中即暴露空列表 不暴露任何函数基础设施豁免除外rbac.on_function_registration_function_idstringregisterFunction前的钩子返回映射字段或抛错拒绝rbac.on_trigger_registration_function_idstringregisterTrigger前的钩子返回映射字段或抛错拒绝rbac.on_trigger_type_registration_function_idstringregisterTriggerType前的钩子返回映射字段或抛错拒绝四、认证函数Auth Function认证函数在每次 WebSocket 升级时被调用接收AuthInput包含headers、query_params、ip_address返回AuthResult抛错即拒绝连接。import type { AuthInput, AuthResult } from iii-dev/helpers/worker-connection-manager iii.registerFunction( my-project::auth, async (input: AuthInput): PromiseAuthResult { const token input.headers?.[authorization]?.replace(/^Bearer\s/i, ) if (!token) throw new Error(Missing credentials) const user await validateToken(token) return { allowed_functions: [], forbidden_functions: user.role readonly ? [api::users::delete, api::users::update] : [], allowed_trigger_types: user.role admin ? [cron, webhook] : undefined, allow_trigger_type_registration: user.role admin, function_registration_prefix: tenant-${user.tenant_id}, context: { user_id: user.id, role: user.role, tenant_id: user.tenant_id }, } }, )AuthResult各字段的默认值依据 README.md 的字段表字段类型默认值说明allowed_functionsstring[][]在expose_functions之外额外放行的函数 IDforbidden_functionsstring[][]即使命中expose_functions也拒绝的 ID优先级高于一切allowed_trigger_typesstring[] 或省略省略宽松允许注册触发器的 trigger type省略时全部允许allow_trigger_type_registrationbooleanfalse是否允许注册新的触发器类型allow_function_registrationbooleantrue是否允许注册新的函数function_registration_prefixstring 或省略省略设置后该会话注册的函数 ID 统一加上{prefix}::触发器注册引用到的function_id也会自动加前缀引擎回派调用时去掉前缀worker SDK 永远看不到它contextobject{}每次调用时转发给中间件与注册钩子的任意上下文其中function_registration_prefix是多租户隔离的核心机制引擎在注册与调用两个方向透明改写 IDworker 代码无需管理前缀即可获得私有命名空间。五、中间件函数Middleware Function中间件在该监听器的每一次调用上执行接收MiddlewareFunctionInput含function_id、payload、action、context。它不是前置处理器——必须自己调用目标函数通常通过iii.trigger并返回其结果。import type { MiddlewareFunctionInput } from iii-sdk iii.registerFunction( my-project::middleware, async (input: MiddlewareFunctionInput) { console.log([audit] user${input.context.user_id} → ${input.function_id}) return iii.trigger({ function_id: input.function_id, payload: { ...input.payload, _caller_id: input.context.user_id, _caller_role: input.context.role, }, }) }, )两个关键行为跳过iii.trigger即短路请求——适合限流拒绝场景不调用目标函数改为返回一个结构化的错误信封context来自该会话认证函数返回的AuthResult.context未配置 RBAC 时为空对象。中间件是请求校验、限流、审计日志的正确位置且必须保持幂等——调用可能被重试。MiddlewareFunctionInput字段来自 README.mdfunction_idworker 想调用的函数、payloadworker 发送的负载、actionenqueue/void等路由动作可省略、context会话认证上下文。六、注册钩子Registration Hooks三个钩子分别在函数注册、触发器注册、触发器类型注册前执行接收注册详情加上AuthResult.context。返回映射后的字段放行抛错即拒绝省略的字段保持原值返回{}表示原样放行。import type { OnFunctionRegistrationInput, OnTriggerRegistrationInput, OnTriggerTypeRegistrationInput, } from iii-dev/helpers/worker-connection-manager iii.registerFunction( my-project::on-fn-reg, async (input: OnFunctionRegistrationInput) { if (input.function_id.startsWith(internal::)) { throw new Error(Cannot register internal functions) } return { function_id: input.function_id } }, ) iii.registerFunction( my-project::on-trig-reg, async (input: OnTriggerRegistrationInput) { const role input.context.role as string if (!input.function_id.startsWith(${role}::)) { throw new Error(Function ID must be prefixed with the role) } return { function_id: ${role}::${input.function_id} } }, ) iii.registerFunction( my-project::on-trig-type-reg, async (input: OnTriggerTypeRegistrationInput) { if (input.context.role ! admin) { throw new Error(Only admins can register trigger types) } return {} }, )注册权限的判定逻辑见 README.mdworker 注册触发器类型仅当allow_trigger_type_registration: true且若配置了钩子钩子返回结果worker 注册触发器仅当其trigger_type在allowed_trigger_types中或该字段省略且若配置了钩子钩子返回结果通过 RBAC 会话注册的触发器与函数限定在该会话作用域内worker 断开连接时自动清理。各钩子的输入/结果字段OnFunctionRegistrationInputfunction_id、description、metadata、context、OnTriggerRegistrationInputtrigger_id、trigger_type、function_id、config、context、OnTriggerTypeRegistrationInputtrigger_type_id、description、context对应结果对象均可省略字段以保留原值。七、函数过滤器Function Filters通配符与元数据expose_functions支持两种过滤器形态可混用多条过滤器之间是**或OR关系而元数据过滤器内部的多个键是与AND**关系。expose_functions: - match(api::*) # ID 通配* 匹配任意字符 - match(*::public) # 后缀匹配 - match(api::*::read) # 多段匹配 - metadata: # 所有键都必须命中 public: true tier: free - metadata: name: match(*public*) # 元数据值也支持通配语义要点函数只要被任意一条过滤器命中即视为暴露expose_functions为空 不暴露任何函数基础设施豁免除外match(pattern)的通配实现可在 rbac_config.rs 的wildcard_match中找到按*切分模式串首段锚定开头、末段锚定结尾、中间段依次查找*单独出现时匹配一切对应单元测试wildcard_prefix、wildcard_suffix、wildcard_middle、wildcard_star_matches_all覆盖了前缀/后缀/中段/全匹配四种形态元数据过滤器中的值既可以是精确 JSON 值public: true也可以写成match(...)字符串形式MetadataValue::matches会区分精确比较与通配比较非字符串值做通配比较时返回 false见测试metadata_wildcard_match从源码看FunctionFilter还支持可选的namespace作用域未声明命名空间的规则只匹配default命名空间跨命名空间不生效测试expose_filter_without_namespace_matches_only_default与expose_filter_with_namespace_matches_only_that_namespace分别验证了两种行为反序列化时未知键会直接报错避免因拼写错误导致授权规则静默失效。八、访问决策流程默认拒绝每个经过 RBAC 监听器的调用都按以下流程裁决SKILL.md 中的 mermaid 流程图对应 rbac_config.rs 中is_function_allowed的实现顺序决策顺序即「规则 5默认拒绝」function_id在forbidden_functions中 →拒绝在allowed_functions中 →允许属于基础设施豁免 ID →允许carve-out命中任意expose_functions过滤器 →允许其余 →拒绝。基础设施豁免infrastructure carve-out是一组固定的内置函数 ID无论操作员的过滤器如何配置RBAC 监听器始终放行以保证连接建立、日志与上下文传播正常工作常量INFRASTRUCTURE_FUNCTIONS定义在 rbac_config.rsengine::channels::create engine::workers::register engine::log::info engine::log::warn engine::log::error engine::log::debug engine::log::trace engine::baggage::get engine::baggage::set engine::baggage::get_all需要特别强调的三条边界源码注释与文档共同确认carve-out 属于公开契约同一大版本内只增不减把豁免 ID 加进forbidden_functions仍会拒绝规则 1 优先但会记录警告且 worker 可能表现异常连接建立失败、日志丢失、上下文缺失forbidden_functions是全局的——在任意命名空间生效且胜过allowed_functions与expose_functions测试forbidden_stays_global_across_namespaces、access_resolution_forbidden_takes_precedence验证了这一点会话无法覆盖操作员的拒绝名单命名空间感知allowed_functions只作用于default命名空间测试unscoped_allowed_functions_apply_in_default_only而forbidden_functions全局生效——拒绝必须赢在全局这是刻意的安全设计。九、RBAC 端口上的 ChannelsChannels 挂载在 worker 实际连接的那个端口上路径为/ws/channels/{channel_id}。由于engine::channels::create属于基础设施豁免即使expose_functions为空RBAC 监听器也能发放 channel 引用。SDK 的createChannel()无需任何额外配置即可工作——channel 数据流经 worker 所在的监听器绝不走主引擎端口。channel WebSocket 的访问由StreamChannelRef中的access_key能力令牌独立校验。ws_handler.rs 给出了实现证据升级请求携带key与dir查询参数ChannelManager::get_channel校验channel_id access_key不匹配返回 404dir决定该连接是读取方向channel → WebSocket 流式转发还是写入方向WebSocket → channel 流式转发。十、安全注意事项面向不受信任网络的监听器必须设置auth_function_id没有rbac块的监听器不认证任何连接仅靠expose_functions把关第一个iii-worker-manager条目主引擎端口应保持内部使用只有 RBAC 保护的监听器才应暴露到外部网络并配合防火墙或网络策略强制执行优先使用窄范围的expose_functions而非match(*)引擎每新增一个命名空间就审计一次过滤器列表中间件是请求校验、限流与审计日志的正确位置务必保持幂等调用可能被重试避免重复计费或重复记录多租户隔离优先使用function_registration_prefix而不是要求各租户自行注册带前缀的函数 ID——前缀对 worker SDK 完全透明。十一、进一步阅读与验证关联技能文档engine/src/workers/worker/skills/SKILL.md本文核心来源字段级参考engine/src/workers/worker/README.md含完整的 AuthInput/AuthResult、MiddlewareFunctionInput、各钩子输入/结果字段表RBAC 决策实现与单元测试engine/src/workers/worker/rbac_config.rsis_function_allowed、INFRASTRUCTURE_FUNCTIONS、通配与元数据匹配的完整测试覆盖Channel WebSocket 端点实现engine/src/workers/worker/ws_handler.rsWorker 清单声明engine/src/workers/worker/iii.worker.yaml【免费下载链接】iiiEffortlessly compose, extend, and observe every service in real-time for the first time ever.项目地址: https://gitcode.com/GitHub_Trending/mo/iii创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
上一篇/下一篇内容由系统自动关联 返回资讯列表 →