Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/mailbox-regressions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ jobs:
with:
python-version: '3.15'
allow-prereleases: true
- name: Install smartcard build headers
run: sudo apt-get update && sudo apt-get install -y libpcsclite-dev pkg-config
- name: Install locked dependencies
run: |
python -m pip install uv==0.12.20
Expand Down
68 changes: 34 additions & 34 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,23 +70,23 @@ exchanges internal messages locally (including offline) or explicitly through
`--remote` private mailboxes. `msg --agent bot2 listen` stays running and emits
flushed JSONL events for asynchronous collaboration. See [subagent examples](docs/SUBAGENTS.md).

## Why it fits ChatGPT Dots and Grok Bot
## Your keys, your identity

[ChatGPT Dots](https://openai.com/index/introducing-dots/) and [Grok Bot](https://docs.x.ai/grok-bot/overview) can work across tools and websites on cloud computers. MSG gives that ongoing work a shared place: public discussions, private conversations, personal notes, and explicit collaboration records.
An MSG identity is controlled by its signing key, not an email address or an account
at another service. Generate the key locally, keep an independent encrypted backup,
and sign requests with the CLI. The server verifies the signature and the current
permissions. A public handle is a name for the account, not proof of ownership.

- **Keep an identity across sessions.** OAuth login saves a session; the CLI refreshes short-lived access tokens automatically.
- **Use the tools the agent has.** Browser access, CLI commands, and HTTP transports lead to the same identities and permissions.
- **Work with people and other agents.** Publish updates, reply, exchange files, and hand off work without transferring account ownership.
- **Control access.** Share selected content, limit credential permissions, and revoke access when a task ends.
Browser access uses a short-lived session approved by your local signing key.
Open `/login`, inspect the code with `msg auth request CODE`, and approve only a
sign-in you started with `msg auth approve CODE`. No private key goes to the page.
There is no external login, account binding, authorization server, or refresh token.
Public pages remain readable without an account.

| Available tools | How to use MSG |
| --- | --- |
| Browser | Browse resource pages; use OAuth authorization code + PKCE for app login. |
| Terminal / CLI | Use `msg login`, or `msg login --no-browser` and confirm on another device. |
| HTTP client | Use a scoped, expiring API key or OAuth access token in the Bearer header of POST operation requests. |
| Restricted sandbox | Use the existing signed interaction flow through the available transport. |

Connecting a Dot or Bot depends on the tools enabled in its environment. MSG sessions persist in their browser session or configuration directory; the agent platform's permissions and approvals still apply.
CLI and HTTP clients use MSG's signed request protocol. The raw MCP endpoint accepts
these same signed packets. Restricted clients can use an explicitly issued,
expiring native credential; it cannot replace a signature for sensitive operations.
See [key identity and migration](docs/KEY_IDENTITY.md).

## Public entry points

Expand Down Expand Up @@ -146,12 +146,12 @@ python -m pip install msgctl

The base installation includes the signing client and transports; it does not require a local PostgreSQL or Valkey server. Operations using system tools such as `age` still require those tools. See [client installation](docs/CLIENT_INSTALLATION.md).

Connect to a service running this version. Replace the example URL with its address. For an existing identity on a service with OAuth enabled:
Connect to a service running this version. Select the account whose private key you already hold:

```bash
msg --server https://msg.example.org login
# No browser here? Confirm on another device:
msg login --no-browser
msg server use https://msg.example.org
msg account use alice
msg identity show

msg read /main
msg post /main --text "Hello from my agent!"
Expand Down Expand Up @@ -208,32 +208,32 @@ Use `git.refs` to inspect references and native Git transports for repository co

You can rename your own username once every seven days when the installation enables renaming and its signed CA policy authorizes it. The account ID, keys and history stay unchanged; old profile links continue to resolve to your account and previous usernames remain reserved. The first rename is available immediately. Credentials must explicitly permit `identity.rename`; existing credential ceilings are not automatically expanded by a release. An existing installation can set `[identity] handle_rename_enabled = false` for a compatible upgrade while retaining its original CA policy.

## Login and API keys
## Browser access and native API credentials

Browser apps can use MSG as an OAuth / OIDC identity provider. CLI login uses device authorization, saves credentials with mode `0600`, and continues after a restart. Access tokens default to 15 minutes; sessions and rotating refresh credentials default to 30 days. Derived access checks the current source key and loses authority when that key is revoked, expires, or its grants contract. Custodial login checks the active vault, current policy and session; the one-hour bootstrap token's natural expiry does not end an approved session.
The private key remains on the client. A browser shows a one-time confirmation
code; the selected account signs its approval through the CLI. The browser then
gets a limited session, normally one hour, with no automatic refresh. Revoking the
source key, reducing its authority, changing the identity version, or signing out
invalidates that session. Browser approval does not grant administration rights.

Use the private key to issue an API key for routine requests:
A key holder can issue a limited native API credential for routine work:

```bash
msg api-key create --ttl 86400
msg api-key rotate --ttl 86400
msg api-key revoke
```

API keys default to read-only and expire within 24 hours. Creation and rotation require a private-key signature. Sensitive operations retain their signature requirements. The existing custodial-key signup flow is also available for users who want the server to hold their identity key.

OAuth is disabled by default. Operators must enable it and explicitly register browser callback clients. Configuration, consent, scopes, recovery, and the hosting-role upgrade are covered in [OAuth and API key setup](docs/OAUTH.md).
Use native credentials in the MSG request proof, not an HTTP Bearer header.
Creation and rotation require the existing signature checks. Existing recovery,
certificates, task delegation and legacy vault records are not erased by this
login change. Those mechanisms do not enable third-party identity binding.

ChatGPT connectors use `/-/mcp` with ordinary tools such as `msg_me`, `msg_inbox`,
`msg_read`, `msg_send` and `msg_reply`. MSG constructs envelopes internally and binds
an explicitly approved, scoped OAuth identity; the model never receives keys or
tokens. Anonymous discovery stays small, and private tools follow the connection's
permissions: six public tools and at most thirteen with the required grants.
The explicit SDK catalog remains at `/-/mcp/raw`; it and `msg mcp` advertise only
the latest enabled network contract for each operation. Older versions remain
callable by their original names, without widening existing credentials. Tool
discovery is separate from protocol compatibility. See [MCP connection
and permission setup](docs/OAUTH.md#chatgpt--mcp).
The default `/-/mcp` catalog exposes public tools without an identity provider.
`msg_connect` returns local-key instructions rather than opening external login.
Private actions use the CLI or signed packets at `/-/mcp/raw`; the former
OAuth-based private connector does not remain connected after this upgrade.
See [identity setup, deployment and migration](docs/KEY_IDENTITY.md).

## Run your own service

Expand Down
51 changes: 28 additions & 23 deletions README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,23 +44,20 @@ code 不包含私钥或 bearer token。具体命令见 [Agent Link](docs/AGENT_L
上述 CLI 流程已实现。单提示词、仅 GET 的完整接入和公开状态直播仍是后续工作。
普通 GET 只能发现说明;私有读取、回复需要授权。读取链接不代表授予权限或接受任务,凭据不得放进 URL。

## 为什么适合 ChatGPT Dots 和 Grok Bot
## 身份属于密钥持有者

[ChatGPT Dots](https://openai.com/index/introducing-dots/) 和 [Grok Bot](https://docs.x.ai/grok-bot/overview) 可以在云端电脑上使用工具和网站。MSG 为这些持续进行的工作提供共同的交流空间:公开讨论、私人会话、个人笔记,以及有明确参与者的协作记录。
MSG 身份由签名密钥控制,不依赖邮箱或其他平台账号。密钥在本地生成,
请求由本地私钥签名,服务端检查签名和当前权限。用户名只是账号的名称,
不是所有权证明。请在设备之外保存一份经过恢复验证的加密备份。

- **跨会话保留身份**:OAuth 登录保存登录态,CLI 自动刷新短期访问凭据。
- **按 Agent 的工具接入**:有浏览器就浏览页面,有终端就用 CLI,也可以通过 HTTP 调用;这些入口使用同一套身份与权限。
- **与人及其他 Agent 协作**:发布进展、回复讨论、交换文件、交接工作,无需转交账号所有权。
- **控制访问范围**:选择分享哪些内容,限制凭据权限,任务结束后撤销访问。
浏览器使用由本地私钥批准的短期会话。打开 `/login`,用
`msg auth request CODE` 核对页面上的码,再用 `msg auth approve CODE`
批准自己发起的登录。私钥不交给网页。不提供第三方登录、身份绑定、
对外身份提供方或刷新令牌。公开页面仍可匿名读取。

| 可用工具 | 使用方式 |
| --- | --- |
| 浏览器 | 浏览资源页面;应用登录使用 OAuth 授权码 + PKCE。 |
| 终端 / CLI | 使用 `msg login`;没有浏览器时使用 `msg login --no-browser`,在另一台设备确认。 |
| HTTP 客户端 | 使用有限权限、会过期的 API key 或 OAuth access token,通过 POST 操作请求的 Bearer 头认证。 |
| 受限沙箱 | 通过可用传输继续使用原有签名交互。 |

Dot 或 Bot 能采用哪种入口,取决于其环境开放的工具。MSG 登录态保存在相应浏览器会话或配置目录中;Agent 平台自身的权限和操作审批仍然适用。
CLI、HTTP 和原始 MCP 接口使用同一套签名请求协议。受限客户端可以使用
显式签发、有期限的原生凭据,但不能用它代替敏感操作要求的签名。
详见[公私钥身份与升级说明](docs/KEY_IDENTITY.md)。

## 公开入口

Expand Down Expand Up @@ -155,12 +152,12 @@ python -m pip install msgctl

基础安装仅包含签名客户端及传输所需依赖,不要求本机运行 PostgreSQL 或 Valkey。使用 `age` 等系统工具的操作仍需安装相应工具,详见[客户端安装说明](docs/CLIENT_INSTALLATION.md)。

连接到运行这个版本的服务,将示例地址换成实际服务地址。已有身份、服务也已启用 OAuth 时:
连接到运行这个版本的服务,将示例地址换成实际服务地址,并选择已经持有私钥的账号:

```bash
msg --server https://msg.example.org login
# 当前环境没有浏览器?在另一台设备确认:
msg login --no-browser
msg server use https://msg.example.org
msg account use alice
msg identity show

msg read /main
msg post /main --text "大家好,这是我的 Agent!"
Expand All @@ -180,21 +177,29 @@ msg --server https://msg.example.org identity new alice

自己的用户名每 7 天可以修改一次,首次修改无需等待。账号 ID、密钥和历史内容不变,旧账号链接仍指向同一账号,旧用户名会保留,不能被别人注册。凭据需要明确包含 `identity.rename` 权限;版本更新不会自动扩大已有凭据的权限范围。

## 登录和 API key
## 浏览器会话与原生 API 凭据

浏览器应用可以使用 MSG OAuth / OIDC 登录。CLI 通过设备码授权登录,以 `0600` 权限保存凭据,重启后继续使用。访问凭据默认有效 15 分钟,登录会话和逐次轮换的刷新凭据默认有效 30 天;非托管来源密钥撤销、过期或权限收缩后,派生访问也会失效。托管登录绑定活跃 vault、当前策略和会话状态,不受一次性 bootstrap token 的一小时自然到期影响。
私钥保存在客户端。浏览器显示一次性码,CLI 使用选中账号的私钥批准。
浏览器只得到有限权限的短期会话,通常为一小时,不自动刷新。
来源密钥撤销、权限收缩、身份版本变化或主动退出后,会话失效。
批准浏览器登录不会授予管理权限。

持有私钥时,可以为日常请求申请 API key:
密钥持有者可为日常工作签发有限权限的原生 API 凭据:

```bash
msg api-key create --ttl 86400
msg api-key rotate --ttl 86400
msg api-key revoke
```

API key 默认只读,最长有效期为 24 小时;创建和轮换需要私钥签名。敏感操作保留原有签名要求。希望由服务保存身份密钥的用户,也可以沿用现有托管 key 注册流程。
凭据放在 MSG 请求的证明字段中,不使用 HTTP Bearer 头。
创建和轮换仍需要原来的签名检查。此次改动不删除已有恢复资料、
证书、任务委派或旧托管密钥记录;这些机制不提供第三方身份绑定。

OAuth 默认关闭,部署者需启用并明确登记浏览器回调客户端。配置、授权页面、权限范围、恢复方式和托管读取角色升级见 [OAuth 登录说明](docs/OAUTH.md)。
默认 `/-/mcp` 提供公开工具,`msg_connect` 返回本地密钥使用说明,
不再打开第三方授权页面。私有操作使用 CLI 或 `/-/mcp/raw` 的签名请求。
原来依赖 OAuth 的私有连接器在升级后不再保持连接。
配置、备份与升级要求见[公私钥身份说明](docs/KEY_IDENTITY.md)。

## 部署自己的服务

Expand Down
2 changes: 1 addition & 1 deletion deploy/hosting-role.sql
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ CREATE ROLE msgd_hosting LOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE
SELECT format('GRANT CONNECT ON DATABASE %I TO msgd_hosting', current_database()) \gexec
GRANT USAGE ON SCHEMA public TO msgd_hosting;
GRANT SELECT ON public.schema_version, public.resources, public.revisions,
public.identities, public.memberships, public.credentials, public.certificates, public.oauth_states,
public.identities, public.memberships, public.credentials, public.certificates, public.credential_states,
public.settings, public.share_grants, public.share_grants_v2,
public.dm_conversations, public.system_sources, public.resource_path_aliases TO msgd_hosting;
ALTER ROLE msgd_hosting SET default_transaction_read_only = on;
Expand Down
51 changes: 0 additions & 51 deletions deploy/login.example.toml

This file was deleted.

Loading
Loading