@eduwork/dsh-oidc 0.2.4 → 0.3.0-dev.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/README.md +20 -132
  2. package/README_EN.md +20 -177
  3. package/docs/EDUWORK-MIGRATION.en.md +3 -25
  4. package/docs/EDUWORK-MIGRATION.md +3 -25
  5. package/docs/account-extensions.en.md +6 -6
  6. package/docs/account-extensions.md +3 -3
  7. package/docs/architecture.en.md +12 -117
  8. package/docs/architecture.md +12 -118
  9. package/docs/compatibility.en.md +6 -40
  10. package/docs/compatibility.md +6 -40
  11. package/docs/decisions/0001-one-plugin-composition-boundary.en.md +2 -2
  12. package/docs/decisions/0001-one-plugin-composition-boundary.md +2 -2
  13. package/docs/desktop-host.en.md +4 -5
  14. package/docs/desktop-host.md +8 -9
  15. package/docs/development.en.md +2 -2
  16. package/docs/development.md +2 -2
  17. package/docs/dsh-integration.en.md +11 -46
  18. package/docs/dsh-integration.md +12 -47
  19. package/docs/ecnu-reference.en.md +4 -61
  20. package/docs/ecnu-reference.md +4 -61
  21. package/docs/enterprise-profile.en.md +10 -31
  22. package/docs/enterprise-profile.md +11 -32
  23. package/docs/gateway-auth/README.md +168 -0
  24. package/docs/gateway-auth/README_EN.md +70 -0
  25. package/docs/gateway-auth/experimental-oidc-llm.en.md +53 -0
  26. package/docs/gateway-auth/experimental-oidc-llm.md +53 -0
  27. package/docs/gateway-auth/litellm-setup.en.md +114 -0
  28. package/docs/gateway-auth/litellm-setup.md +114 -0
  29. package/docs/gateway-auth/oidc-llm-draft.en.md +141 -0
  30. package/docs/gateway-auth/oidc-llm-draft.md +141 -0
  31. package/docs/getting-started.en.md +17 -122
  32. package/docs/getting-started.md +16 -225
  33. package/docs/key-binding-protocol.en.md +10 -220
  34. package/docs/key-binding-protocol.md +10 -220
  35. package/docs/oidc-interoperability.en.md +1 -1
  36. package/docs/oidc-interoperability.md +1 -1
  37. package/docs/open-integration.en.md +5 -67
  38. package/docs/open-integration.md +5 -67
  39. package/docs/public-resource-protocol.en.md +8 -44
  40. package/docs/public-resource-protocol.md +8 -43
  41. package/docs/security-model.en.md +10 -132
  42. package/docs/security-model.md +10 -132
  43. package/docs/server-integration-contract.en.md +12 -813
  44. package/docs/server-integration-contract.md +12 -825
  45. package/examples/ecnu.enterprise-profile.example.json +14 -19
  46. package/examples/enterprise-profile.example.json +14 -19
  47. package/examples/litellm.enterprise-profile.example.json +9 -0
  48. package/examples/oidc-llm.enterprise-profile.example.json +12 -0
  49. package/examples/resources-discovery.example.json +5 -8
  50. package/lib/callback-page.js +5 -5
  51. package/lib/client.js +31 -48
  52. package/lib/desktop-oidc.js +7 -11
  53. package/lib/gateway-backend.js +443 -0
  54. package/lib/gateway-protocol.js +6 -0
  55. package/lib/index.js +14 -15
  56. package/lib/litellm-protocol.js +117 -0
  57. package/lib/model-resource-transport.js +19 -0
  58. package/lib/oidc-llm-protocol.js +88 -0
  59. package/lib/oidc.js +37 -323
  60. package/lib/profile.js +34 -40
  61. package/lib/provider/authorization-scope.js +46 -0
  62. package/lib/provider/index.js +11 -2
  63. package/lib/typert-schemas.js +1 -1
  64. package/package.json +2 -2
  65. package/protocol/openapi.yaml +33 -240
  66. package/protocol/resources.openapi.yaml +8 -9
  67. package/schema/enterprise-profile.v1alpha1.schema.json +509 -107
@@ -1,227 +1,17 @@
1
- # Worker User Center Key Binding Protocol v1
1
+ # 旧 Key Binding 接入迁移
2
2
 
3
3
  **简体中文** | [English](key-binding-protocol.en.md)
4
4
 
5
- ## 1. 状态与术语
5
+ 当前客户端源码已移除 Key Binding 模型凭据流程:不再调用 /bootstrap 或 /runtime-credential 的 provision、resolve、renew,也不再接受 keyBinding 配置或 backend: native 旧账户桥。
6
6
 
7
- 本文定义 `worker-user-center-v1`:`dsh-oidc` 用它把经 OIDC 认证的 subject 与模型运行时 API Key 绑定。这是企业管理协议,不属于 OIDC 标准。
7
+ 服务端可以继续实现旧接口,供已发布的老客户端使用。新客户端的机构模型接入统一使用 Access Token;兼容责任不要求新客户端保留旧取 Key 分支。
8
8
 
9
- 它是[服务端接口规范](server-integration-contract.md)中托管模型能力档的组成部分,需与 OIDC Provider 和模型网关共同实现。纯身份 Profile 不要求 Key Binding。
9
+ ## 迁移步骤
10
10
 
11
- 关键词 **必须(MUST)**、**不得(MUST NOT)**、**必需(REQUIRED)**、**应该(SHOULD)**、**不应该(SHOULD NOT)**、**建议(RECOMMENDED)**、**不建议(NOT RECOMMENDED)**、**可以(MAY)** 和 **可选(OPTIONAL)** 按 RFC 2119 与 RFC 8174 解释。
11
+ 1. 确认服务端已支持 [oidc-llm 实验契约](gateway-auth/experimental-oidc-llm.md),或使用 [LiteLLM native 契约](gateway-auth/README.md)。
12
+ 2. 把旧 oidc + keyBinding + provider.baseURL 配置替换为完整 auth.discoveryUrl;OIDC 模式另外填写显式实验开关、预注册 public client ID 和 identityMode。
13
+ 3. 保留稳定的 Profile/Provider ID 和模型能力元数据,但模型可见性、API 基址来自已验证的发现和目录。
14
+ 4. 重新登录。客户端不猜测旧服务的新发现地址,不把旧模型 Key 当作 Access Token,也不自动回退。旧本地凭据不会被新模型路径读取;不批量删除可能仍由其他配置使用的 Key。
15
+ 5. 仅身份登录可继续使用 oidc 配置,但不得同时配置模型 provider。
12
16
 
