OpenViking 数据加密实战指南三层密钥架构、信封加密与多租户隔离【免费下载链接】OpenVikingSelf-evolving Context Database for AI Agents. Unify Agent Memory, Knowledge RAG and Skills.项目地址: https://gitcode.com/GitHub_Trending/op/OpenVikingOpenViking 面向 AI Agent 提供统一的自进化上下文数据库在多租户场景下不同账户的资源文件、记忆与技能共享同一 AGFS 存储实例静态数据加密因此成为数据安全与租户隔离的基石。本文以 数据加密概念文档 为核心脉络深入讲解 OpenViking 的三层密钥信封加密架构、三种密钥提供程序Local / Vault / 火山引擎 KMS的配置与原理、透明读写流程与信封格式并结合仓库源码与测试用例给出可落地的实操指引。读完本文你将掌握 OpenViking 加密功能的完整配置方法、密钥管理选型依据以及如何验证加密是否真正生效。为什么需要静态加密多租户共享存储下的威胁模型在多租户架构中不同客户账户的资源文件、记忆和技能都存储在共享的 AGFS 实例中。这意味着存储层天然是一个“共享”的信任边界加密确保磁盘泄露不泄露数据即使攻击者获得 AGFS 磁盘访问权限也无法读取任何客户的明文数据密钥级租户隔离不同账户的数据使用独立密钥加密账户 A 的密钥无法解密账户 B 的文件隔离在密钥层面实现不依赖存储层权限密文只出现在存储层所有加密解密操作集中在 VikingFS 层完成AGFS 和外部对象存储只看到密文。需要特别强调的是加密对用户和开发者完全透明客户端 API 无变化、现有代码无需修改读写操作与未加密时完全相同且向后兼容未加密的旧文件仍可正常读取。透明性在源码中得到印证——FileEncryptor.decrypt的第一步就是检查魔术数if not ciphertext.startswith(MAGIC): return ciphertext见 encryptor.py凡是未以OVE1开头的文件一律视为明文直接返回。三层密钥架构信封加密Envelope EncryptionOpenViking 采用经典的信封加密架构使用三层密钥体系将“高价值的主密钥”与“高频使用的数据密钥”彻底分离┌─────────────────────────────────────────────────────────┐ │ Layer 1: Root Key根密钥 │ │ • 整个 OpenViking 实例全局唯一 │ │ • 存储KMS 服务 / ~/.openviking/master.key │ │ • 用途派生所有账户密钥 │ └────────────────────┬────────────────────────────────────┘ │ HKDF 派生 ▼ ┌─────────────────────────────────────────────────────────┐ │ Layer 2: Account Key账户密钥KEK │ │ • 每个账户一个独立密钥 │ │ • 不存储运行时派生 │ │ • 用途加密该账户下的所有文件密钥 │ └────────────────────┬────────────────────────────────────┘ │ AES-256-GCM 加密 ▼ ┌─────────────────────────────────────────────────────────┐ │ Layer 3: File Key文件密钥DEK │ │ • 每次写操作生成新的随机密钥 │ │ • 加密后存储在文件头信封中 │ │ • 用途加密实际文件内容 │ └─────────────────────────────────────────────────────────┘层级名称说明数量Root Key根密钥整个系统的主密钥用于派生所有账户密钥1 个实例Account Key账户密钥每个账户独立的密钥从根密钥派生每个账户 1 个File Key文件密钥每个文件的一次性随机密钥每次写入 1 个这一设计在源码中有着严格的对应实现每次写入生成新的 File KeyFileEncryptor.encrypt中通过secrets.token_bytes(32)生成 32 字节随机文件密钥、secrets.token_bytes(12)生成 12 字节随机 IV见 encryptor.py保证每个文件使用独立的 DEK单个文件密钥泄露不会波及其他文件Account Key 由 Root Key 经 HKDF 派生RootKeyProvider._hkdf_derive使用 HKDF-SHA256算法 SHA256、输出 32 字节盐固定为bopenviking-kek-salt-v1info 为bopenviking:kek:v1: account_id见 providers.py 与 providers.py。Account Key 永不落盘、运行时按需派生这就是“每个账户独立密钥”的来源File Key 用 Account Key 加密BaseProvider.encrypt_file_key先派生账户密钥再用 AES-256-GCM 加密文件密钥并生成独立 IV见 providers.py。值得注意的一个工程细节Rust 端的 RAGFS 也实现了与 PythonFileEncryptor逐字节一致的信封格式并共享同一个OVE1魔术数见 crates/ragfs/src/crypto/mod.rs确保 Python 端与 Rust 端加密的数据可以互相解密这也是“加密集中在 VikingFS 层”这一设计跨语言落地的基础。三种密钥提供程序选型与完整配置OpenViking 支持三种 Root Key 提供程序适配从开发到云原生的不同部署场景提供程序适用场景Root Key 存储特点Local开发环境、单节点部署本地文件~/.openviking/master.key简单无需外部服务Vault生产环境、多云部署HashiCorp Vault Transit Engine企业级密钥管理支持密钥版本控制Volcengine KMS火山引擎云部署火山引擎 KMS云原生密钥管理服务三种提供程序都实现了同一个抽象接口RootKeyProviderget_root_key/derive_account_key/encrypt_file_key/decrypt_file_key见 providers.py由工厂函数create_root_key_provider依据encryption.provider字段统一创建见 providers.py。Local本地文件最快上手的开发模式适合开发环境和单节点部署无需任何外部服务{ encryption: { enabled: true, provider: local, local: { key_file: ~/.openviking/master.key } } }初始化命令生成 32 字节随机根密钥并写入指定文件ov system crypto init-key --output-file ~/.openviking/master.key # 或使用短选项 ov system crypto init-key -f ~/.openviking/master.keyinit-key命令由 Rust CLI 实现见 crates/ov_cli/src/commands/crypto.rs底层调用getrandom生成 32 字节密钥以十六进制写入文件并在 Unix 平台强制设置0600权限仅所有者可读写。如果目标文件已存在命令会直接报错拒绝覆盖防止误操作破坏既有密钥。LocalFileProvider在运行时按需读取或创建根密钥文件不存在时生成新密钥并写入同样强制0600权限存在时读取 hex 内容解析见 providers.py。配置校验还会检查密钥文件权限是否为0600过宽会报错提示见 config.py。VaultHashiCorp Vault生产环境的企业级密钥管理适合生产环境和多云部署Root Key 由 Vault Transit 引擎加密保管。前置条件已部署 Vault 服务、已启用 Transit 引擎、有足够权限的 Token。{ encryption: { enabled: true, provider: vault, vault: { address: https://vault.example.com:8200, token: hvs.your-vault-token, mount_point: transit, kv_mount_point: secret, kv_version: 1, root_key_name: openviking-root-key, encrypted_root_key_key: openviking-encrypted-root-key } } }参数说明默认值与源码VaultProvider.__init__一致见 providers.py参数说明默认值addressVault 服务器地址必需如https://vault.example.com:8200tokenVault 认证令牌必需mount_pointTransit 引擎挂载路径transitkv_mount_pointKV 引擎挂载路径secretkv_versionKV 引擎版本1 或 21root_key_nameTransit 引擎中的密钥名称openviking-root-keyencrypted_root_key_keyKV 引擎中存储加密根密钥的路径openviking-encrypted-root-key其工作方式为Root Key 由 OpenViking 随机生成32 字节先用 Transit 引擎中名为root_key_name的密钥aes256-gcm96类型缺失时自动创建见 providers.py加密再将密文存入 KV 引擎的encrypted_root_key_key路径。启动时从 KV 读取密文、经 Transit 解密还原 Root Key见 providers.py。实现中还包含一个关键的数据安全保护若根密钥已生成但持久化失败如 Transit 加密不可用、KV 写入失败会立即清空内存缓存并拒绝启动避免用未落盘的临时密钥加密数据导致数据丢失见 providers.py。若你使用 KV v2 引擎配置kv_version: 2即可读取与写入走kv.v2接口。Volcengine KMS火山引擎云原生密钥管理适合火山引擎云部署Root Key 由火山引擎 KMS 服务加密保管{ encryption: { enabled: true, provider: volcengine_kms, volcengine_kms: { key_id: d926aa0d-xxxx-xxxx-xxxx-xxxxxxxxxxxx, region: cn-beijing, access_key: AKLTxxxxxxxxxxxxxxxxxx, secret_key: Tmpxxxxxxxxxxxxxxxxxxxxxx, endpoint: null, key_file: ~/.openviking/openviking-volcengine-root-key.enc } } }参数说明参数说明默认值key_idKMS 密钥 ID对称密钥算法 AES_256必需region区域如cn-beijing必需access_keyAccess Key必需secret_keySecret Key必需endpoint自定义 KMS 端点null默认kms.{region}.volcengineapi.comkey_file加密根密钥的本地缓存文件路径~/.openviking/openviking-volcengine-root-key.enc其工作方式与 Vault 类似但更简洁Root Key 随机生成后调用 KMSEncrypt加密密文缓存到本地key_file启动时读取本地密文、调用 KMSDecrypt还原见 providers.py。同样若持久化失败会拒绝启动。配置校验与健康检查无论选择哪种提供程序配置在启动时都会经过validate_encryption_config校验见 config.pyencryption.enabled必须是布尔值provider仅支持local/vault/volcengine_kmsLocal 模式检查key_file是否存在或父目录可写、文件权限是否为0600Vault 模式address与token必填火山引擎模式region/access_key/secret_key/key_id四项必填。此外加密模块还提供encryption_health_check健康检查见 config.py会依次验证配置合法性、模块初始化并实际执行一次加密→解密往返测试用health-check-account账户加解密bhealth check test任何一步失败都会将状态标记为unhealthy。工作原理透明读写流程加密位于 VikingFS 层客户端与 AGFS 之间的一切加解密对两端透明。写流程客户端 VikingFS FileEncryptor KeyManager AGFS │ │ │ │ │ │ write(uri, data) │ │ │ │ │──────────────────│ │ │ │ │ │ encrypt(account_id, │ │ │ │ │ plaintext) │ │ │ │ │──────────────────────│ │ │ │ │ │derive_account_key()│ │ │ │ │───────────────────│ │ │ │ │───────────────────│ │ │ │ │ account_key │ │ │ │ 1. 生成随机 File Key │ │ │ │ 2. 用 File Key 加密内容 │ │ │ │ 3. 用 Account Key 加密 File Key │ │ │ │ 4. 构建信封格式 │ │ │ │──────────────────────│ │ │ │ │ ciphertext │ │ │ │ │─────────────────────────────────────────────────────────│ │ │ │ │ Write │ │──────────────────│ │ │ │ │ success │ │ │ │对应到FileEncryptor.encrypt的实现见 encryptor.py生成随机 32 字节 File Key 与 12 字节 data IV用 File Key 以 AES-256-GCM 加密文件内容_aes_gcm_encrypt调用 provider 的encrypt_file_key派生 Account Key 后用 AES-256-GCM 加密 File Key返回加密后的文件密钥与其独立 IV调用_build_envelope组装信封。读流程客户端 VikingFS FileEncryptor KeyManager AGFS │ │ │ │ │ │ read(uri) │ │ │ │ │──────────────────│ │ │ │ │ │──────────────────────────────────────────────────────────│ │ │ │ │ Read │ │ │──────────────────────────────────────────────────────────│ │ │ raw_bytes │ │ │ │ │ 检查魔术数 OVE1? │ │ │ │ │ 是 → decrypt() │ │ │ │ │──────────────────────│ │ │ │ │ │ derive_account_key()│ │ │ │ │────────────────────│ │ │ │ │────────────────────│ │ │ │ │ account_key │ │ │ │ 1. 解析信封格式 │ │ │ │ 2. 用 Account Key 解密 File Key │ │ │ │ 3. 用 File Key 解密内容 │ │ │ │──────────────────────│ │ │ │ │ plaintext │ │ │ │──────────────────│ │ │ │ │ content │ │ │ │对应到FileEncryptor.decrypt见 encryptor.py先检查魔术数非OVE1开头直接按明文返回向后兼容的关键否则解析信封、用 Account Key 解密 File Key、再用 File Key 解密内容。解密过程若发生 AES-GCM 认证失败会抛出AuthenticationFailedError——GCM 模式自带完整性校验密文被篡改时解密必然失败实现上还通过异常类型区分了CorruptedCiphertextError信封损坏、InvalidMagicError魔术数非法、KeyMismatchError密钥不匹配等场景见 exceptions.py。信封格式OVE1 头部加密文件使用统一的信封格式以魔术数OVE1OpenViking Encryption v1开头┌─────────────────────────────────────────────────────────────┐ │ 魔术数 │ 版本 │ Provider │ 加密的 File Key │ .. │ │ 4 字节 │ 1 字节 │ 1 字节 │ 可变长度 │ ... │ │ OVE1 │ 0x01 │ 0x01local │ │ ... │ └─────────────────────────────────────────────────────────────┘实际信封的完整二进制布局由_build_envelope通过struct.pack(!4sBBHHH, ...)构建见 encryptor.py为字段长度说明Magic4 字节bOVE1Version1 字节0x01Provider Type1 字节0x01local0x02vault0x03volcengine_kmsEncrypted File Key Length2 字节大端加密文件密钥长度Key IV Length2 字节大端文件密钥 IV 长度Data IV Length2 字节大端内容 IV 长度Encrypted File Key可变用 Account Key 加密后的文件密钥Key IV可变文件密钥的 IVData IV可变文件内容的 IVEncrypted Content可变AES-256-GCM 密文头部固定 12 字节解析时若长度不足或版本不支持都会抛错见 encryptor.py。Rust 端 RAGFS 实现了相同布局的信封构建与解析并内置了envelope_build_parse_roundtrip、full_envelope_encrypt_decrypt等单元测试验证与 Python 端字节级一致见 crates/ragfs/src/crypto/mod.rs。集成测试同样会断言 AGFS 中落盘文件以OVE1开头见 tests/integration/test_encryption_integration.py。多租户隔离密钥层面的数据边界不同账户的数据使用独立的 Account Key 加密隔离效果如下账户 A 的密钥无法解密账户 B 的文件——Account Key 由HKDF(root_key, account_id)派生账户 ID 不同则密钥不同即使 AGFS 被完全访问磁盘泄露、存储层越权没有对应密钥也无法读取数据租户隔离在密钥层面实现不依赖存储层权限即加密层兜底。这一隔离在集成测试中被显式验证测试尝试用不同提供程序解密彼此的数据期望抛出异常KeyMismatchError并断言跨提供程序解密失败符合预期而非安全漏洞见 docs/zh/guides/08-encryption.md 中跨提供程序验证一节与 tests/unit/crypto/test_encryptor.py。实操验证确认加密已生效启用加密后可通过两种方法验证方法一检查文件内容是否以 OVE1 开头# 查看文件前 4 字节 hexdump -C ./data/agfs/your-file | head -1加密文件应看到前 4 字节4f 56 45 31即 ASCII OVE100000000 4f 56 45 31 01 01 00 00 00 20 8a 7b 2c 9d 1e |OVE1..... .{,..|未加密文件则直接是明文 JSON 等可读内容。方法二端到端读写验证启用加密后通过 SDK 正常读写资源即可验证透明加密——API 无任何变化示例见 docs/zh/guides/08-encryption.mdimport asyncio from pathlib import Path from openviking_sdk import AsyncHTTPClient async def test(): client AsyncHTTPClient(urlhttp://localhost:1933, api_keyyour-key) await client.initialize() # add_resource 接收文件路径或 URL写入即自动加密 sample Path(./encrypted-sample.txt) sample.write_text(Hello, encrypted world!, encodingutf-8) await client.add_resource( pathstr(sample), options{reason: 测试加密}, ) # 读取资源自动解密应用层无感知 results await client.find(queryencrypted) print(f找到 {len(results)} 个结果) await client.close() asyncio.run(test())如果上述流程能正常写入、检索并读取明文内容说明加密已在 VikingFS 层透明生效。集成测试还覆盖了摘要/概览等衍生内容不应泄露OVE1密文这一细节见 tests/integration/test_encryption_integration.py可作为回归验证的参考。配置注意点与安全最佳实践密钥文件权限master.key必须妥善保管建议保持0600权限仅所有者可读写、定期备份、切勿提交到版本控制系统init-key在 Unix 平台会自动设置0600Vault Token 最小权限建议仅授予 Transit 引擎encrypt/decrypt路径的update能力避免使用 root token火山引擎 Access Key 最小权限仅授予目标密钥的kms:Encrypt/kms:Decrypt权限从无加密迁移到有加密启用加密不会改写已有明文文件旧文件仍可读取、新写入数据自动加密。如需加密存量数据官方推荐通过 OVPack 逻辑备份ov backup→ 切换到全新空加密存储 →ov restore的方式迁移迁移细节见 加密指南的迁移说明切换密钥提供程序是破坏性操作需先备份数据与密钥、用旧提供程序解密全部数据、配置新提供程序后再重新加密建议先在测试环境验证API Key 哈希文件层加密encryption.enabled与 API key 字段层哈希encryption.api_key_hashing.enabledArgon2id 单向哈希是两层独立保护默认api_key_hashing.enabled false自 OpenViking v0.3.12 起encryption.enabled true不再隐式启用 API key 哈希如需保持原有行为需显式配置详见 加密指南的 API Key 哈希配置。相关文档存储架构 — VikingFS 和 AGFS 架构配置指南 — 加密配置详解加密指南 — 三种提供程序的详细配置、验证与迁移步骤多租户 — 账号、用户与 Agent 的隔离模型【免费下载链接】OpenVikingSelf-evolving Context Database for AI Agents. Unify Agent Memory, Knowledge RAG and Skills.项目地址: https://gitcode.com/GitHub_Trending/op/OpenViking创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
阅读完成 · 觉得有帮助?