尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

OpenViking 隐私配置(Privacy Configs)深度解析:敏感字段版本化管理与 Skill 密钥占位/恢复机制

OpenViking 隐私配置(Privacy Configs)深度解析:敏感字段版本化管理与 Skill 密钥占位/恢复机制 OpenViking 隐私配置Privacy Configs深度解析敏感字段版本化管理与 Skill 密钥占位/恢复机制【免费下载链接】OpenVikingSelf-evolving Context Database for AI Agents. Unify Agent Memory, Knowledge RAG and Skills.项目地址: https://gitcode.com/GitHub_Trending/op/OpenViking隐私配置Privacy Configs是 OpenViking 提供的按category target_key管理敏感字段版本的能力每次写入都会生成不可变的版本快照支持查询历史、回滚并切换生效版本。本文基于仓库中的 API 实现、存储模型与技能处理链路完整讲解隐私配置的接口用法、底层存储结构、并发控制机制以及它如何与 Skill 的占位符自动脱敏/读取时恢复机制协同工作读完后可直接用于密钥轮换、版本回滚和敏感配置的安全管理实战。一、隐私配置解决什么问题在 Agent 场景中Skill技能文件往往内嵌api_key、base_url等敏感配置。如果把这些值直接写死在SKILL.md内容里密钥一旦泄露就需要重新分发整个技能文件且无法做轮换与审计。OpenViking 的隐私配置模块把敏感值从技能内容中抽离出来单独按目标管理为某个 skill 保存密钥等敏感配置轮换密钥写入新版本回滚到历史版本在读取 skill 内容时按占位符自动恢复配置值从源码结构看隐私配置按用户空间user space隔离存储服务入口 UserPrivacyConfigService 通过canonical_user_root(ctx)定位当前请求用户的根目录因此不同用户请求头X-OpenViking-User之间的隐私配置互不可见。二、存储结构与数据模型隐私配置并非存在专门的数据库中而是落在 OpenViking 的 VikingFS 命名空间下。路径构造逻辑集中在 helpers.pyviking://user/{user_space}/privacy/{category}/{target_key}/ ├── current.json # 当前生效版本快照 ├── .meta.json # 元信息active_version / latest_version / labels 等 └── history/ ├── version_001.json ├── version_002.json └── version_003.json # 文件名正则^version_(\d)\.json$对应两个核心数据模型models.pycurrent当前生效版本UserPrivacyConfigVersion{ version: 3, category: skill, target_key: byted-viking-search-knowledgebase, values: { api_key: ***, base_url: https://example.com }, created_at: 2026-04-27T10:00:0008:00, created_by: alice, change_reason: rotate key }meta元信息UserPrivacyConfigMeta{ category: skill, target_key: byted-viking-search-knowledgebase, active_version: 3, latest_version: 5, created_at: 2026-04-21T10:00:0008:00, updated_at: 2026-04-27T10:00:0008:00, updated_by: alice, last_accessed_at: 2026-04-27T10:00:0008:00, labels: { env: prod } }两个字段值得注意active_version与latest_version分离写入永远追加新版本latest_version单调递增而“生效版本”由current.json指向可以停留在任意历史版本上这就是回滚能力的来源labels是自由键值标签用于给配置打上env: prod之类的自定义标记仅随写入请求更新不参与版本快照。三、API 总览HTTP 路由注册在 privacy_configs.py前缀为/api/v1/privacy-configs。所有接口都需要请求头X-API-Key、X-OpenViking-Account、X-OpenViking-User见 鉴权与请求上下文 相关实现。方法路径说明GET/api/v1/privacy-configs列出隐私配置分类GET/api/v1/privacy-configs/{category}列出分类下目标GET/api/v1/privacy-configs/{category}/{target_key}获取当前生效配置meta currentPOST/api/v1/privacy-configs/{category}/{target_key}写入新版本并激活GET/api/v1/privacy-configs/{category}/{target_key}/versions列出版本号GET/api/v1/privacy-configs/{category}/{target_key}/versions/{version}获取指定版本详情POST/api/v1/privacy-configs/{category}/{target_key}/activate激活指定版本下面按接口逐一展开。四、接口详解与调用示例以下示例默认服务监听在localhost:1933。4.1 列出分类list_privacy_categoriescurl -X GET http://localhost:1933/api/v1/privacy-configs \ -H X-API-Key: your-key \ -H X-OpenViking-Account: default \ -H X-OpenViking-User: alice响应{ status: ok, result: [skill], time: 0.01 }实现上就是ls用户空间下的privacy/目录并排序返回条目名service.py 的 list_categories目录不存在时返回空列表而不是报错。4.2 列出分类下的目标list_privacy_targetscurl -X GET http://localhost:1933/api/v1/privacy-configs/skill \ -H X-API-Key: your-key \ -H X-OpenViking-Account: default \ -H X-OpenViking-User: alice{ status: ok, result: [byted-viking-search-knowledgebase], time: 0.01 }同理这是对privacy/skill/目录的列举list_targets。4.3 获取当前生效配置get_privacy_currentcurl -X GET http://localhost:1933/api/v1/privacy-configs/skill/byted-viking-search-knowledgebase \ -H X-API-Key: your-key \ -H X-OpenViking-Account: default \ -H X-OpenViking-User: alice{ status: ok, result: { meta: { category: skill, target_key: byted-viking-search-knowledgebase, active_version: 3, latest_version: 5 }, current: { version: 3, category: skill, target_key: byted-viking-search-knowledgebase, values: { api_key: ***, base_url: https://example.com } } }, time: 0.01 }若 target 不存在返回NOT_FOUND。路由层通过 _require_privacy_target 统一做存在性检查再同时读取meta与current返回便于调用方一次性拿到版本状态和实际值。4.4 写入新版本upsert_privacy_config写入新版本并将其设为当前生效版本。行为说明与 service.py 的 upsert 实现 一致values按整包快照写入本次传入内容成为新版本的values因此更新前若只想改一个 key客户端需要先读取 current 再合并回传传入新 key 会直接写入允许新增旧 key 未传则视为被移除整包替换语义若与当前版本完全一致按json.dumps(sort_keysTrue)规范化后比较见 canonicalize_values则复用当前版本号不新建版本只刷新 meta 的last_accessed_at等信息首次写入版本号从 1 开始之后取latest_version 1。HTTP APIPOST /api/v1/privacy-configs/{category}/{target_key}请求体请求模型定义见 UpsertPrivacyConfigRequest字段类型必填默认值说明valuesobject是-隐私配置键值change_reasonstring否变更原因labelsobject否null元信息标签curl -X POST http://localhost:1933/api/v1/privacy-configs/skill/byted-viking-search-knowledgebase \ -H Content-Type: application/json \ -H X-API-Key: your-key \ -H X-OpenViking-Account: default \ -H X-OpenViking-User: alice \ -d { values: { api_key: secret-2, base_url: https://example.com, region: cn }, change_reason: rotate key, labels: { env: prod } }响应{ status: ok, result: { version: 4, category: skill, target_key: byted-viking-search-knowledgebase, values: { api_key: secret-2, base_url: https://example.com, region: cn }, change_reason: rotate key }, time: 0.02 }从写入顺序看upsert会依次写history/version_NNN.json、current.json最后落盘meta.jsonservice.py整个读改写过程被分布式路径锁保护下一节。4.5 列出版本list_privacy_versionscurl -X GET http://localhost:1933/api/v1/privacy-configs/skill/byted-viking-search-knowledgebase/versions \ -H X-API-Key: your-key \ -H X-OpenViking-Account: default \ -H X-OpenViking-User: alice{ status: ok, result: [1, 2, 3, 4], time: 0.01 }若 target 不存在返回NOT_FOUND。实现上是ls历史目录后用正则^version_(\d)\.json$解析文件名并排序list_versions非版本文件会被忽略。4.6 获取历史版本get_privacy_versioncurl -X GET http://localhost:1933/api/v1/privacy-configs/skill/byted-viking-search-knowledgebase/versions/2 \ -H X-API-Key: your-key \ -H X-OpenViking-Account: default \ -H X-OpenViking-User: alice{ status: ok, result: { version: 2, category: skill, target_key: byted-viking-search-knowledgebase, values: { api_key: secret-1, base_url: https://example.com } }, time: 0.01 }若 target/version 不存在返回NOT_FOUND。历史快照是只读的读取不会改变active_version也不会刷新 meta 中的版本指针。4.7 激活历史版本activate_privacy_version切换当前生效版本即“回滚”操作。HTTP APIPOST /api/v1/privacy-configs/{category}/{target_key}/activate请求体字段类型必填说明versionint是要激活的版本号curl -X POST http://localhost:1933/api/v1/privacy-configs/skill/byted-viking-search-knowledgebase/activate \ -H Content-Type: application/json \ -H X-API-Key: your-key \ -H X-OpenViking-Account: default \ -H X-OpenViking-User: alice \ -d {version: 2}响应{ status: ok, result: { version: 2, category: skill, target_key: byted-viking-search-knowledgebase, values: { api_key: secret-1, base_url: https://example.com } }, time: 0.01 }若 target/version 不存在返回NOT_FOUND。从实现看activate_version激活只是把指定历史快照的内容重新写入current.json并更新meta.active_versionlatest_version不受影响——后续继续 upsert 时版本号仍从最新历史版本递增不会与已存在快照冲突。五、并发安全路径锁保护读改写密钥类配置常被多个客户端并发更新upsert/activate/delete都运行在 _config_lock 上下文管理器中它通过底层 AGFS 的pathlock_acquire_tree在配置根目录上获取路径树锁超时 30 秒确保“读 meta/current → 生成新版本 → 写 history/current/meta”的整个临界区串行化。可以推断该锁机制同样覆盖多实例部署下的跨进程场景因为锁建立在存储层而非进程内。测试方面tests/server/test_api_privacy_configs.py覆盖了该接口的端到端行为可作为接口回归依据。六、与 Skill 的联动占位脱敏与读取时恢复隐私配置在categoryskill时与技能处理链路深度集成构成“写入时脱敏、读取时还原”的闭环。6.1 占位符格式敏感值在技能内容中统一被替换为形如 build_placeholder 生成的占位符{{ov_privacy:skill:{skill_name}:{field_name}}}例如byted-viking-search-knowledgebase技能的api_key会写成{{ov_privacy:skill:byted-viking-search-knowledgebase:api_key}}。6.2 写入侧LLM 提取 替换技能入库前skill_processor.py 的 prepare_skill_privacy 调用extract_skill_privacy_valuesskill_extractor.py通过提示词模板skill.privacy_extraction让 VLM/LLM 从技能内容中识别出敏感字段返回{values: {...}}随后 placeholderize_skill_content_with_blocks 把原文中的敏感值替换为占位符。替换策略分两层结构化替换带引号的形式值/值整体替换行尾裸值替换匹配key: 值/key值这类行尾模式_replace_structured_value。且字段按值长度降序处理避免短值误替换长值的子串。提取出的值经 apply_skill_privacy 调用privacy_configs.upsert(categoryskill, target_key技能名, ...)落盘为隐私配置若本次提取为空且允许删除则会调用delete清理旧配置delete 实现 同样走路径锁递归删除配置目录。6.3 读取侧自动还原读取SKILL.md时文件系统服务会在返回内容前自动还原占位符fs_service.py 的 read 方法 先解析 URI用 get_skill_name_from_uri 识别出这是某个技能的SKILL.md要求路径形如.../skills/{name}/SKILL.md若命中则读取该技能的categoryskill当前生效版本交给 restore_skill_content 完成替换内容中的每个占位符按field_name从current.values取值回填配置存在但内容未引用的 key会在文末追加Configured but not referenced in content: ...提示内容引用了但配置缺失的字段占位符保留并追加Missing config: fieldmissing提示方便定位配置缺口。由于还原永远取current.json指向的生效版本前文的“写入新版本 / 激活历史版本”两个 API 就直接决定了 Agent 读取技能时拿到的密钥是哪一版——这就是密钥轮换与回滚对上层完全透明的原理。七、CLI 快速操作Rust 实现的 CLI 在 main.rs 的 PrivacyCommands 中定义了对应子命令# 分类/目标 openviking privacy categories openviking privacy list skill # 当前生效配置支持快捷形式 openviking privacy get skill byted-viking-search-knowledgebase openviking privacy skill byted-viking-search-knowledgebase # 更新整包 JSON openviking privacy upsert skill byted-viking-search-knowledgebase \ --values-json {api_key:secret-2,base_url:https://example.com} # 仅更新部分 key先读取 current 再合并 openviking privacy upsert skill byted-viking-search-knowledgebase \ --key-api_key secret-3 # 版本查询与切换 openviking privacy versions skill byted-viking-search-knowledgebase openviking privacy version skill byted-viking-search-knowledgebase 2 openviking privacy activate skill byted-viking-search-knowledgebase 2结合 CLI 参数定义可以补充几点实操细节upsert除--values-json外还支持--values-file path二者互斥conflicts_with适合 values 较大时避免命令行转义问题--key keyvalue可重复传入VecString对应“先读 current 再合并”的部分更新语义还支持--change-reason默认空串与--labels-json与 HTTP 请求体字段一一对应。八、小结与延伸阅读隐私配置模块用“目录 JSON 快照”的轻量结构实现了完整的版本化敏感配置管理current.json决定生效版本、history/version_NNN.json保留不可变历史、.meta.json维护版本指针与标签配合路径锁保证多端并发安全再叠加 Skill 的占位符提取与读取时自动还原使得密钥轮换、回滚、审计都可以只通过category/target_key维度的 API 或 CLI 完成无需改动技能内容本身。相关文档技能 - 技能写入与读取文件系统 -read/write/ls等系统 - 服务状态与可观测性核心源码入口路由层、存储服务、数据模型、路径与版本辅助、技能脱敏提取、占位符替换、读取时还原、接口测试。【免费下载链接】OpenVikingSelf-evolving Context Database for AI Agents. Unify Agent Memory, Knowledge RAG and Skills.项目地址: https://gitcode.com/GitHub_Trending/op/OpenViking创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表