news 2026/10/9 2:29:02

OpenHanako(HanaAgent)安全策略解读:本地凭证存储契约、权限自愈与漏洞报告机制

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
OpenHanako(HanaAgent)安全策略解读:本地凭证存储契约、权限自愈与漏洞报告机制
  • 人工智能
  • AI Agent
  • AI 应用
  • 交互助手
  • 桌面应用
  • 多智能体
  • Agent 记忆
  • 工具调用

【免费下载链接】OpenHanako

可作为日常办公助手,无需复杂配置即可让 AI 记住信息、操作电脑、搜索浏览、执行代码等。具备记忆系统、人格塑造、多 Agent 协作、安全沙盒等核心功能,支持多平台接入和插件扩展。

项目地址:https://gitcode.com/liliMozi/OpenHanako
点击查看免费下载

本文以 SECURITY.md 为骨架,结合 OpenHanako 仓库中的安全模块实现,系统讲解该项目的漏洞报告流程、安全关注范围、本地凭证存储的权限契约(owner-only 读写)、每次启动都会执行的文件权限自愈机制,以及迁移备份的 90 天保留策略。读完你不仅能理解这份安全文档的全部承诺,还能掌握这些承诺在代码中是如何落地与验证的,例如凭证文件写入、权限修复、跨平台差异等具体实现细节。

1. 项目背景与安全文档定位

OpenHanako 是一款可作为日常办公助手的 AI 桌面应用,具备记忆系统、人格塑造、多 Agent 协作、安全沙盒等核心能力,支持多平台接入和插件扩展。项目已更名为HanaAgent,但出于过渡期兼容考虑,仓库路径与安全报告 URL 仍保留在旧版openhanako名称上——这一点在安全文档开篇即有说明。

该项目的安全文档承担了三类职责:

  1. 外部沟通:明确漏洞发现者如何报告问题、响应时限;
  2. 边界声明:界定哪些安全问题是项目关注范围(Scope);
  3. 存储契约:详细说明本地凭证(Provider 密钥、OAuth Token、设备记录)在数据目录中的存放方式、权限保证与已知边界。

2. 漏洞报告流程(Reporting a Vulnerability)

2.1 报告渠道

安全文档给出的报告方式分为两个优先级:

  • 首选:在仓库 Security 标签页打开 Private vulnerability report(私有漏洞报告),路径为https://github.com/liliMozi/openhanako/security;
  • 备选:若私有报告不可用,则在https://github.com/liliMozi/openhanako/issues提交 Issue。

2.2 报告需要包含的信息

为了让维护者能快速复现与评估,报告应包含:

  • 漏洞的描述(Description of the vulnerability);
  • 复现步骤(Steps to reproduce);
  • 潜在影响(Potential impact)。

2.3 响应承诺

维护者承诺在72 小时内响应,并先与报告者协作修复,再对外公开披露(coordinated disclosure)。这是一个典型的负责任的漏洞披露流程,意味着漏洞细节在修复完成前不会被公开展示。

3. 安全关注范围(Scope)

SECURITY.md 明确了四个重点关注的安全风险类型,这些也是仓库中安全代码模块实际防范的对象:

风险类型英文原文仓库中的相关机制
沙盒逃逸Sandbox escape(PathGuard / Seatbelt bypass)lib/sandbox/下的沙盒策略模块
凭证泄露Credential leakagecore/credential-file-healer.ts、shared/secret-fs.ts等凭证保管模块
远程代码执行Remote code execution执行边界与策略模块(如 core/execution-boundary.ts、core/execution-router.ts)
Electron 渲染进程 XSSCross-site scripting in the Electron renderer桌面端 CSP 配置(vite.csp-profiles.ts)及配套的 csp-sync.test.ts

从源码结构看,这份 Scope 列表与仓库安全基础设施的划分一一对应,属于“有实际防御实现支撑的边界声明”,而非空泛的承诺。

4. 本地凭证存储契约(Local credential storage)

4.1 数据目录与存放位置

Provider 密钥、OAuth Token 和设备记录均存放在数据目录中,该目录由环境变量HANA_HOME指定,默认值为~/.hanako(即用户主目录下的.hanako隐藏目录)。