13
- [`protocol/openapi.yaml`](../protocol/openapi.yaml) 是配套的机器可读契约。若正文与 OpenAPI 不一致,本文决定安全和生命周期语义,OpenAPI 决定字段拼写和基本结构。任何差异都属于规范缺陷,必须报告。
14
-
15
- ## 2. 设计目标
16
-
17
- 协议区分三类凭据:
18
-
19
- - 机构密码:只由 OIDC Provider 看见;
20
- - OIDC access token:只用于 UserInfo 和 Key Binding 服务;
21
- - 模型运行时 API Key:只用于模型 Provider 路由。
22
-
23
- API Key 是可替换、可撤销的运行凭据,不是用户身份证明。Key Binding 服务端是决定其创建和解析权限的授权权威。
24
-
25
- ## 3. Base URL 与固定资源
26
-
27
- Enterprise Profile 提供一个 HTTPS `keyBinding.baseURL`。其中不得包含 userinfo、query 或 fragment,并且应该包含类似 `/api/worker/v1` 的版本路径。
28
-
29
- 相对于该 base URL,以下路径固定不变:
30
-
31
- | 方法 | 路径 | 用途 |
32
- | --- | --- | --- |
33
- | GET | `/bootstrap` | 读取 Provider、能力、授权资格和凭据状态。 |
34
- | POST | `/runtime-credential/provision` | 状态为 `missing` 时创建或绑定凭据。 |
35
- | POST | `/runtime-credential/resolve` | 返回活动凭据。 |
36
- | POST | `/runtime-credential/renew` | 轮换 `expiring` 或 `expired` 凭据。 |
37
-
38
- Profile 和用户不得覆盖路径、HTTP 方法、字段映射或凭据引用名。
39
-
40
- ## 4. 认证与授权
41
-
42
- 除显式 loopback 开发环境外,每个请求都必须使用 TLS。客户端发送:
43
-
44
- ```http
45
- Authorization: Bearer <OIDC access token>
46
- Accept: application/json
47
- ```
48
-
49
- 服务端至少必须验证:
50
-
51
- - token 签名或 introspection 结果;
52
- - issuer;
53
- - 面向 Key Binding 服务的 audience;
54
- - 过期时间和 not-before;
55
- - 已认证 subject;
56
- - 操作所需 scope;
57
- - 机构成员资格、账号状态和模型授权。
58
-
59
- 建议 scope:
60
-
61
- | 操作 | Scope |
62
- | --- | --- |
63
- | bootstrap | `worker.bootstrap.read` |
64
- | provision | `worker.credential.provision` |
65
- | resolve | `worker.credential.read` |
66
- | renew | `worker.credential.renew` |
67
-
68
- 部署可以使用不同 scope 名称,但这些仍属于 OIDC 授权策略,并列在 Enterprise Profile `oidc.scopes` 中;网络操作本身不变。
69
-
70
- 服务端必须从已验证 access token 派生绑定 subject,不得接受请求 body 中由调用方提供的 subject ID。
71
-
72
- ## 5. Bootstrap
73
-
74
- 请求:
75
-
76
- ```http
77
- GET /api/worker/v1/bootstrap HTTP/1.1
78
- Authorization: Bearer …
79
- Accept: application/json
80
- ```
81
-
82
- 最小成功响应:
83
-
84
- ```json
85
- {
86
- "provider": { "id": "example-ai" },
87
- "capabilities": ["worker.credential.provision"],
88
- "runtime_credential": {
89
- "status": "missing",
90
- "provisioning": { "allowed": true }
91
- }
92
- }
93
- ```
94
-
95
- 返回的 `provider.id` 是必需字段,必须与 Enterprise Profile `provider.id` 完全相等。不一致即视为绑定失败。
96
-
97
- 有效的 `runtime_credential.status`:
98
-
99
- - `missing`:尚未绑定凭据;
100
- - `active`:可以解析活动凭据;
101
- - `expiring`:存在 `api_key_id` 时轮换,否则按服务端策略解析;
102
- - `expired`:存在 `api_key_id` 时轮换,否则按服务端策略解析;
103
- - `suspended`:授权或账号已停用;本地凭据不得继续视为可用;
104
- - `unavailable`:服务当前无法提供凭据。
105
-
106
- `subject` 可以携带仅供管理面显示的信息。客户端不得用它替换 OIDC `sub` 或 `name`。
107
-
108
- 若返回 `protocol_version`,其值必须是 `worker.user-center.v1`、`worker-user-center/v1` 或 `eduwork-resources/v1`(三个别名共享同一组 v1 字段与路径,未知版本拒绝)。该字段在 v1 采用阶段可选;未来 major 协议可以要求显式协商。
109
-
110
- ## 6. Provision
111
-
112
- 用户必须先完成 OIDC 认证。`dsh-oidc` 还要求显式 UI 操作(`allowProvision: true`),因此仅完成 callback 不会静默创建模型凭据。
113
-
114
- ```http
115
- POST /api/worker/v1/runtime-credential/provision HTTP/1.1
116
- Authorization: Bearer …
117
- Content-Type: application/json
118
- Idempotency-Key: <UUID>
119
-
120
- { "provider_id": "example-ai" }
121
- ```
122
-
123
- 服务端必须:
124
-
125
- - 验证该 subject 获准使用 `provider_id`;
126
- - 执行机构凭据创建策略;
127
- - 对相同已认证 subject、Provider 和 Idempotency-Key 保证幂等;
128
- - 在服务端幂等保留窗口内,对重放请求返回相同逻辑结果;
129
- - 同一 key 与不同 payload 重用时返回 `409 Conflict`;
130
- - 绝不记录返回的 API Key。
131
-
132
- ## 7. Resolve
133
-
134
- ```http
135
- POST /api/worker/v1/runtime-credential/resolve HTTP/1.1
136
- Authorization: Bearer …
137
- Content-Type: application/json
138
-
139
- {
140
- "provider_id": "example-ai",
141
- "api_key_id": "optional-known-id"
142
- }
143
- ```
144
-
145
- Resolve 不得创建新的授权资格。它返回已绑定到 subject 的活动凭据,或者返回 `404`/策略错误。服务端可以在保持同一逻辑 `api_key_id` 的情况下轮换不透明秘密材料,但不得改变 Provider 所有权。
146
-
147
- ## 8. Renew
148
-
149
- ```http
150
- POST /api/worker/v1/runtime-credential/renew HTTP/1.1
151
- Authorization: Bearer …
152
- Content-Type: application/json
153
- Idempotency-Key: <UUID>
154
-
155
- {
156
- "provider_id": "example-ai",
157
- "api_key_id": "key-123"
158
- }
159
- ```
160
-
161
- Renew 要求提供 `api_key_id`,必须幂等,并轮换或替换即将过期/已过期凭据。服务端应该在操作安全允许后尽快使旧秘密材料失效,并且必须记录任何重叠有效窗口。
162
-
163
- ## 9. 凭据响应
164
-
165
- 三个 POST 操作成功时都返回:
166
-
167
- ```json
168
- {
169
- "provider_id": "example-ai",
170
- "api_key": "secret-runtime-value",
171
- "api_key_id": "key-123",
172
- "status": "active",
173
- "expires_at": "2026-09-01T00:00:00Z"
174
- }
175
- ```
176
-
177
- `provider_id`、`api_key` 和 `status=active` 是必需字段。Provider 缺失、不匹配或 key 为空时,客户端会拒绝响应。
178
-
179
- 凭据响应必须包含 `Cache-Control: no-store`,并且应该包含 `Pragma: no-cache`。服务端、代理、APM agent 和 WAF 必须脱敏 Authorization header 与 `api_key` 响应字段。不得把秘密写入 URL、错误详情、分析事件或审计日志。
180
-
181
- ## 10. 错误
182
-
183
- 错误应该遵循 RFC 9457,使用 `application/problem+json`,并提供稳定扩展字段 `code`。至少包含:
184
-
185
- - `400`:请求或 Provider ID 格式错误;
186
- - `401`:token 缺失、无效、过期或 audience 错误;
187
- - `403`:scope、成员资格、授权、停用或创建策略拒绝;
188
- - `404`:没有可解析或可更新的凭据;
189
- - `409`:幂等或生命周期冲突;
190
- - `429`:限流,最好包含 `Retry-After`;
191
- - `5xx`:不包含秘密材料的服务端失败。
192
-
193
- 同一逻辑操作重试 provision/renew 时,客户端必须保留相同 Idempotency-Key。`dsh-oidc` 当前只发起一次调用;DSH 模型请求重试属于另一条链路,绝不会重复 Key Binding 操作。
194
-
195
- ## 11. 生命周期与撤销
196
-
197
- 以下情况发生时,Key Binding 服务应该撤销模型凭据:
198
-
199
- - 机构成员资格或授权终止;
200
- - OIDC subject 被停用;
201
- - 凭据被轮换;
202
- - 安全管理员撤销凭据;
203
- - 达到最大生命周期。
204
-
205
- 本地退出会删除缓存模型 Key,但不能单独证明远程凭据已撤销。要求即时远程撤销的部署,应该在未来协议版本增加经过认证的管理操作,而不是复用 OIDC token revocation。
206
-
207
- 模型网关必须独立执行 API Key 状态、Provider scope、过期和配额策略。持有旧 Key 不得无限期绕过当前企业策略。
208
-
209
- ## 12. 隐私与审计
210
-
211
- 服务端应该尽量减少 bootstrap 返回的身份数据。审计记录应该包含事件时间、不透明 subject 引用、Provider ID、操作、结果、策略原因、请求关联 ID 和 `api_key_id`,绝不能包含 API Key 或 OIDC token。
212
-
213
- 数据保留、访问控制、泄露响应和跨境处理由部署方负责。该协议不授予收集更多个人数据的权限。
214
-
215
- ## 13. 符合性检查
216
-
217
- 服务端满足以下条件时符合本规范:
218
-
219
- - 实现全部四个固定资源;
220
- - 使用 OIDC access token 认证请求,绝不使用请求 body 中的 subject 数据;
221
- - 返回完全匹配的 Provider 绑定;
222
- - 执行所需 scope 和机构授权;
223
- - 实现 provision/renew 幂等;
224
- - 凭据响应使用 no-store;
225
- - 不记录秘密;
226
- - 提供稳定生命周期状态和问题代码;
227
- - 通过仓库 OpenAPI 契约测试和机构特有授权测试。
17
+ 这次删除属于尚未发布源码的破坏性配置变更;旧协议细节以历史版本为准。个人 API Key 入口保持可用。
@@ -2,7 +2,7 @@
2
2
 
