Skip to content

写命令鉴权契约

This content is not available in your language yet.

mailagent 用一条简单规则保护写操作:读命令免鉴权,写命令需 API key。本页是这条规则的完整契约与 agent 安全须知。

本机访问 SQLite,无需 token:

email get / list / body / search / list-pinned
attachment list / download / search
admin stats / health / db-version / fts-health / pm2-status / queue-depth /
export-diagnostics / dead-letter list / config show / config get
llm selftest / stats
kos stats
calendar events / today / week / event-get / sync-status / recurring discover
folder discover
report list / get / config-get
api-key list
im status
debug * (email-source / mail-structure / inline-images / applescript-fetch / notion-page)
notion page-orphans (--dry-run) / file-link-audit (--dry-run)

会改 SQLite / Notion / Mail.app / Exchange 的命令,必须提供 MAILAGENT_CLI_API_KEY:

email resync / delete / flag / pin / unpin / archive / draft / send / unsubscribe
attachment extract / cleanup-orphans
llm run / retry-failed / compare-paths (--no-dry-run)
backfill body / metadata
notion resync / update-flag / create-task / archive
file-link-audit (--no-dry-run) / page-orphans (--archive-... / --insert-...)
admin dead-letter retry / delete / cleanup-* / repair-parents / repair-date-tz /
config set / config show|get (仅加 --show-secrets 时)
init * (fetch-cache / analyze / fix-* / update-parents / sync-new / all)
calendar create / update / delete / rsvp (真跑) / sync-now / expand (--no-dry-run) / replay / recurring replay
folder enable / disable / create / rename / delete-folder / cleanup
report run / delete / config-set / agent-create / agent-delete
api-key create / revoke / rotate
im pair
contact backfill (--rescan / --calibrate-only 真跑)
project-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。

两种提供方式,优先用环境变量:

Terminal window
# ✅ 推荐:环境变量(不进 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

破坏性命令(notion archive / admin cleanup-* / admin dead-letter delete / folder delete-folder / calendar delete)默认要交互确认。agent 调用必须显式传 --yes 跳过 prompt:

Terminal window
mailagent notion archive 36215375-830d-... --yes
mailagent admin cleanup-deadletter --older-than 30 --no-dry-run --yes
mailagent calendar delete <ical-uid> --yes

--yes 不替代鉴权——破坏性写命令既要 --yes 又要 API key。

--dry-run 只打 plan、不写任何东西,因此不需要 API key。这让 agent 能在没有 token 的环境里先验证一条写命令「会做什么」:

Terminal window
# 无需 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)——这是有意的「默认安全」。唯一逃生口是显式设环境变量:

Terminal window
# 仅限本地 dev:服务端没配 token 时放行写命令
MAILAGENT_CLI_ALLOW_UNAUTH_WRITES=true mailagent email flag 53675 --is-read

给写自动化 / 让 AI agent 调 mailagent 时,遵守这几条:

  1. token 从 secret store 注入环境变量,不 hardcode、不 inline --api-key、不进 repo。
  2. CI / CD 用 CLI_API_KEY 环境变量,并确保 MAILAGENT_CLI_ALLOW_UNAUTH_WRITES 未设。
  3. agent 默认只给读命令;要执行写命令时,先 --dry-run 让 agent 输出 plan、人工 / 上层 gate 审核,再真跑。
  4. 破坏性命令(delete / cleanup / archive)要双闸:--yes + 有效 API key。
  5. 退出码 4 当作硬失败,不自动重试——重试一个鉴权失败的命令只会刷日志,不会成功。