4.2 项目承诺的三项保证

安全文档明确承诺以下三点,每一项都有对应的源码实现:

保证一:凭证文件仅所有者可读写,数据目录仅所有者可访问。

代码层面的落地位于 shared/secret-fs.ts,其中定义了两个核心常量:

  • SECRET_FILE_MODE = 0o600:凭证文件,所有者可读可写,其他任何账户无任何权限;
  • SECRET_DIR_MODE = 0o700:凭证目录,仅所有者可进入和列出。

该模块特意将权限固化在函数内部而非作为参数传入,原因在模块注释中说明得很清楚:一个把 mode 作为可选参数的通用原子写函数,每一个新调用点都可能是"忘记传权限参数"从而写出全机器可读凭证的隐患。这里权限不是参数,调用方根本不可能写错,静态扫描也能仅凭函数名区分凭证写入与普通写入。

凭证写入统一走writeSecretFileSync(filePath, content):先清除可能残留的临时文件(.tmp),再以0o600创建临时文件并写入内容,随后做一次 best-effort 的权限收紧(tightenBestEffort),最后原子rename到目标位置。之所以要先清残留临时文件,是因为"以 mode 创建文件"对已存在的文件不生效——若一次崩溃留下了旧临时文件,它会把旧权限带给下一个写入。

从调用面来看,writeSecretFileSync被 core/migrations.ts、core/provider-catalog.ts、core/device-registry.ts、core/local-user-account.ts、core/web-session-store.ts、core/plugin-config.ts、core/first-run.ts 等大量模块共用,构成了整个数据目录的凭证写入统一入口。

保证二:每次启动都验证权限,发生漂移时自动修复并记录日志。

新写入文件带正确权限,只能覆盖"升级后写入的文件";磁盘上已有的文件会保留其创建时的权限,且永远不会被重写的文件会一直带着旧权限。因此每次启动都执行自愈,而非只做一次性迁移——因为权限会在之后再次漂移:恢复备份、跨机器拷贝数据目录、外部同步都会重新引入原始权限。

实现位于 core/credential-file-healer.ts 的healCredentialFileModes({ hanakoHome, log }),其工作范围包括:

  • 数据目录本身(收紧为0o700);
  • 顶层凭证文件清单TOP_LEVEL_SECRET_FILES,共 10 个:provider-catalog.json、models.json、added-models.yaml、auth.json、device-credentials.json、devices.json、pairing-sessions.json、local-user-auth.json、users.json、web-sessions.json;
  • 每个 Agent 目录下的config.yaml(可能含 Provider 密钥),以及迁移过程中产生的config.yaml.pre-scope-migration备份、config.yaml.tmp崩溃残留;
  • 三个整树凭证目录(SECRET_TREES):migration-backups(迁移备份)、本地 Provider 插件目录(其定义文件携带 Provider 密钥)、security目录(签名密钥与授权记录);
  • 插件数据目录中每个插件的config.yaml(可能持有连接器与服务凭证),但只修配置文件本身,不动插件数据目录里属于其他 store 的下载文件、任务状态与产物;
  • 会话清单迁移检查点(checkpoints/session-manifest/)内完整拷贝的 agents 目录。

每次修复都会记录日志(如[credential-custody] tightened <相对路径>);修复失败的文件会被归入failed列表并上报错误总线(errorBus,以credential-custody:<路径>去重),但不会中断应用启动——因为部分文件系统(可移动介质、网络挂载)会直接拒绝 chmod,若因此打断用户反而小题大做。

保证三:迁移产生的备份同样持有凭证副本,超过 90 天即被清理,且仅在"存活目录可读且非空"时清理。