3
3
  [简体中文](oidc-interoperability.md) | **English**
4
4
 
5
- OIDC is the identity tier of the [server API specification](server-integration-contract.en.md). An identity-only Profile may implement this tier alone. Managed enterprise keys and automatic model setup additionally require Key Binding and the model gateway.
5
+ OIDC is the identity tier of the [server API specification](server-integration-contract.en.md). An identity-only Profile may implement this tier alone. Model access uses an explicitly advertised token gateway contract; see [gateway integration](gateway-auth/README_EN.md).
6
6
 
7
7
  ## Standards
8
8
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  **简体中文** | [English](oidc-interoperability.en.md)
4
4
 
5
- OIDC 是[服务端接口规范](server-integration-contract.md)的身份能力档,纯身份 Profile 可只实现本文件。只有需要托管模型 Key 和自动配置企业模型时,才必须同时提供 Key Binding 和模型网关。
5
+ OIDC 是[服务端接口规范](server-integration-contract.md)的身份能力档,纯身份 Profile 可只实现本文件。模型接入使用独立声明的 Token 网关契约,见[网关接入](gateway-auth/README.md)。
6
6
 
7
7
  ## 标准依据
8
8
 
@@ -1,73 +1,11 @@
1
- # Open Identity and Model Integration Initiative
1
+ # Open identity and model integration
2
2
 
