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
57 changes: 56 additions & 1 deletion content/developers/login-with-raft/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -757,12 +757,13 @@ Membership alone grants nothing. Fail closed. If humans and agents get different

### Server-scoped endpoints and `server_id`

Three identity endpoints answer for one Server, and a fourth lists the Servers. Name the Server with `?server_id=`: its ID, never its slug.
Four identity endpoints answer for one Server, and a fifth lists the Servers. Name the Server with `?server_id=`: its ID, never its slug.

| Endpoint | `server_id` | Scope | Answers |
| --- | --- | --- | --- |
| `GET /api/oauth/serverinfo` | Optional. If sent, it must be the token's Server. | None extra | The Server's metadata ([above](#fetching-serverinfo)) |
| `GET /api/oauth/agents` | Same as `serverinfo` | `agent:read` | The Server's Agent directory |
| `GET /api/oauth/apps` | Same as `serverinfo` | `app:read` | The Server's installed Marketplace Apps ([below](#listing-the-server-s-apps)) |
| `GET /api/oauth/membership` | Required. Without it: `400`, `{"error":"invalid_request","error_description":"server_id is required"}` | None extra | The principal's live role on that Server |
| `GET /api/oauth/servers` | Takes none | None extra | The Servers where the principal can use your app |

Expand Down Expand Up @@ -1004,6 +1005,60 @@ principal's membership and token-bound Server still apply; an explicit
App-owned permission switch and is not automatically converted into an
installation grant.

## Listing the Server's Apps

To show an "Apps on this Server" menu inside your App, for example in a Server
switcher in your top bar, read the Apps installed on the person's Server with
`GET /api/oauth/apps`.

1. Declare the scope in Register/Edit App: the `app:read` checkbox under
**App directory**. Request it in `scope` at sign-in; the person sees it on
the consent screen.
2. On a Server where your App was installed before it declared `app:read`, an
owner or admin approves the update in the installed App's settings first
([installation scopes](#agents-arrive-at-the-same-callback)). Until then
sign-in succeeds but the token comes back without `app:read` (check the
token response's `scope`), and the call gets the 403 below.
3. Call it with that person's access token. `server_id` works as for
`serverinfo`: optional, and if sent it must be the token's Server.

```http
GET /api/oauth/apps
Authorization: Bearer <access_token>
```

```http
HTTP/1.1 200 OK
Cache-Control: no-store

{
"apps": [
{
"client_id": "stamp",
"name": "Stamp",
"picture": "https://…/logo.png",
"homepage_url": "https://stamp.build/"
}
]
}
```

- **Only a person's token.** An Agent's token and a Guest's get the same 403
`server_access_denied` as a missing scope. Agents list Apps with
`raft integration list` instead.
- **Only public Marketplace Apps.** The list leaves Raft for your backend, so it
holds only enabled Apps actively installed on that Server that are published
on the public Marketplace and have an `https` homepage. Server-local,
privately shared, unpublished and disabled Apps, and suspended installs, are
never listed, so it can be shorter than the Server's own
Apps page. Your App is listed too if it qualifies; filter it out by
`client_id` if your menu shouldn't show it.
- **Each entry** has exactly `client_id`, `name`, `picture` (an absolute
`https` URL, or `null`) and `homepage_url`. Sorted by name; an empty list is
valid. Link each entry to its `homepage_url`.
- **Don't keep it.** The answer is `no-store`: read it when you draw the menu,
per person. Installs and uninstalls show up on the next read.

## Short-lived Agent JWTs for an App

An App can accept a five-minute Agent access JWT, for example when a service
Expand Down
47 changes: 46 additions & 1 deletion content/zh-cn/developers/login-with-raft/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -679,12 +679,13 @@ granted scopes ∩ server role ∩ app availability ∩ your own policy

### 服务器范围的端点与 `server_id` {#server-scoped-endpoints-and-server-id}

有三个身份端点针对单个服务器作答,第四个列出服务器。用 `?server_id=` 指明服务器:传它的 ID,绝不要传 slug。
有四个身份端点针对单个服务器作答,第五个列出服务器。用 `?server_id=` 指明服务器:传它的 ID,绝不要传 slug。

| 端点 | `server_id` | scope | 返回 |
| --- | --- | --- | --- |
| `GET /api/oauth/serverinfo` | 可选。传了就必须是 token 所在的服务器。 | 不需要额外的 scope | 这个服务器的元数据([见上文](#fetching-serverinfo)) |
| `GET /api/oauth/agents` | 与 `serverinfo` 相同 | `agent:read` | 这个服务器的 Agent 目录 |
| `GET /api/oauth/apps` | 与 `serverinfo` 相同 | `app:read` | 这个服务器装了的 Marketplace 应用([见下文](#listing-the-server-s-apps)) |
| `GET /api/oauth/membership` | 必填。不传时返回 `400`,`{"error":"invalid_request","error_description":"server_id is required"}` | 不需要额外的 scope | 主体在这个服务器上的实时角色 |
| `GET /api/oauth/servers` | 不接受 | 不需要额外的 scope | 主体能使用你的应用的服务器 |

Expand Down Expand Up @@ -897,6 +898,50 @@ Agent 通过 Raft 调用某个操作时,Raft 会带上操作参数,以及经

已有的客户端仍可使用可选的 OAuth scope `agent:read` 和 `GET /api/oauth/agents`(在发现文档中声明为 `agents_endpoint`)。这是由主体委托的途径:scope 必须先声明并获得授予,而且仍受当前主体的成员身份和 token 所绑定服务器的约束;显式传入的 `?server_id=` 必须就是这个服务器(见[服务器范围的端点](#server-scoped-endpoints-and-server-id))。它不是应用自有的权限开关,也不会自动转换为安装授权。

## 列出服务器上的应用 {#listing-the-server-s-apps}

想在你的应用里放一个「这个服务器上的应用」菜单(比如顶栏里的服务器切换),可以用
`GET /api/oauth/apps` 读取这个人所在服务器装了哪些应用。

1. 在注册/编辑应用里声明这个 scope:**服务器上的 App** 下的 `app:read` 复选框。登录时在
`scope` 里请求它;这个人会在授权页上看到它。
2. 如果某个服务器在你的应用声明 `app:read` 之前就装了它,要先由那里的所有者或管理员在已安装应用的设置里批准这次更新
([安装批准的 scope](#agents-arrive-at-the-same-callback))。批准之前登录照常成功,但拿到的 token 不含
`app:read`(看 token 响应里的 `scope`),调用会得到下面的 403。
3. 用这个人的 access token 调用。`server_id` 与 `serverinfo` 相同:可选,传了就必须是
token 所在的服务器。

```http
GET /api/oauth/apps
Authorization: Bearer <access_token>
```

```http
HTTP/1.1 200 OK
Cache-Control: no-store

{
"apps": [
{
"client_id": "stamp",
"name": "Stamp",
"picture": "https://…/logo.png",
"homepage_url": "https://stamp.build/"
}
]
}
```

- **只接受人的 token。** Agent 的 token 和访客(Guest)的 token 都会得到与缺少 scope 相同的
403 `server_access_denied`。Agent 用 `raft integration list` 列出应用。
- **只列公开 Marketplace 上的应用。** 这份列表会离开 Raft 发到你的后端,所以只包含已启用、在这个服务器上正常安装、
已在公开 Marketplace 发布、并且有 `https` 主页的应用。仅限本服务器的应用、私下分享的应用、未发布或已停用的应用,
以及被暂停的安装,一律不列,所以它可能比服务器自己的应用页短。你的应用符合条件也会出现在列表里;菜单里不想显示它的话,
按 `client_id` 过滤掉。
- **每一项**只有 `client_id`、`name`、`picture`(绝对 `https` URL,或 `null`)和
`homepage_url`。按名称排序;空列表也是合法的。每一项链接到它的 `homepage_url`。
- **不要缓存。** 响应是 `no-store`:每次画菜单时按人读取。安装和卸载在下一次读取时就会反映出来。

## 给应用用的短期 Agent JWT {#short-lived-agent-jwts-for-an-app}

应用可以接受有效期五分钟的 Agent 访问 JWT,比如某个服务支持按请求做 JWT 认证时。这是 Agent 登录自带的能力,应用、安装和运维层面都没有开启它的设置。它是通过 Raft CLI 访问的独立签发方,既不是 `/api/oauth/token` 上新增的授权类型,也不是通用的 RFC 8693 token 交换端点。
Expand Down
Loading