实现位于 core/credential-backup-retention.ts 的pruneStaleCredentialBackups({ hanakoHome, now, maxAgeMs, log }):

  • 保留窗口常量CREDENTIAL_BACKUP_MAX_AGE_MS = 90 * DAY_MS,即 90 天;
  • 删除(不可逆)必须同时满足两个条件:备份超过保留窗口,且当前provider-catalog.json可读、可解析、含非空 providers;
  • 若存活目录缺失、无法解析或为空,无论备份多旧都全部保留——这正是回滚存在的目的;
  • 每个决定(删除或保留)都记录日志,保证策略可审计而非静默执行;
  • 健康检查刻意直接读取并解析目录文件,而不是走 catalog store 的加载器——因为 store 的加载器在目录缺失时会回退触发旧文件迁移,让一次"提问"产生改写状态的副作用(对应测试 credential-backup-retention.test.ts 专门验证了"缺失的目录必须保持缺失")。

4.3 自愈与保留在启动序列中的位置

这两个启动步骤在 core/engine.ts 中以runBestEffortStartupMigrationStep形式顺序执行(见 core/engine.ts):

  1. 先pruneStaleCredentialBackups(步骤credential-backup-retention)清理过期迁移备份;
  2. 再healCredentialFileModes(步骤credential-custody)收紧凭证权限。

代码注释解释了放置顺序的用意:放在所有数据迁移之后,让本轮迁移刚写出的文件也被覆盖到。两个步骤互相独立,任何一步出意外都不会连累另一步——"清理"和"矫正"解耦。

另外值得注意的工程细节:目录名全部从所属模块导入常量,而非各处重复拼写。例如 core/security-dir.ts 是唯一命名security目录的地方,core/migration-backups.ts 是唯一命名migration-backups的地方。模块注释记录了一次真实事故:某列表手写了providers而 store 实际写的是provider-plugins,导致自愈 pass 走过一条不存在的路径、静默地什么都没修。这个教训直接促成了"目录名单一来源"的约定。

5. 保护的边界:什么不是承诺

SECURITY.md 诚实且具体地划出了权限保护的三个边界:

5.1 同用户程序不可防

权限位决定的是"哪些账户可以打开文件",它无法限制以同一用户身份运行的程序——这类程序可以读取该用户能读取的一切。要收窄这一点,需要由操作系统凭证存储(如 macOS Keychain、Windows Credential Locker)键控的加密,而本项目目前没有做("this project does not do today")。

5.2 Windows 平台不执行任何权限操作

NTFS 不实现 POSIX 权限位,平台文件 API 也无法表达它们,因此应用在 Windows 上完全不执行权限工作(secret-fs.ts中SUPPORTS_POSIX_MODE = process.platform !== "win32",Windows 分支直接跳过 chmod)。在 Windows 上真正保护数据的是数据目录从父目录继承的 ACL:

  • 默认位置(用户配置文件内)已排除其他标准账户;
  • 但通过HANA_HOME把数据目录放到别处时,它继承的权限取决于目标位置的授权,应用既不调整也不报告。

因此文档给出的 Windows 建议是:尽量让数据目录留在默认位置。

5.3 凭证以明文存储

凭证文件是明文存放的,权限保护只是"谁可以打开",不提供内容加密。安全文档据此给出操作纪律:不要把数据目录放进版本控制、共享盘或转发的压缩包里。

6. 测试覆盖:契约如何被验证

这份安全契约不仅有文档与实现,还有成体系的测试印证:

  • tests/credential-file-healer.test.ts(POSIX 平台运行)验证了:
    • 数据目录本身被收紧为0o700;
    • 10 个顶层凭证文件全部收紧为0o600并进入healed列表;
    • 每个 Agent 的config.yaml、scope 迁移备份config.yaml.pre-scope-migration、崩溃残留config.yaml.tmp(含检查点内副本)都被修复;
    • migration-backups目录树、本地 Provider 插件目录树、security目录树(签名密钥resource-ticket-key、授权记录grants.json)整体收紧;
    • 插件数据目录只修配置文件、不动邻居文件(负向断言同样构成契约);
    • 已合规时保持静默(healed为空、无日志);
    • 缺失数据目录时抛错而非假装干净通过;
    • 某个文件 chmod 失败时记入failed,其余文件照常处理。
  • tests/credential-backup-retention.test.ts 验证了:
    • 超过 90 天且存活目录健康时删除备份;
    • 窗口内(如 89 天)保留,理由为within-retention-window;
    • 存活目录缺失/无法解析/无 providers 时无条件保留所有备份(live-catalog-unusable);
    • 健康检查不会触发目录重建;
    • 保留窗口常量恰好等于 90 天。