3
3
  [简体中文](open-integration.md) | **English**
4
4
 
5
- **Make institutional accounts and model services reusable across AI clients.**
5
+ A user can authorize a general-purpose client in the browser and use their model permissions. OIDC verifies identity; the model service explicitly grants Access Token model access. Clients reuse discovery, PKCE, refresh and the model Provider.
6
6
 
7
- Schools and businesses already have identity systems and are building model services. Users want to sign in with a familiar account and start working in their chosen AI client. Our aim is for one server implementation of an open contract to serve multiple compatible clients, and for a client to connect another organization primarily through configuration.
7
+ Current implementations support [LiteLLM native OAuth](gateway-auth/README_EN.md) and the [experimental oidc-llm draft](gateway-auth/experimental-oidc-llm.en.md). An implementation does not make the draft a finalized standard. Personal models and identity-only sign-in remain independent.
8
8
 
9
- EduWork puts this into practice through `dsh-oidc`. We invite identity platforms, model gateways, client developers, and plugin authors to improve the contract together.
9
+ New clients no longer consume Key Binding. Servers may support token model access alongside old client endpoints without retaining old logic in new clients. Institution quota, team policy, web pages and operations remain extensions using bounded Host transport.
10
10
 
11
- > Status: this is a community initiative. The accompanying RFC EW-IDENTITY-1 documents implemented interfaces, with future protocol changes open for discussion. It is not a standard published by DSH, the OpenID Foundation, or the IETF, and does not imply that other clients are already compatible.
12
-
13
- ## The experience we want to enable
14
-
15
- A user selects an organization, signs in through the system browser, grants authorization, and confirms credential creation when required. The client then loads the organization's models so the user can start a task. Personal API keys and other models remain available.
16
-
17
- ```mermaid
18
- flowchart LR
19
- A[Choose an organization] --> B[Browser sign-in and authorization]
20
- B --> C[Confirm when needed and obtain model credentials]
21
- C --> D[Load available models]
22
- D --> E[Start working]
23
- ```
24
-
25
- This is the intended managed-model experience. An organization that only needs identity can start with OIDC alone and let users configure their models, without first building a model-credential service.
26
-
27
- | Participant | Work we hope to reduce together |
28
- | --- | --- |
29
- | Users | Repeatedly copying keys, finding endpoint addresses, and entering model parameters. |
30
- | Schools and businesses | Reimplementing identity and model integration for each client. |
31
- | Client developers | Maintaining a separate sign-in, credential, and model adapter for every organization. |
32
- | Plugin authors | Implementing another sign-in flow or storing another copy of a user's credentials in a tool plugin. |
33
-
34
- ## What we propose to agree on
35
-
36
- 1. **Use existing identity standards.** Use OpenID Connect with PKCE for local public clients, and derive identity from verified OIDC results. Resource services authorize model access without replacing the identity source.
37
- 2. **Define an open model-access contract.** Specify requests and responses for credential state, provisioning, resolution, renewal, and model catalogs. OIDC handles identity; model credentials and catalogs require separate resource APIs. Successful sign-in alone does not establish model integration.
38
- 3. **Keep institution configuration as data.** Declare branding, trusted endpoints, and model policy in local configuration. Configuration cannot deliver scripts, install tools, or replace executable modules. Add behavior through explicitly installed plugins.
39
- 4. **Preserve user choice and institution boundaries.** Institutional and personal models can coexist. Public integration does not require a particular school, desktop shell, quota system, or activity heartbeat. Institution-specific capabilities remain optional extensions.
40
- 5. **Make compatibility verifiable.** Document fields, errors, versions, and migrations in specifications, OpenAPI, examples, and tests. Follow the [compatibility policy](compatibility.en.md) when changing the protocol, so clients do not have to guess.
41
-
42
- ## Build on the existing implementation
43
-
44
- The protocol and client implementation are available for server integration and client interoperability work.
45
-
46
- | Part | Current scope | Start here |
47
- | --- | --- | --- |
48
- | Identity | OIDC Discovery, Authorization Code + PKCE, Token, JWKS, and UserInfo, including identity-only mode. | [OIDC interoperability requirements](oidc-interoperability.en.md) |
49
- | Managed credentials | Bootstrap and the provision, resolve, and renew lifecycle endpoints. | [Complete server interfaces and requests](server-integration-contract.en.md) · [Key Binding OpenAPI](../protocol/openapi.yaml) |
50
- | Model catalog | A static catalog in trusted configuration, or explicitly enabled `/models` discovery. | [Client modes and model discovery](public-resource-protocol.en.md) |
51
- | DSH client | The independent npm package `@eduwork/dsh-oidc`, used by EduWork and available to other compatible DSH hosts. | [Module guide](../README_EN.md) · [Desktop host integration](desktop-host.en.md) |
52
- | Institution extensions | Configuration, skills, and plugins that reuse public integration capabilities. | [EduWork@ECNU example](https://github.com/ecnu/EduWork-ECNU) |
53
-
54
- A server must implement the interfaces required by its selected mode. This repository does not include a deployable OIDC or Key Binding server. Current clients are single-user local applications; local Web is for validation and does not provide shared multi-user sign-in sessions.
55
-
56
- Remote organization-profile discovery and remote model-key revocation remain optional proposals in the RFC. Quota and activity heartbeats remain institution extensions. Proposals or capability declarations do not activate unimplemented features. The model gateway uses the documented OpenAI Chat Completions compatible contract; other model and media APIs require separate validation against their own contracts.
57
-
58
- Other clients can implement these network interfaces without adopting EduWork's UI or desktop shell. Interoperability depends on the declared protocol versions and actual integration results.
59
-
60
- ## How to participate
61
-
62
- - **Identity and model platform developers:** start with the [server specification](server-integration-contract.en.md) and [integration guide](getting-started.en.md). Contribute sanitized examples and explain constraints that are difficult for existing platforms to meet.
63
- - **Client developers:** integrate `dsh-oidc` or implement the network protocol independently. Verify sign-in, credential lifecycle, model catalogs, and error handling; share interoperability results with explicit version information.
64
- - **Plugin authors:** connect institution capabilities through the [account extension interfaces](account-extensions.en.md), reusing the host's authorized transport and account state where possible.
65
- - **Specification contributors:** describe use cases and compatibility issues in [EduWork Issues](https://github.com/ecnu/EduWork/issues). Discuss interface changes first, then update the specification, machine-readable contract, examples, and necessary tests following the [contribution guide](../CONTRIBUTING.en.md).
66
-
67
- Implementations from different organizations and clients are welcome. Use placeholder configuration and synthetic data in examples; report authentication vulnerabilities and credential issues through the [security reporting process](../SECURITY.en.md).
68
-
69
- ## Relationship to the DSH plugin ecosystem
70
-
71
- [DSH Desktop's plugin ecosystem initiative](https://github.com/anywhere-labs/dsh-desktop/blob/master/docs/plugin-ecosystem.en.md) promotes plugin composition and collaboration. We share that direction and aim to contribute implementable, discussable public interfaces for identity and model access. The initiatives are independent; this reference does not imply that DSH Desktop has adopted this protocol.
72
-
73
- The next result we hope to establish together is that one institutional service can connect to more clients through a clear protocol and a small amount of configuration, and continue working across upgrades.
11
+ Start with the [server contract](server-integration-contract.en.md), [profiles](enterprise-profile.en.md) and [development guide](development.en.md).
@@ -1,73 +1,11 @@
1
- # 开放身份与模型接入倡议
1
+ # 开放身份与模型接入
2
2
 
3
3
  **简体中文** | [English](open-integration.en.md)
4
4
 
5
- **让机构的账号与模型服务,被更多 AI 客户端复用。**
5
+ 机构用户可以通过一次浏览器授权,在通用客户端使用自己的模型访问权限。OIDC 负责身份验证;模型服务明确授予 Access Token 模型权限,客户端复用发现、PKCE、刷新和模型 Provider。
6
6
 
7
- 学校和企业已经有自己的账号体系,也在建设模型服务。用户希望用熟悉的账号登录,在自己选择的 AI 客户端里开始工作。我们希望服务端实现一套公开接口后,能够服务多个遵循同一约定的客户端;客户端新增一个机构时,也能主要通过配置完成接入。
7
+ 当前实现支持 [LiteLLM native OAuth](gateway-auth/README.md) 与 [oidc-llm 实验草案](gateway-auth/experimental-oidc-llm.md)。草案仍需评审,已实现不等于标准定稿。个人模型和纯身份登录保留独立入口。
8
8
 
9
- EduWork 从 `dsh-oidc` 开始实践这件事,并邀请身份平台、模型网关、客户端和插件作者一起完善这套约定。
9
+ 新客户端不再消费 Key Binding。服务端可同时支持新 Token 模型接入和老客户端接口;新客户端无需保留旧实现。机构配额、团队策略、网页和运维功能由机构独立扩展,公共包提供受控 Host 传输。
10
10
 
11
- > 状态:这是一份面向社区的倡议。配套的 RFC EW-IDENTITY-1 描述已有实现的接口,后续协议演进开放讨论;它不是 DSH 官方、OpenID Foundation 或 IETF 发布的标准,也不代表其他客户端已经兼容。
12
-
13
- ## 用户应当得到什么
14
-
15
- 用户选择机构,在系统浏览器完成登录,授权并在必要时确认创建模型凭据。客户端随后加载机构提供的模型,用户即可开始任务。个人 API Key 和其他模型仍然可以使用。
16
-
17
- ```mermaid
18
- flowchart LR
19
- A[选择机构] --> B[浏览器登录与授权]
20
- B --> C[按需确认并领取模型凭据]
21
- C --> D[加载可用模型]
22
- D --> E[开始工作]
23
- ```
24
-
25
- 这是托管模型模式的目标体验。只需登录身份的机构可以从纯 OIDC 模式开始,用户自行配置模型;不必先建设模型凭据服务。
26
-
27
- | 参与者 | 我们希望共同减少的工作 |
28
- | --- | --- |
29
- | 使用者 | 反复复制 Key、查找接口地址和填写模型参数。 |
30
- | 学校与企业 | 为每个客户端重复编写身份和模型接入逻辑。 |
31
- | 客户端作者 | 为每个机构维护一套专有登录、凭据和模型适配。 |
32
- | 插件作者 | 在工具插件里再次实现登录或另存一份用户凭据。 |
33
-
34
- ## 共同约定什么
35
-
36
- 1. **身份遵循已有标准。** 使用 OpenID Connect 与适合本机公共客户端的 PKCE 登录流程,用户身份以经过验证的 OIDC 结果为准。资源服务负责模型授权,不替换身份来源。
37
- 2. **模型接入有公开契约。** 明确凭据状态、申请、读取、轮换和模型目录的请求与响应。OIDC 负责身份;模型凭据与目录使用另外定义的资源接口,不能把完成登录等同于完成模型接入。
38
- 3. **机构配置保持为数据。** 品牌、受信任端点和模型策略由本地配置声明;配置不能下发脚本、安装工具或替换执行模块。需要新增行为时,通过显式安装的插件接入。
39
- 4. **保留用户选择和机构边界。** 机构模型与个人模型可以共存。公共接入不要求某所学校、某个桌面壳、配额系统或活跃心跳;机构专属能力按需扩展。
40
- 5. **兼容性可以核验。** 字段、错误、版本和迁移方式写入规范、OpenAPI、示例与测试。协议变化遵循[兼容性策略](compatibility.md),不让客户端靠猜测完成接入。
41
-
42
- ## 从现有实现开始共建
43
-
44
- 协议和客户端实现随源码提供,可以据此开展服务端接入及客户端互操作验证。
45
-
46
- | 部分 | 当前范围 | 阅读入口 |
47
- | --- | --- | --- |
48
- | 身份接入 | OIDC Discovery、Authorization Code + PKCE、Token、JWKS、UserInfo;支持纯身份模式。 | [OIDC 兼容要求](oidc-interoperability.md) |
49
- | 托管凭据 | Bootstrap,以及 provision、resolve、renew 生命周期接口。 | [服务端完整接口与请求示例](server-integration-contract.md) · [Key Binding OpenAPI](../protocol/openapi.yaml) |
50
- | 模型目录 | 可信配置中的静态目录,或显式启用的 `/models` 自动发现。 | [客户端模式与模型发现](public-resource-protocol.md) |
51
- | DSH 客户端 | 独立 npm 包 `@eduwork/dsh-oidc`,由 EduWork 使用,也供其他兼容 DSH 宿主集成。 | [模块说明](../README.md) · [桌面宿主接入](desktop-host.md) |
52
- | 机构扩展 | 配置、技能和插件组合,复用公共接入能力。 | [EduWork@ECNU 示例](https://github.com/ecnu/EduWork-ECNU) |
53
-
54
- 服务端需要按所选模式提供相应接口;本仓库不包含可直接部署的 OIDC 或 Key Binding 服务端。现有客户端都是单机应用,本机 Web 用于验证,不提供多人共享的登录会话服务。
55
-
56
- 远程机构配置发现、远端模型 Key 注销等内容仍在 RFC 的可选扩展提案中;配额和活跃心跳继续由机构扩展处理。文档中的提案和能力声明不会自动启用未实现的功能。模型网关采用本文档规定的 OpenAI Chat Completions 兼容接口,其他模型及媒体接口须按各自契约另行核验。
57
-
58
- 其他客户端可以独立实现这些网络接口,不必采用 EduWork 的界面或桌面壳。能否互通,以双方声明的协议版本和实际联调结果为准。
59
-
60
- ## 你可以从哪里参与
61
-
62
- - **身份或模型平台开发者**:从[服务端接口规范](server-integration-contract.md)和[接入指南](getting-started.md)开始,提供经过脱敏的接入示例,反馈现有平台难以满足的约束。
63
- - **客户端作者**:尝试复用 `dsh-oidc`,或独立实现网络协议;验证登录、凭据生命周期、模型目录及错误处理,分享注明版本的互操作结果。
64
- - **插件作者**:通过[账户扩展接口](account-extensions.md)接入机构能力,优先复用宿主授权传输与账户状态。
65
- - **规范贡献者**:在 [EduWork Issues](https://github.com/ecnu/EduWork/issues) 描述场景与兼容性问题;修改接口前先讨论设计,并按[贡献指南](../CONTRIBUTING.md)同步规范、机器契约、示例和必要测试。
66
-
67
- 我们欢迎不同机构、不同客户端的实现参与。示例请使用占位配置和合成数据;认证漏洞与凭据问题通过[安全报告入口](../SECURITY.md)反馈。
68
-
69
- ## 与 DSH 插件生态的关系
70
-
71
- [DSH Desktop 的插件生态倡议](https://github.com/anywhere-labs/dsh-desktop/blob/master/docs/plugin-ecosystem.md)推动插件之间的组合与协作。我们认同这个方向,希望在身份与模型接入这一环节提供可实现、可讨论的公共接口。这两份倡议各自独立;引用并不表示对方已经采纳本协议。
72
-
73
- 下一步希望共同验证的是:同一个机构服务能否通过清晰的协议和少量配置,接入更多客户端,并在升级后继续工作。
11
+ 参与接入请先阅读[服务端契约](server-integration-contract.md)、[配置](enterprise-profile.md)与[开发指南](development.md)。
@@ -1,51 +1,15 @@
1
- # EduWork public identity and resource protocol v1
1
+ # Token-authorized model resources
2
2
 
3
3
  [简体中文](public-resource-protocol.md) | **English**
4
4
 
5
- The public `@eduwork/dsh-oidc` package owns identity login, managed model keys and model configuration. Quota and heartbeat are institution-only extensions; the public package neither requests nor renders quota. Remote speech, institution activity heartbeats and institution-specific tools belong in separate plugins. Each deployment is a local single-user client; the browser connects to the local Runtime.
5
+ The current source uses authorized Access Tokens for organization models. Legacy Key Binding management and model-key flows are removed; see [migration](key-binding-protocol.en.md).
6
6
 
7
- ## Modes and configuration
8
-
9
- Identity-only profiles omit both `keyBinding` and `provider`; successful OIDC login completes identity integration. Users configure personal API keys through ordinary DSH model settings. Organization logout leaves those personal credentials alone. See the [identity-only example](../examples/identity-only.example.json).
10
-
11
- Full integration includes both fields. `keyBinding.type` defaults to `worker-user-center-v1`, while `eduwork-resources-v1` explicitly names the public resource contract. Both use the existing deployed wire paths; current institutions do not need new endpoint URLs. See the [discovery example](../examples/resources-discovery.example.json).
12
-
13
- Both modes permit other models and personal API keys. Optional `brand` only controls presentation; an empty brand leaves the host product name unchanged.
14
-
15
- ## Endpoints and credentials
16
-
17
- | Capability | Endpoint | Authentication |
7
+ | Operation | Endpoint source | Credential |
18
8
  | --- | --- | --- |
19
- | Identity | OIDC Discovery, Authorization Code + PKCE S256, Token, JWKS, UserInfo | OIDC |
20
- | Credential state | `GET {keyBinding.baseURL}/bootstrap` | OIDC access token |
21
- | Provision, resolve, renew | `POST {keyBinding.baseURL}/runtime-credential/{provision,resolve,renew}` | OIDC access token |
22
- | Models | `GET {provider.baseURL}/models` | Managed model API key |
23
- | Inference | `POST {provider.baseURL}/chat/completions` | Managed model API key |
24
-
25
- The [Key Binding OpenAPI](../protocol/openapi.yaml) retains existing lifecycle fields and idempotency requirements. The [resource OpenAPI](../protocol/resources.openapi.yaml) defines model discovery. Optional bootstrap `protocol_version` accepts `worker.user-center.v1`, `worker-user-center/v1` or `eduwork-resources/v1`; unknown versions fail closed. Bootstrap never replaces verified OIDC identity, trusted endpoint configuration or executable components. Resource HTTP requests do not follow redirects.
26
-
27
- ## Model discovery
28
-
29
- `provider.modelSource` defaults to `profile`, preserving reviewed distribution metadata. With `discovery`, `/models` is read after managed key resolution; initial `models` may be omitted and no fake route is registered before discovery.
30
-
31
- The response is `{"data":[{"id":"model-a"}]}` with up to 128 unique model IDs. IDs already declared in the trusted Profile retain their capabilities. New IDs are conservatively text-only with reasoning disabled; model names are not capability evidence. Arbitrary URLs, scripts and adapter configuration in remote responses are ignored.
32
-
33
- Empty or invalid discovery preserves the last usable catalog and returns `models_unavailable`. Successful discovery replaces the provider snapshot for new calls; prepared calls retain their earlier snapshot. After restart the first signed-in status read rediscovers models. Personal provider routes are unaffected.
34
-
35
- ## Host integration
36
-
37
- The plugin is `@eduwork/dsh-oidc`, with bundle layer ID `enterprise-oidc`. Use `backend: web` and `uiMode: standard` for the public interface; `external` keeps public RPC while allowing a product-owned UI. `allowEmptyProfiles: true` supports a public client using only personal keys.
38
-
39
- `EDUWORK_OIDC_PROFILE` names a single profile, an array, or a `{ "profiles": [...] }` file. When absent, `DSH_OIDC_ENTERPRISE_PROFILE` remains a compatible fallback. Explicit `profilePathEnv` names remain supported.
40
-
41
- Existing `oidcAccounts.configuration/status/begin/reconcile/logout/management` RPCs remain available. New `resources(profileID)` returns `{profileID, modelSource, models, issues}` without secrets. `reconcile` automatically refreshes model metadata. The legacy native backend does not call its former quota method; new `backend: desktop` shares the Web OIDC implementation but uses a temporary loopback callback without requiring a persistent WebServer.
42
-
43
- Institution plugins may call Host-only `ctx.oidcAccounts.authorizedFetch(profileID, endpoint, init)` to reuse the current OIDC access token, refresh and one 401 retry. It returns a regular `Response`, has no Remote marker, and never exposes tokens to the browser. Allowed origins default to the configured issuer and Key Binding origins. Additional exact HTTPS origins require trusted host `authorizedOrigins` configuration and cannot be set by browser RPC. Concurrent requests share one rotating refresh operation. This is an authenticated transport seam, not a heartbeat or speech business protocol.
44
-
45
- Host event `oidc/accounts-changed` carries `{profileID, state}`. Both `authenticated` and `connected` mean identity is signed in; identity-only `connected` does not require a model key. `signed_out` means signed out. Authorized requests without a usable identity throw `oidc_login_required`; forbidden origins throw `oidc_authorized_origin_denied`. A second HTTP 401 remains a Response for the caller to handle. Explicit sign-out should not automatically produce an expiry warning.
46
-
47
- Changed issuer, client ID or resource endpoints prevent stale managed keys from reaching a different deployment. Existing Web identity records can retain identity while reacquiring the managed model key. Personal API keys remain unaffected by organization logout or resource-binding changes.
48
-
9
+ | GET /models | Validated gateway API base | Current Access Token |
10
+ | JSON/SSE inference | Same API base | Current Access Token |
11
+ | Optional institution quota GET | Extension-declared relative path | Current Access Token through shared Host transport |
49
12
 
13
+ Catalog data[].id determines model visibility. Reviewed local metadata can describe context, modalities and reasoning but cannot expand server authorization. Logout or reauthorization cancels in-flight calls and prevents prepared old calls from borrowing a new account's credentials. Refresh within the same authorization can continue normally.
50
14
 
51
- Institution account extensions use the [Host transport and account-menu slot contract](account-extensions.en.md). A configured capability string does not activate an extension; install and configure the institution plugin explicitly.
15
+ Public Remote returns only model-resource projections, never Tokens, quota or management APIs. Institutions own quota semantics and scope; see [account extensions](account-extensions.en.md). The [catalog OpenAPI](../protocol/resources.openapi.yaml) complements the [gateway contract](gateway-auth/README_EN.md).
@@ -1,50 +1,15 @@
1
- # EduWork 公共身份与资源协议 v1
1
+ # Token 模型资源接入
2
2
 
3
3
  **简体中文** | [English](public-resource-protocol.en.md)
4
4
 
5
- 本规范属于通用 `@eduwork/dsh-oidc`。身份登录、自动获得模型 Key 和自动配置模型由本包实现;配额由独立机构扩展实现,公版既不请求也不展示配额;远端语音、机构活跃心跳和校内服务由独立插件实现。所有客户端均为单机,Web 只是本机 Runtime 的界面。
5
+ 当前源码只通过获准 Access Token 接入机构模型。旧 Key Binding 的管理和模型 Key 流程已移除,详见[迁移说明](key-binding-protocol.md)。
6
6
 
7
- ## 接入模式
8
-
9
- - 纯身份接入:只配置 `oidc`,省略 `keyBinding` 与 `provider`。登录成功即完成身份接入。用户继续在 DSH 原生模型设置添加自己的 API Key,退出机构身份不会删除个人凭据。见 [示例](../examples/identity-only.example.json)。
10
- - 完整资源接入:同时配置 `keyBinding` 与 `provider`。`keyBinding.type` 默认为 `worker-user-center-v1`;也可显式声明 `eduwork-resources-v1`。两者复用同一组已部署的固定路径,不要求现有机构改造端点。见 [自动目录示例](../examples/resources-discovery.example.json)。
11
-
12
- 这两个模式都允许其他模型与个人 API Key,不能以组织登录覆盖原生模型配置。可选 `brand` 只负责展示,空品牌保持宿主产品名称。
13
-
14
- ## 路径与认证
15
-
16
- | 能力 | 路径 | 凭据 |
7
+ | 操作 | 地址来源 | 使用凭据 |
17
8
  | --- | --- | --- |
18
- | 身份 | OIDC Discovery、Authorization Code + PKCE S256、Token、JWKS、UserInfo | OIDC 标准 |
19
- | 凭据状态 | `GET {keyBinding.baseURL}/bootstrap` | OIDC Access Token |
20
- | 申请、读取、续期 Key | `POST {keyBinding.baseURL}/runtime-credential/{provision,resolve,renew}` | OIDC Access Token |
21
- | 模型目录 | `GET {provider.baseURL}/models` | 获得的模型 API Key |
22
- | 模型调用 | `POST {provider.baseURL}/chat/completions` | 获得的模型 API Key |
23
-
24
- 管理面既有字段、幂等语义见 [Key Binding OpenAPI](../protocol/openapi.yaml)。完整扩展见 [资源 OpenAPI](../protocol/resources.openapi.yaml)。Bootstrap 的可选 `protocol_version` 接受 `worker.user-center.v1`、`worker-user-center/v1` 或 `eduwork-resources/v1`;未知版本拒绝。主体身份只来自经验证的 OIDC,Bootstrap 不覆盖用户身份、发行配置、执行模块或服务地址。资源请求不跟随重定向。
25
-
26
- ## 模型目录
27
-
28
- `provider.modelSource` 默认 `profile`,使用发行方已审查的模型事实,保证现有部署不受发现接口变化影响。设为 `discovery` 时登录/凭据关联后自动读取 `/models`;`models` 可省略,初始化时等待目录,不注册伪造的模型。
29
-
30
- `/models` 返回 `{"data":[{"id":"model-a"}]}`,最多 128 个不同 ID。目录内已在 Profile 声明的 ID 沿用其 reasoning、模态和上下文等事实;其他新 ID 仅声明文本与不支持推理档位。不能从模型名猜能力,也不采用服务响应中的执行配置或任意 URL。目录为空、结构错误或暂不可用时保留上一份已可用目录,并单独返回 `models_unavailable`。
31
-
32
- 成功更新目录会替换同一 Provider 的运行模型快照,新调用使用新目录,已经准备的调用继续使用原快照。重启后首次读取已登录状态会重新发现。个人提供方不受影响。
33
-
34
- ## 宿主 RPC 与装配
35
-
36
- 插件名为 `@eduwork/dsh-oidc`,Bundle 层 ID 为 `enterprise-oidc`。`backend: web`、`uiMode: standard` 启用公共界面;`external` 允许产品自绘入口但保留公共 RPC。`allowEmptyProfiles: true` 允许公版先只用个人 Key。
37
-
38
- 环境变量 `EDUWORK_OIDC_PROFILE` 指向一个 Profile、Profile 数组或 `{ "profiles": [...] }` 文件。未设置时兼容 `DSH_OIDC_ENTERPRISE_PROFILE`;显式 `profilePathEnv` 仍遵循宿主指定名称。
39
-
40
- `oidcAccounts.configuration/status/begin/reconcile/logout/management` 保持原契约;新增 `resources(profileID)` 返回 `{profileID, modelSource, models, issues}`,不含秘密。`reconcile` 自动同步模型元数据。旧 `native` backend 不调用原配额桥接口,不新增桌面框架依赖;新桌面 `backend: desktop` 与 Web 共享 OIDC 实现,使用临时 loopback 回调而不依赖常驻 WebServer。
41
-
42
- 专属插件可在 Host 调用 `ctx.oidcAccounts.authorizedFetch(profileID, endpoint, init)`,复用有效 OIDC Access Token、刷新及一次 401 重试,得到普通 `Response`。此方法没有 Remote 标记,不向浏览器暴露 Token;默认只允许该 Profile 的 issuer 和 Key Binding 精确 origin。额外 HTTPS origin 必须通过受信宿主插件配置 `authorizedOrigins` 声明,浏览器不能改变。并发请求共享一次 Refresh Token 轮换,避免心跳与模型配置同时刷新造成失效。该入口提供认证运输能力,不定义心跳或语音业务。
43
-
44
- Host 事件 `oidc/accounts-changed` 返回 `{profileID, state}`。`authenticated` 与 `connected` 都表示身份已登录,纯身份的 `connected` 不要求模型 Key;`signed_out` 表示已退出。未登录的授权请求抛出 `oidc_login_required`,越界 origin 为 `oidc_authorized_origin_denied`;第二次 HTTP 401 仍返回 Response,由业务方处理。主动退出不应自动弹出过期提示。
45
-
46
- Issuer、Client ID 或资源端点变化会阻止旧管理凭据流向新环境;旧 Web 登录记录仍可复用身份,但需要重新关联模型 Key。个人 API Key 不受机构注销与资源绑定变化影响。
47
-
9
+ | 模型目录 GET /models | 已验证网关发现的 API 基址 | 当前 Access Token |
10
+ | 模型 JSON/SSE 调用 | 相同 API 基址 | 当前 Access Token |
11
+ | 可选机构配额 GET | 机构扩展声明的相对路径 | 共享 Host 传输中的当前 Access Token |
48
12
 
13
+ 目录响应中的 data[].id 决定可见模型;本地元数据可以补充上下文、模态和推理事实,不能扩大服务端授权。退出或重新授权会取消在途调用,并拒绝旧调用使用新账户凭据。同一授权正常刷新可以继续工作。
49
14
 
50
- 机构账户扩展使用 [Host 授权传输与账户菜单插槽](account-extensions.md)。声明 capability 不会激活扩展;发行方必须显式安装和配置机构插件。
15
+ 公共 Remote 只返回模型资源投影,不包含 Token、配额或管理接口。配额逻辑和授权范围由机构维护,见[账户扩展](account-extensions.md)。[目录 OpenAPI](../protocol/resources.openapi.yaml)与[网关契约](gateway-auth/README.md)共同说明接入表面。