[{"data":1,"prerenderedAt":269},["ShallowReactive",2],{"docs-protocol\u002Fsecurity-zh":3},{"id":4,"title":5,"body":6,"description":261,"extension":262,"meta":263,"navigation":264,"path":265,"seo":266,"stem":267,"__hash__":268},"docs\u002Fzh\u002Fprotocol\u002Fsecurity.md","安全模型",{"type":7,"value":8,"toc":250},"minimark",[9,12,21,25,33,46,53,56,59,63,86,91,111,116,136,143,147,159,163,170,173,187,203,206,218,221],[10,11,5],"h1",{"id":5},[13,14,15,16,20],"p",{},"A@UI 的安全设计基于",[17,18,19],"strong",{},"声明式组件约束","——Agent 只能使用预先注册的组件，不能注入任意代码或操作未授权的 DOM。",[22,23,24],"h2",{"id":24},"组件白名单",[13,26,27,28,32],{},"所有可被 Agent 驱动的 UI 组件必须通过 ",[29,30,31],"code",{},"a-at-ui.manifest.json"," 声明。Runtime 在初始化时构建组件映射表：",[34,35,36,40,43],"ul",{},[37,38,39],"li",{},"插件安装阶段：遍历 manifest 中的每个组件名，从显式映射或 Vue 全局注册表中查找对应实现",[37,41,42],{},"组件未找到 → 初始化抛错，拒绝启动",[37,44,45],{},"接收到 manifest 未声明的组件名 → 调度阶段抛错",[13,47,48,49,52],{},"Agent 无法在流中加入未注册组件的 ",[29,50,51],{},"render"," 命令。",[22,54,55],{"id":55},"命令校验",[13,57,58],{},"每条命令在 dispatch 前会经过结构校验，规则如下：",[13,60,61],{},[17,62,51],{},[34,64,65,74,80],{},[37,66,67,70,71],{},[29,68,69],{},"type"," 必须是 ",[29,72,73],{},"\"render\"",[37,75,76,79],{},[29,77,78],{},"component"," 必须是字符串",[37,81,82,83],{},"不允许带 ",[29,84,85],{},"widgetId",[13,87,88],{},[17,89,90],{},"update",[34,92,93,100,105],{},[37,94,95,70,97],{},[29,96,69],{},[29,98,99],{},"\"update\"",[37,101,102,104],{},[29,103,85],{}," 必须是非空字符串",[37,106,107,110],{},[29,108,109],{},"params"," 必须是对象",[13,112,113],{},[17,114,115],{},"destroy",[34,117,118,125,129],{},[37,119,120,70,122],{},[29,121,69],{},[29,123,124],{},"\"destroy\"",[37,126,127,104],{},[29,128,85],{},[37,130,82,131,133,134],{},[29,132,78],{}," 或 ",[29,135,109],{},[13,137,138,139,142],{},"流中遇到不合法命令时，不静默吞掉，通过 ",[29,140,141],{},"onError"," 通道暴露原始 payload 和错误信息。",[22,144,146],{"id":145},"widgetid-隔离","widgetId 隔离",[13,148,149,151,152,154,155,158],{},[29,150,85],{}," 由前端 Runtime 在 ",[29,153,51],{}," 时生成（",[29,156,157],{},"crypto.randomUUID()","），后端 Agent 无法指定或预知 widgetId。update 和 destroy 命令中的 widgetId 引用由 Runtime 校验，指向不存在的 widget 时发出警告并跳过。",[22,160,162],{"id":161},"payload-序列化校验","Payload 序列化校验",[13,164,165,166,169],{},"组件事件 payload 在 emit 到 Agent 层之前经过 ",[29,167,168],{},"isSerializableValue()"," 校验，确保只包含 JSON 兼容类型（string、number、boolean、null、数组、纯对象）。包含函数、DOM 元素或其他运行时对象的 payload 会被拒绝。",[22,171,172],{"id":172},"生命周期声明",[13,174,175,176,179,180,179,183,186],{},"组件在 manifest 中显式声明 ",[29,177,178],{},"lifecycle.render","、",[29,181,182],{},"lifecycle.update",[29,184,185],{},"lifecycle.destroy","。Runtime 在执行对应操作前检查声明：",[34,188,189,196],{},[37,190,191,192,195],{},"对声明为 ",[29,193,194],{},"false"," 的生命周期操作 → 抛错",[37,197,198,199,202],{},"对未声明的命令类型 → ",[29,200,201],{},"Unsupported command type"," 错误",[22,204,205],{"id":205},"错误通道",[13,207,208,209,211,212,217],{},"所有非法命令、解析失败、调度错误统一通过 ",[29,210,141],{}," 回调暴露，不会在 Runtime 内部被丢弃。详细错误类型见 ",[213,214,216],"a",{"href":215},".\u002Ferrors","错误参考","。",[22,219,220],{"id":220},"参考",[34,222,223,233,244],{},[37,224,225,228,229,232],{},[29,226,227],{},"packages\u002Fa-at-ui\u002Fsrc\u002Futils.ts"," — ",[29,230,231],{},"validateAAtUICommand()"," 校验函数",[37,234,235,228,238,179,241,243],{},[29,236,237],{},"packages\u002Fa-at-ui\u002Fsrc\u002Fruntime\u002Fvue\u002Fwidget-manager.ts",[29,239,240],{},"buildComponentMap()",[29,242,168],{},"、生命周期检查",[37,245,246,249],{},[29,247,248],{},"packages\u002Fa-at-ui\u002Fsrc\u002Fruntime\u002Fvue\u002Fstream.ts"," — 流解析中的命令校验",{"title":251,"searchDepth":252,"depth":252,"links":253},"",2,[254,255,256,257,258,259,260],{"id":24,"depth":252,"text":24},{"id":55,"depth":252,"text":55},{"id":145,"depth":252,"text":146},{"id":161,"depth":252,"text":162},{"id":172,"depth":252,"text":172},{"id":205,"depth":252,"text":205},{"id":220,"depth":252,"text":220},"A@UI 的安全设计基于声明式组件约束——Agent 只能使用预先注册的组件，不能注入任意代码或操作未授权的 DOM。","md",{},true,"\u002Fzh\u002Fprotocol\u002Fsecurity",{"title":5,"description":261},"zh\u002Fprotocol\u002Fsecurity","ONXSD-b8oPFcj_yDpmbLQz-VpX4lV9KtuQS31c5FZD4",1780547990951]