这些测试直接对应 SECURITY.md 中"每次启动验证并在漂移时恢复、每次修正都记录日志、备份 90 天后清理且仅当回滚目标健康时清理"的每一句承诺,属于可执行的契约定义。

7. 实操要点速查

将本文内容沉淀为可直接照做的检查清单:

  1. 数据目录位置:确认HANA_HOME指向可信的本地路径;默认~/.hanako即可,不要为了省事把它放到共享盘或网盘同步目录。
  2. Windows 用户:保持数据目录在默认位置,不要通过HANA_HOME挪到权限不受控的目录;不要期待应用会帮你收紧权限。
  3. 权限巡检:在 Linux/macOS 下可以自行抽查——ls -l ~/.hanako应为drwx------(0o700),其中的auth.json、provider-catalog.json等应为-rw-------(0o600)。若发现漂移,重启应用即可触发自愈并产生[credential-custody] tightened ...日志。
  4. 备份纪律:迁移备份最多保留 90 天且存活目录健康时才会清理;涉及回滚时不要手动删除migration-backups。
  5. 明文凭证意识:任何情况下都不要把数据目录纳入版本控制、打包或传输;同用户下的其他程序仍可读取这些明文文件。
  6. 漏洞报告:遵循私有报告优先的流程,报告需包含描述、复现步骤与潜在影响,响应承诺为 72 小时内。

8. 总结

SECURITY.md 是一份"承诺 + 边界"双轨并行的安全文档:它既给出了外部可依赖的漏洞报告流程与响应时限,又用精确的语言划定了本地凭证保护的保证范围与三个明确边界(同用户程序、Windows ACL 继承、明文存储)。而仓库源码把每一句承诺都落成了可执行、可测试的模块——统一入口的 owner-only 写入(secret-fs.ts)、每次启动幂等的权限自愈(credential-file-healer.ts)、90 天可审计的备份保留(credential-backup-retention.ts),并由 credential-file-healer.test.ts 与 credential-backup-retention.test.ts 固化为契约。理解这份文档,等于同时理解了该应用在本地凭证安全上"做了什么、不做什么、以及为什么"。

  • 人工智能
  • AI Agent
  • AI 应用
  • 交互助手
  • 桌面应用
  • 多智能体
  • Agent 记忆
  • 工具调用

【免费下载链接】OpenHanako

可作为日常办公助手,无需复杂配置即可让 AI 记住信息、操作电脑、搜索浏览、执行代码等。具备记忆系统、人格塑造、多 Agent 协作、安全沙盒等核心功能,支持多平台接入和插件扩展。

项目地址:https://gitcode.com/liliMozi/OpenHanako
点击查看免费下载

相关推荐

上一篇:5分钟把魔兽世界宏命令工具跑起来:wow_api的API查询与智能宏生成全攻略
下一篇:魔兽世界插件开发快速上手指南:wow_api 工具集全解析

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/9 2:28:50

中小企业DeepSeek私有化部署实战:从华为云环境搭建到性能优化

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/9 2:23:58

Apache OpenWhisk 构建辅助脚本 `redo` 与 `citool` 实战指南

后端云原生 【免费下载链接】openwhisk Apache OpenWhisk is an open source serverless cloud platform 项目地址&#xff1a; https://gitcode.com/gh_mirrors/ope/openwhisk 点击查看 免费下载 导读 本文以 tools/build/README.md 为主线&#xff0c;系统讲解 Apache Open…

作者头像 李华
网站建设 2026/10/9 2:21:22

家具电商详情页设计及主图生成全套注意事项

&#xff08;运营美工通用&#xff0c;适配淘宝/拼多多/抖音小店/1688&#xff0c;结合木创家AI落地要点&#xff09;一、首屏图核心&#xff1a;5秒抓住客户&#xff0c;决定是否往下滑1. 首屏大图必须直击卖点&#xff0c; 不要放杂乱场景图&#xff0c;优先放全景实景图核心…

作者头像 李华