远程守护进程(HTTP/WebSocket 与中继 RPC)
Memories 可通过以下传输承载同一套带帧的 service::Request 协议:
- 本地 IPC(默认;通过操作系统用户认证;使用长度前缀帧)
- HTTP + WebSocket(可选监听;令牌认证;与中继 RPC 使用相同的二进制 JSON 帧)
- WSS 中继 RPC(
/v1/rpc/{room}/{slot})
直连与中继远程连接共用一种线路格式:WebSocket 二进制帧先携带 AuthFrame,再携带版本 1 的 Wire(service::Request)。保险库同步仍使用 /v1/channel。WebUI 仍仅用于查看状态。
安全规则
- 监听令牌:通过
--listen-token/MEMORIES_LISTEN_TOKEN提供,或在启用 HTTP/中继主机时生成并仅打印一次。切勿将令牌写入 TOML。 - 存储锁定时会清除令牌。
- 远程调用者使用稳定的提权命名空间
ws:remote/relay:remote(与cli:{pid}分离)。通过远程传输执行解锁和 sudo 会提升该命名空间的权限,因此后续一次性连接可在空闲窗口内保留提权状态(规则与本地相同:空闲 5 分钟 / 最长 15 分钟)。 - 桌面端 HTTP/中继主机在解锁/sudo 后提供完整的
handle_client功能面(保险库、卡片、记忆、文件、凭据、同步、MCP 授权、备份、主机上的代理绑定、远程会话、Run、CryptoJob 等),并遵循与本地 IPC 相同的提权检查。 - HTTP 监听默认使用回环地址;监听非回环地址需要
--allow-non-loopback。 - 普通 HTTP/WS 不需要证书(局域网直连的默认方式)。
- 可选 TLS:
--tls-cert/--tls-key(PEM)在同一监听地址上启用 HTTPS/WSS。https://监听 URL 必须提供这些参数。 - 信任边界之外的中继必须使用
wss://,并提供 43 个字符的房间 ID 和令牌。 - 持有监听令牌的任何人,在该传输命名空间内都与本地已提权客户端具有同等信任。应像保护密码一样保护令牌;优先使用回环地址或经过认证的网络路径。
残余风险
- 令牌被盗 ⇒ 攻击者可完全远程控制已解锁/已提权的桌面守护进程。
- 非回环 HTTP 会将带帧 API 暴露到网络;绑定回环地址之外的地址时,应使用
--tls-cert/--tls-key、反向代理、VPN 或防火墙。 - 中继 RPC(
/v1/rpc/{room}/{slot})经过认证,但并非端到端加密:其应用层 JSON 帧先传送共享监听令牌,再传送请求和响应。中继运营者或 TLS 终止端可读取令牌和 RPC 载荷。WSS 保护的是到中继的每条连接,无法防范中继本身;远程访问守护进程时应使用可信中继。 - 保险库对等同步(
/v1/channel)是独立通道,承载端到端加密载荷。在该通道中,中继运营者可看到密文长度和时间信息,无法看到资产明文。 - 主机侧代理监听器仍绑定在守护进程所在机器的回环地址;远程客户端提权后可启动它们,但只有同时能够访问该主机回环地址(通常通过独立隧道)时才能连接。
HTTP/WebSocket 主机与客户端
# Host (prints a token once if --listen-token is omitted)
memories daemon --listen http://127.0.0.1:7900
# or HTTPS URL when TLS is configured:
memories daemon --listen https://127.0.0.1:8443 \
--tls-cert certs/daemon-tls.crt --tls-key certs/daemon-tls.key --listen-token "$TOKEN"
# Client (another shell / machine that can reach the listener)
export MEMORIES_DAEMON=http://127.0.0.1:7900
export MEMORIES_DAEMON_TOKEN="$TOKEN"
memories status
memories unlock
memories sudo
memories vault list
直连 RPC 路径为 /v1/rpc(WebSocket 升级)。参数:--daemon、--daemon-token(含义与环境变量相同)。
客户端 TLS 信任
默认启用证书和主机名验证。全局选项 --ca-file PATH 会将 PEM CA 包中的所有证书加入常规信任库。对于使用自签名证书的守护进程,应显式信任其证书(证书的 DNS/IP 使用者备用名称仍必须与 URL 匹配):
memories --daemon https://localhost:8443 --daemon-token "$TOKEN" \
--ca-file certs/daemon-tls.crt status
# Equivalent CA setting, also usable with relay and HTTPS clients:
export MEMORIES_CA_FILE=certs/daemon-tls.crt
memories --daemon https://localhost:8443 --daemon-token "$TOKEN" status
# DANGEROUS: development only; prefer --ca-file instead.
memories --daemon https://localhost:8443 --daemon-token "$TOKEN" --insecure status
--insecure 会禁用证书链和主机名验证。 TLS 加密仍然启用,但攻击者可以冒充服务器,读取守护进程令牌、凭据或请求/响应数据。切勿在生产环境或不可信网络上使用。此选项仅限 CLI(没有 MEMORIES_INSECURE 环境变量)。即使使用 --insecure,显式提供的 CA 文件也必须可读且包含有效 PEM 证书;无效文件会在连接前导致失败。文件仅在启动时加载一次;修改证书包后应重启进程。
这两个选项都适用于当前进程建立的出站连接:直连守护进程 HTTPS/WSS 连接、中继 RPC 主机/客户端、保险库同步中继客户端、云端 OAuth 和 Drive HTTP、RAG API/模型下载 HTTP、使用凭据认证的 HTTPS、自动化 webhook,以及数据库 TLS 会话/代理。对于由守护进程执行的操作,应在启动守护进程时传入这些选项;客户端参数不会通过 RPC 发送,也无法改变守护进程的上游 TLS 策略:
memories --ca-file /path/internal-ca.pem daemon
# Development only: affects every outbound TLS connection in this daemon.
memories --insecure daemon
服务器的 --tls-cert / --tls-key 和共享令牌认证保持不变。数据库 --tls-ca CA_ID 仍从保险库解析 PEM 凭据;其信任与守护进程的 --ca-file 证书包合并。这两个选项都不会禁用 TLS 或 SSH 主机密钥固定。这些参数不是 TOML 设置,不会作为保险库秘密持久化,也不会配置移动端/FFI 调用者、外部程序/浏览器中的 TLS 客户端,或这些 HTTP 构建器之外由依赖管理的下载。
中继 RPC 主机与客户端
# Generate a room id (43 URL-safe characters)
memories sync room
# Host joins slot a
memories daemon \
--relay-host wss://relay.example.com \
--room "$ROOM" \
--listen-token "$TOKEN"
# Client joins slot b
export MEMORIES_DAEMON_RELAY=wss://relay.example.com
export MEMORIES_DAEMON_ROOM="$ROOM"
export MEMORIES_DAEMON_TOKEN="$TOKEN"
memories status
本地开发可配合 memories-relay 使用 ws://127.0.0.1:8787。
对于使用私有 CA 的中继,主机和客户端都可使用全局参数:
memories --ca-file /path/relay-ca.pem daemon \
--relay-host wss://relay.example.com --room "$ROOM" --listen-token "$TOKEN"
memories --ca-file /path/relay-ca.pem --daemon-relay wss://relay.example.com \
--daemon-room "$ROOM" --daemon-token "$TOKEN" status
移动端共享(前台主机)
Flutter 应用在已解锁且处于前台时,可以启动共享会话,作为主机(槽位 a)加入中继 RPC。进入后台或锁定都会结束该会话。移动端保留 FFI 禁止列表(不允许 Run/CryptoJob/MCP 授权/远程会话/代理,且共享也拒绝凭据明文复制和备份转储)。手机不会开启 HTTP 监听器。参见 mobile/README.md。
仅限本地 / 平台例外
| 功能面 | 桌面端远程(HTTP/WS / 中继) | 移动端 FFI / 共享 |
|---|---|---|
| 保险库 / 记忆 / 卡片 / 文件 / 同步 / 状态 / 解锁 / sudo | 完整支持(按需提权) | 在 FFI 允许范围内完整支持 |
| MCP 授权/撤销、Backup、CredentialCopy | 提权后完整支持 | 共享中禁止;FFI 允许在本地复制/备份 |
| Run、CryptoJob、Remote、Proxy | 提权后完整支持(在主机上运行) | 禁止(无桌面运行时) |
| HTTP/WS 监听 | 可选(--listen) |
不可用 |
人格自动化 webhook
启用 HTTP 监听后,以下端点可接收入站自动化触发请求:
POST /v1/persona/{vault}/{persona}/automation/trigger
Authorization: Bearer <persona world.automation.webhook_token>
Content-Type: application/json
{"hook":"HOOK_ID"}
守护进程必须已解锁(与其他写入 RPC 相同)。监听令牌启用 HTTP 功能面;自动化 webhook_token(通过 persona automation put --webhook-token 设置)授权该钩子。中继主机通过中继上的 POST /v1/persona/{room}/{vault}/{persona}/automation/trigger 接收同一调用(请求体和 webhook bearer 相同);房间段是路径的唯一区别,中继会将一个现有的 persona_automation_trigger 线路帧转发给已连接主机,而非在本地处理或向外发起请求。
等效 CLI:
memories persona automation trigger VAULT PERSONA --id HOOK_ID \
--source webhook --token "$WEBHOOK_TOKEN"