Repository navigation
feat(connection): 连接级 AI 访问策略(issue #437) - #444
Merged
Merged
Conversation
feigeCode
force-pushed
the
feat/connection-ai-access-policy
branch
4 times, most recently
from
October 22, 2026 03:24
df74e1f to
9d33f4f
Compare
问题:AI 可能绕过只读工具,直接登录「只打算人工管理」的连接执行写命令。 方案:连接新增 `ai_access_level`(允许 / 只读 / 禁止),三层落地: - 可见性:资源池与内置 AI 的资源目录、@ 提及按级别过滤或裁剪能力; `connections.list/find` 不返回被禁止的连接; - 路由:目标解析在能力不匹配时直接失败,模型拿不到句柄; - 执行:`ToolRegistry` 挂 `ToolAccessGuard`,外部 MCP 与内置 AI 共用同一闸门, 覆盖 `connection` / `connection_id` / `target` / `session_id` 四类目标。 策略属于连接内容:随云同步与导入导出走(载荷新增 `ai_access_level`,并加入团队 冲突判定的内容变更白名单),保证换机器、换客户端后「生产就是生产」的限制仍生效。 界面:连接表单(数据库 / SSH / Redis / MongoDB / middleware)三选一,侧栏徽标与 右键菜单可直接切换;写失败显式报错,不静默放宽。 Refs #437
feigeCode
force-pushed
the
feat/connection-ai-access-policy
branch
from
October 22, 2026 03:25
9d33f4f to
0c7b757
Compare
feigeCode
added a commit
that referenced
this pull request
Oct 22, 2026
合入 dev 做整体联调(启动验证后再决定是否合 main)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
背景
Closes #437
用户用 Navop 管理多台服务器,一部分只允许人工操作。风险不是「AI 看不到连接」,而是
AI 在推理后自行换一条路做写操作:用户明确让 AI 用只读数据库工具排查问题,AI 若判断某个
已保存连接就是测试库,仍可能通过
connections.open_session/ssh.exec登到那台服务器上执行写入、删除命令。
因此需要在连接这个粒度上声明「AI 是否可操作」,并且声明必须在 AI 真正执行命令的那一跳生效。
方案
连接新增
ai_access_level:allowed(默认)/read_only(只能调只读工具)/denied(AI 完全不能碰)。策略三层落地,单点拦截不够:
main/src/public_mcp_runtime/resource_pool.rs、crates/ai_chat_view/src/resource_builder.rs、crates/navop_runtime/src/connections/management.rs@提及,connections.list/find也不返回;只读连接的能力按白名单裁剪ToolRuntimeMcpProvider的 target 归一化TargetNotInPool/TargetLacksCapabilities,模型拿不到句柄crates/tool_runtime的ToolAccessGuard+main/src/public_mcp_runtime/access_guard.rsToolRegistry::call是外部 MCP 与内置 AI 的共同汇聚点;connection/connection_id/target/session_id都解析成连接后按级别拒绝,读存储失败时 fail-closed终端会话(用户自己手动打开的 SSH 会话)按
session.connection_id回查策略:denied的会话整条移出资源池,
read_only的会话削掉TerminalExec/TerminalInput。活动中的 Redis 通道同理。策略随连接同步
「生产就是生产」——策略属于连接内容,必须跨设备一致:
crates/core/migrations/20261022000001_connection_ai_access.sql给connections加列,NULL= 默认「允许」,旧库升级不需要回填数据;ConnectionPlainData新增ai_access_level(#[serde(default)]),上/下行都带上,并加入团队冲突判定的
connection_content_changed白名单(否则只改策略不会重新上传,冲突解决后会被云端旧值覆盖);
StoredConnection的 serde,字段随文件走,旧文件缺该字段按「允许」解析。界面
crates/connection_form/src/ai_access.rs:ai_access_selector统一渲染三档选择器(选项顺序、文案、选中态、说明),表单只持有一个
Entity<AiAccessLevel>并把它交给组件。数据库 / SSH / Redis / MongoDB / middleware 五个表单共用同一份实现,新增连接类型时一行接入,
不再各复制一遍单选钮。
ai_access_label/level_label/level_hint收拢文案,stored_level/write_level负责读、写连接字段;SaveError事件),不静默放宽。验证
cargo test -p one-core --lib:844 passed(含策略列往返、SELECT列清单、下行同步保留本地 id、冲突白名单变异验证)
cargo test -p tool_runtime -p navop_runtime -p connection-form -p ai_chat_view -p db_view -p terminal_view -p redis_view -p mongodb_view:全绿cargo test -p main --bin navop:718 passed(含「被禁止的连接立刻拦截、改回允许后同一 runtime立即恢复」端到端用例)
RUSTFLAGS="-D warnings" cargo check --workspace --all-targets:干净已知限制
PermissionMode::Ask下会先弹审批再被拒绝(结果仍是拒绝,只多一次提示)。设计与取舍记录:
docs/design/connection-ai-access-policy.md