写命令鉴权契约
mailagent 用一条简单规则保护写操作:读命令免鉴权,写命令需 API key。本页是这条规则的完整契约与 agent 安全须知。
读命令 vs 写命令
Section titled “读命令 vs 写命令”读命令(免鉴权)
Section titled “读命令(免鉴权)”本机访问 SQLite,无需 token:
email get / list / body / searchattachment list / downloadadmin stats / health / db-version / dead-letter listllm selftest / statscalendar recurring discoverdebug * (email-source / mail-structure / inline-images / applescript-fetch / notion-page)notion page-orphans (--dry-run) / file-link-audit (--dry-run)写命令(需鉴权)
Section titled “写命令(需鉴权)”会改 SQLite / Notion / Mail.app 的命令,必须提供 MAILAGENT_CLI_API_KEY:
email resync / delete / flag / draftattachment derive / cleanup-orphansllm run / retry-failed / compare-paths (--no-dry-run)backfill body / derivativesnotion resync / update-flag / create-task / archive file-link-audit (--no-dry-run) / page-orphans (--archive-... / --insert-...)admin dead-letter retry / cleanup-* / repair-parentsinit * (fetch-cache / analyze / fix-* / update-parents / sync-new / all)calendar expand (--no-dry-run) / recurring replayproject-progress sync服务端 .env 配 MAILAGENT_CLI_API_KEY 后,写命令必须提供同值,CLI 用 hmac.compare_digest 常量时间比对。不上 OAuth、不做 RBAC、不区分用户——目的不是防本机其他用户(macOS Full Disk Access 已锁住 SQLite),而是防 agent / 第三方进程 / 误粘贴命令 误触发写操作。
校验失败 → 退出码 4 + error.code = E_AUTH_FAILED。
--api-key vs 环境变量
Section titled “--api-key vs 环境变量”两种提供方式,优先用环境变量:
# ✅ 推荐:环境变量(不进 shell history、不进多数进程列表快照)export MAILAGENT_CLI_API_KEY="$(cat /run/secrets/mailagent_cli_key)"mailagent email flag 53675 --is-read
# ⚠️ inline flag:会进 shell history + ps 进程列表,泄漏面更大mailagent --api-key xxx email flag 53675 --is-read优先级(高 → 低):
--api-key > $MAILAGENT_CLI_API_KEY > .env 里的 MAILAGENT_CLI_API_KEY--yes / --confirm —— 破坏性命令
Section titled “--yes / --confirm —— 破坏性命令”破坏性命令(email delete / admin cleanup-* / notion archive)默认要交互确认。agent 调用必须显式传 --yes 跳过 prompt:
mailagent email delete 53675 --yesmailagent notion archive 36215375-830d-... --yesmailagent admin cleanup-deadletter --older-than 30 --no-dry-run --yes部分高危场景还可叠加 --confirm <internal_id> 二次确认,防 wrong target。--yes 不替代鉴权——破坏性写命令既要 --yes 又要 API key。
--dry-run 跳过鉴权
Section titled “--dry-run 跳过鉴权”--dry-run 只打 plan、不写任何东西,因此不需要 API key。这让 agent 能在没有 token 的环境里先验证一条写命令”会做什么”:
# 无需 API key:dry-run 只输出计划mailagent -o json email resync 53675 --dry-run | jq '.data'mailagent -o json llm run 53675 --dry-run | jq '.data.labels'工作流建议:先 --dry-run 验证 plan → 再去真跑(带 API key)。
dev bypass 风险(ALLOW_UNAUTH_WRITES)
Section titled “dev bypass 风险(ALLOW_UNAUTH_WRITES)”服务端没配 MAILAGENT_CLI_API_KEY 时,写命令默认拒绝(退 4)——这是有意的”默认安全”。唯一逃生口是显式设环境变量:
# 仅限本地 dev:服务端没配 token 时放行写命令MAILAGENT_CLI_ALLOW_UNAUTH_WRITES=true mailagent email flag 53675 --is-readAgent 安全须知
Section titled “Agent 安全须知”给写自动化 / 让 AI agent 调 mailagent 时,遵守这几条:
- token 从 secret store 注入环境变量,不 hardcode、不 inline
--api-key、不进 repo。 - CI / CD 用
CLI_API_KEY环境变量,并确保MAILAGENT_CLI_ALLOW_UNAUTH_WRITES未设。 - agent 默认只给读命令;要执行写命令时,先
--dry-run让 agent 输出 plan、人工 / 上层 gate 审核,再真跑。 - 破坏性命令(delete / cleanup / archive)要双闸:
--yes+ 有效 API key,必要时--confirm <id>。 - 退出码
4当作硬失败,不自动重试——重试一个鉴权失败的命令只会刷日志,不会成功。
- 自动化环境安装与配置 —
MAILAGENT_CLI_API_KEY注入 - 退出码契约 —
4/E_AUTH_FAILED - 10 大命令组参考 — 各写命令的 flag
- 鉴权 spec:
agent-cli-rfc.md§5.3 ·cli-reference.md