@eduwork/dsh-oidc 0.1.0-alpha.11 → 0.2.0
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.
- package/CHANGELOG.en.md +58 -1
- package/CHANGELOG.md +58 -1
- package/CODE_OF_CONDUCT.en.md +17 -0
- package/CODE_OF_CONDUCT.md +17 -0
- package/CONTRIBUTING.en.md +56 -0
- package/CONTRIBUTING.md +56 -0
- package/GOVERNANCE.en.md +41 -0
- package/GOVERNANCE.md +41 -0
- package/MAINTAINERS.en.md +13 -0
- package/MAINTAINERS.md +13 -0
- package/README.en.md +24 -22
- package/README.md +18 -16
- package/SECURITY.en.md +45 -0
- package/SECURITY.md +45 -0
- package/SUPPORT.en.md +15 -0
- package/SUPPORT.md +15 -0
- package/THIRD_PARTY_NOTICES.en.md +7 -5
- package/THIRD_PARTY_NOTICES.md +7 -5
- package/cordis.patch.yml +2 -1
- package/docs/EDUWORK-MIGRATION.en.md +17 -5
- package/docs/EDUWORK-MIGRATION.md +17 -5
- package/docs/account-extensions.en.md +40 -0
- package/docs/account-extensions.md +42 -0
- package/docs/architecture.en.md +9 -9
- package/docs/architecture.md +11 -10
- package/docs/compatibility.en.md +13 -3
- package/docs/compatibility.md +13 -3
- package/docs/decisions/0001-one-plugin-composition-boundary.en.md +1 -1
- package/docs/decisions/0001-one-plugin-composition-boundary.md +1 -1
- package/docs/desktop-host.en.md +69 -0
- package/docs/desktop-host.md +79 -0
- package/docs/development.en.md +42 -0
- package/docs/development.md +42 -0
- package/docs/dsh-integration.en.md +24 -8
- package/docs/dsh-integration.md +24 -8
- package/docs/ecnu-reference.en.md +3 -3
- package/docs/ecnu-reference.md +3 -3
- package/docs/enterprise-profile.en.md +21 -13
- package/docs/enterprise-profile.md +20 -12
- package/docs/getting-started.en.md +13 -17
- package/docs/getting-started.md +17 -19
- package/docs/key-binding-protocol.en.md +2 -2
- package/docs/key-binding-protocol.md +2 -2
- package/docs/oidc-interoperability.en.md +3 -3
- package/docs/oidc-interoperability.md +2 -2
- package/docs/public-resource-protocol.en.md +51 -0
- package/docs/public-resource-protocol.md +50 -0
- package/docs/release-checklist.en.md +13 -8
- package/docs/release-checklist.md +13 -8
- package/docs/server-integration-contract.en.md +124 -8
- package/docs/server-integration-contract.md +136 -8
- package/examples/ecnu.enterprise-profile.example.json +2 -2
- package/examples/enterprise-profile.example.json +78 -77
- package/examples/identity-only.example.json +10 -0
- package/examples/resources-discovery.example.json +20 -0
- package/lib/callback-page.js +42 -0
- package/lib/client.js +938 -294
- package/lib/desktop-oidc.js +205 -0
- package/lib/index.js +148 -18
- package/lib/oidc.js +314 -58
- package/lib/profile.js +96 -39
- package/lib/provider/core.js +76 -15
- package/lib/provider/index.js +54 -22
- package/lib/provider/transform-adapter.js +32 -11
- package/lib/resources.js +23 -0
- package/lib/typert-schemas.js +34 -3
- package/lib/typert.host.js +42 -36
- package/lib/typert.remote-client.js +41 -35
- package/package.json +117 -23
- package/protocol/openapi.yaml +2 -2
- package/protocol/resources.openapi.yaml +51 -0
- package/schema/enterprise-profile.v1alpha1.schema.json +193 -174
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
# Enterprise Profile specification (`dsh-oidc/v1alpha1`)
|
|
2
2
|
|
|
3
|
+
> Candidate extension: omit both keyBinding/provider for identity-only OIDC; brand is optional. Resource mode accepts keyBinding.type=eduwork-resources-v1 (default worker-user-center-v1). provider.modelSource=discovery may omit models; normal profile mode requires models. See [Public resource protocol](public-resource-protocol.en.md).
|
|
4
|
+
|
|
3
5
|
[简体中文](enterprise-profile.md) | **English**
|
|
4
6
|
|
|
5
7
|
## Status and conformance
|
|
6
8
|
|
|
7
|
-
This document specifies the data contract consumed by `dsh-oidc` `0.
|
|
9
|
+
This document specifies the data contract consumed by `dsh-oidc` `0.2.x`. The key words **MUST**, **MUST NOT**, **REQUIRED**, **SHOULD**, **SHOULD NOT**, and **MAY** are interpreted as described by RFC 2119 and RFC 8174.
|
|
8
10
|
|
|
9
11
|
The canonical machine-readable schema is [`schema/enterprise-profile.v1alpha1.schema.json`](../schema/enterprise-profile.v1alpha1.schema.json). Runtime validation is intentionally stricter in several security-sensitive URL cases. A conforming profile MUST pass both JSON Schema validation and `normalizeEnterpriseProfile()`.
|
|
10
12
|
|
|
@@ -15,7 +17,7 @@ Profiles are trusted deployment configuration, not user input. Nevertheless, the
|
|
|
15
17
|
- unknown keys are rejected at the root and at every executable-relevant nested object;
|
|
16
18
|
- total serialized profile size is limited to 512 KiB;
|
|
17
19
|
- production URLs require HTTPS;
|
|
18
|
-
- development HTTP
|
|
20
|
+
- development HTTP needs an explicit loopback allowance or exact development-origin allowlist;
|
|
19
21
|
- URL credentials, fragments, and endpoint-base query strings are rejected;
|
|
20
22
|
- only the built-in `openai-compatible` adapter can be selected;
|
|
21
23
|
- Key Binding accepts only its protocol base and an optional local DSH credential reference; network paths and fields remain fixed;
|
|
@@ -34,10 +36,10 @@ A remote administration system MAY distribute profile JSON only if the host auth
|
|
|
34
36
|
| `nativeInstitutionID` | no | Identifier passed only to a native backend; defaults to `id`. |
|
|
35
37
|
| `allowInsecureDevelopment` | no | Enables loopback HTTP for local development. Network HTTP additionally requires `insecureDevelopmentOrigin`. |
|
|
36
38
|
| `insecureDevelopmentOrigin` | no | Exact non-TLS development origin. It is accepted only together with `allowInsecureDevelopment: true`, and every HTTP OIDC/key-binding/provider endpoint must use this exact origin. Never ship it in a production profile. |
|
|
37
|
-
| `brand` |
|
|
39
|
+
| `brand` | no | Bounded presentational values. |
|
|
38
40
|
| `oidc` | yes | OIDC public-client facts. |
|
|
39
|
-
| `keyBinding` |
|
|
40
|
-
| `provider` |
|
|
41
|
+
| `keyBinding` | resource mode | Key Binding base URL and optional local DSH credential reference. |
|
|
42
|
+
| `provider` | resource mode | One local OpenAI-compatible Provider route and model list. |
|
|
41
43
|
|
|
42
44
|
## Branding
|
|
43
45
|
|
|
@@ -79,7 +81,7 @@ The Web redirect URI is fixed to `http://127.0.0.1:<DSH-port>/oauth/callback`. T
|
|
|
79
81
|
```json
|
|
80
82
|
{
|
|
81
83
|
"baseURL": "https://ai.example.edu/api/worker/v1",
|
|
82
|
-
"credentialRef": "
|
|
84
|
+
"credentialRef": "EDUWORK_API_KEY"
|
|
83
85
|
}
|
|
84
86
|
```
|
|
85
87
|
|
|
@@ -88,9 +90,11 @@ The Web redirect URI is fixed to `http://127.0.0.1:<DSH-port>/oauth/callback`. T
|
|
|
88
90
|
| `baseURL` | yes | Base URL of the `worker-user-center-v1` Key Binding interface group. |
|
|
89
91
|
| `credentialRef` | no | Local DSH Credential Provider name under which the bound model API key is stored. It must match `^[A-Za-z_][A-Za-z0-9_]*$` and is limited to 128 characters. |
|
|
90
92
|
|
|
91
|
-
The
|
|
93
|
+
The Provider ID sent on the wire is always `provider.id`. An omitted `credentialRef` now defaults to `EDUWORK_API_KEY`. Legacy automatic references derived from this Profile’s `id` or `provider.id` (uppercase, non-alphanumerics replaced with `_`, followed by `_API_KEY`) normalize to this common name. Other explicit references remain unchanged.
|
|
94
|
+
|
|
95
|
+
`credentialRef` names a local secret-store entry; it is not a key and is never sent over the network. Normal deployments use `EDUWORK_API_KEY`; explicit independent overrides such as `MY_TEST_MODEL_KEY` remain supported. With a shared reference, only a verified login whose bound credential fingerprint matches the current key may read it. Rebinding leaves other profiles disconnected from that key, and their logout cannot delete a key written by another login. Independently configured personal model credentials are unaffected.
|
|
92
96
|
|
|
93
|
-
|
|
97
|
+
An upgrade imports an old key only when issuer, client ID, management URL, runtime URL and Provider ID all match and only the automatic reference changed. It neither overwrites nor adopts an occupied target. Unproven ownership retains identity but requires reconnecting model resources. Pre-fingerprint sessions are accepted only with an identical complete binding and unambiguous reference ownership.
|
|
94
98
|
|
|
95
99
|
Endpoint paths, request/response fields, and Provider ID semantics are protocol facts and MUST NOT be customized by profiles. If a native host returns `runtimeCredentialRef`, it MUST equal the normalized profile value or the plugin fails closed.
|
|
96
100
|
|
|
@@ -100,11 +104,11 @@ The Provider object is data interpreted by a local audited adapter.
|
|
|
100
104
|
|
|
101
105
|
| Field | Required | Meaning |
|
|
102
106
|
| --- | --- | --- |
|
|
103
|
-
| `id` | yes | DSH route ID
|
|
107
|
+
| `id` | yes | DSH route ID, independent of the shared default credential reference. Must be unique across loaded profiles. |
|
|
104
108
|
| `displayName` | no | User-facing Provider name. |
|
|
105
109
|
| `adapter` | yes | Exact string `openai-compatible`. |
|
|
106
110
|
| `baseURL` | yes | HTTPS OpenAI-compatible API base. |
|
|
107
|
-
| `reasoning` | no | Default DSH/pi-ai reasoning level
|
|
111
|
+
| `reasoning` | no | Default DSH/pi-ai reasoning level: `off`, `minimal`, `low`, `medium`, `high`, `xhigh`, or `max`; default `high`. |
|
|
108
112
|
| `defaultContextWindow` | no | Positive safe integer, default 262144. |
|
|
109
113
|
| `defaultMaxTokens` | no | Positive safe integer, default 32768. |
|
|
110
114
|
| `maxRequestImageBytes` | no | Accumulated native-image request budget. |
|
|
@@ -113,7 +117,8 @@ The Provider object is data interpreted by a local audited adapter.
|
|
|
113
117
|
| `streamIdleTimeoutMs` | no | Positive idle timeout, default 300000. |
|
|
114
118
|
| `retryPolicy` | no | DSH provider-owned retry policy; default normal/2 retries. |
|
|
115
119
|
| `compat` | no | Bounded pi-ai OpenAI compatibility facts. |
|
|
116
|
-
| `
|
|
120
|
+
| `modelSource` | no | `profile` (default) or `discovery`; discovery requests `/models` with the managed key. |
|
|
121
|
+
| `models` | profile mode | 1–128 unique entries; discovery may omit them, and configured entries supply reviewed capabilities. |
|
|
117
122
|
|
|
118
123
|
`retryPolicy.mode` is `normal` or `always`. `always` can retry indefinitely until success, cancellation, or disposal and SHOULD NOT be enabled without an explicit product decision. The policy is validated again by DSH.
|
|
119
124
|
|
|
@@ -128,9 +133,12 @@ Each model has:
|
|
|
128
133
|
- `input` containing `text`, `image`, or both (default `text`);
|
|
129
134
|
- optional positive `contextWindow` and `maxTokens`;
|
|
130
135
|
- optional `reasoning` boolean;
|
|
131
|
-
- optional `reasoningEfforts` object, or `false`;
|
|
136
|
+
- optional `reasoningEfforts` object, or `false`; object keys are limited to `off`, `minimal`, `low`, `medium`, `high`, `xhigh`, and `max`, and only `off` may have a null wire value;
|
|
137
|
+
- optional `defaultReasoningEffort`, which must name an effort declared by that model; when omitted, the historical provider-level `reasoning` preference falls back to the nearest supported effort, choosing the lower effort on a tie;
|
|
132
138
|
- optional bounded `compat` overrides.
|
|
133
139
|
|
|
140
|
+
Once `reasoningEfforts` is declared, every omitted effort is explicitly unsupported. Effort IDs and wire values remain distinct, so `xhigh` is never silently rewritten as `max`. For thinking without a user-selectable effort, set only `compat.supportsReasoningEffort` to `false`; for a model with no thinking capability, set `reasoning` or `reasoningEfforts` to `false`.
|
|
141
|
+
|
|
134
142
|
If a model supports thinking but not selectable reasoning effort, set:
|
|
135
143
|
|
|
136
144
|
```json
|
|
@@ -139,7 +147,7 @@ If a model supports thinking but not selectable reasoning effort, set:
|
|
|
139
147
|
}
|
|
140
148
|
```
|
|
141
149
|
|
|
142
|
-
The adapter
|
|
150
|
+
The adapter preserves the profile's thinking behavior: historical user-selected efforts are ignored, the profile default is resolved against that model's supported levels, and only an internal enabling signal is passed to PiAi. `compat.supportsReasoningEffort: false` keeps `reasoning_effort` out of the HTTP request. This signal does not create selectable UI efforts; a profile default of `off` still disables models that support it. The request is not rejected merely because the provider lacks an effort parameter.
|
|
143
151
|
|
|
144
152
|
## Secret prohibition
|
|
145
153
|
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
# Enterprise Profile 规范(`dsh-oidc/v1alpha1`)
|
|
2
2
|
|
|
3
|
+
> 当前候选扩展:纯身份模式同时省略 keyBinding/provider;brand 可省略。资源模式支持 keyBinding.type=eduwork-resources-v1,默认兼容 worker-user-center-v1。provider.modelSource=discovery 时 models 可省略;默认 profile 模式仍要求模型列表。见 [公共资源协议](public-resource-protocol.md)。
|
|
4
|
+
|
|
3
5
|
**简体中文** | [English](enterprise-profile.en.md)
|
|
4
6
|
|
|
5
7
|
## 状态与符合性
|
|
6
8
|
|
|
7
|
-
本文规定 `dsh-oidc` `0.
|
|
9
|
+
本文规定 `dsh-oidc` `0.2.x` 使用的数据契约。关键词 **必须(MUST)**、**不得(MUST NOT)**、**必需(REQUIRED)**、**应该(SHOULD)**、**不应该(SHOULD NOT)** 和 **可以(MAY)** 按 RFC 2119 与 RFC 8174 解释。
|
|
8
10
|
|
|
9
11
|
权威机器可读 Schema 为 [`schema/enterprise-profile.v1alpha1.schema.json`](../schema/enterprise-profile.v1alpha1.schema.json)。运行时对若干安全敏感 URL 的校验有意比 JSON Schema 更严格。符合规范的 Profile 必须同时通过 JSON Schema 和 `normalizeEnterpriseProfile()` 校验。
|
|
10
12
|
|
|
@@ -34,10 +36,10 @@ Profile 是受信任的部署配置,不是用户输入。即便如此,解析
|
|
|
34
36
|
| `nativeInstitutionID` | 否 | 仅传给 native 后端的标识符;默认使用 `id`。 |
|
|
35
37
|
| `allowInsecureDevelopment` | 否 | 为本地开发启用 loopback HTTP。网络 HTTP 还必须配置 `insecureDevelopmentOrigin`。 |
|
|
36
38
|
| `insecureDevelopmentOrigin` | 否 | 精确的非 TLS 开发 origin。只有与 `allowInsecureDevelopment: true` 一起使用时才有效,且所有 HTTP OIDC/Key Binding/Provider endpoint 必须使用该 origin。不得放入生产 Profile。 |
|
|
37
|
-
| `brand` |
|
|
39
|
+
| `brand` | 否 | 有边界的展示配置。 |
|
|
38
40
|
| `oidc` | 是 | OIDC public client 配置事实。 |
|
|
39
|
-
| `keyBinding` |
|
|
40
|
-
| `provider` |
|
|
41
|
+
| `keyBinding` | 资源模式 | Key Binding 基础 URL,以及可选的本地 DSH 凭据引用。 |
|
|
42
|
+
| `provider` | 资源模式 | 一个本地 OpenAI-compatible Provider 路由和模型列表。 |
|
|
41
43
|
|
|
42
44
|
## 品牌替换
|
|
43
45
|
|
|
@@ -79,7 +81,7 @@ Web 重定向地址固定为 `http://127.0.0.1:<DSH端口>/oauth/callback`。hos
|
|
|
79
81
|
```json
|
|
80
82
|
{
|
|
81
83
|
"baseURL": "https://ai.example.edu/api/worker/v1",
|
|
82
|
-
"credentialRef": "
|
|
84
|
+
"credentialRef": "EDUWORK_API_KEY"
|
|
83
85
|
}
|
|
84
86
|
```
|
|
85
87
|
|
|
@@ -88,9 +90,11 @@ Web 重定向地址固定为 `http://127.0.0.1:<DSH端口>/oauth/callback`。hos
|
|
|
88
90
|
| `baseURL` | 是 | `worker-user-center-v1` Key Binding 接口组的基址。 |
|
|
89
91
|
| `credentialRef` | 否 | 保存绑定后模型 API Key 的本地 DSH Credential Provider 名称。必须匹配 `^[A-Za-z_][A-Za-z0-9_]*$`,最长 128 字符。 |
|
|
90
92
|
|
|
91
|
-
|
|
93
|
+
请求中的 Provider ID 固定取 `provider.id`。`credentialRef` 省略时统一为 `EDUWORK_API_KEY`。旧配置中按本 Profile 的 `id` 或 `provider.id` 大写、非字母数字替换为 `_` 后追加 `_API_KEY` 的引用,按兼容别名规范化到同一默认值,不再按企业生成名称。其他显式引用原样保留。
|
|
94
|
+
|
|
95
|
+
`credentialRef` 只是本地秘密存储的引用名,不是 API Key,不发送给 OIDC、Key Binding 或模型服务。常规部署使用 `EDUWORK_API_KEY`;需要额外独立管理的显式引用仍可使用例如 `MY_TEST_MODEL_KEY`。默认槽位记录当前绑定的企业 Key;多个 Profile 共用时,仅凭据指纹与当前 Key 匹配的已验证登录可以读取它。重新绑定后,其他 Profile 不会借用该 Key,登出也不会删除其他登录写入的新 Key。个人模型使用的独立引用不受影响。
|
|
92
96
|
|
|
93
|
-
|
|
97
|
+
升级只在同一 issuer、client ID、资源管理基址、模型服务基址、Provider ID 且仅旧自动引用改名时迁移原 Key。新槽位已有值时既不覆盖也不自动接管;无法证明归属时保留身份并重新连接模型资源。旧会话缺少指纹时,仅完整绑定相同且引用归属无歧义才兼容。
|
|
94
98
|
|
|
95
99
|
Endpoint 路径、请求/响应字段和 Provider ID 语义属于协议事实,不得由 Profile 自定义。Native 宿主若返回 `runtimeCredentialRef`,其值必须与本字段规范化后的结果一致,否则插件失败关闭。
|
|
96
100
|
|
|
@@ -100,11 +104,11 @@ Provider 对象是由本地、经过审查的 adapter 解释的数据。
|
|
|
100
104
|
|
|
101
105
|
| 字段 | 必需 | 含义 |
|
|
102
106
|
| --- | --- | --- |
|
|
103
|
-
| `id` | 是 | DSH 路由 ID
|
|
107
|
+
| `id` | 是 | DSH 路由 ID;在所有已加载 Profile 中必须唯一。 |
|
|
104
108
|
| `displayName` | 否 | 面向用户的 Provider 名称。 |
|
|
105
109
|
| `adapter` | 是 | 精确字符串 `openai-compatible`。 |
|
|
106
110
|
| `baseURL` | 是 | HTTPS OpenAI-compatible API 基址。 |
|
|
107
|
-
| `reasoning` | 否 | 默认 DSH/pi-ai reasoning level
|
|
111
|
+
| `reasoning` | 否 | 默认 DSH/pi-ai reasoning level,取值为 `off`、`minimal`、`low`、`medium`、`high`、`xhigh`、`max`,默认为 `high`。 |
|
|
108
112
|
| `defaultContextWindow` | 否 | 正安全整数,默认 262144。 |
|
|
109
113
|
| `defaultMaxTokens` | 否 | 正安全整数,默认 32768。 |
|
|
110
114
|
| `maxRequestImageBytes` | 否 | 单次原生图片请求的累计大小预算。 |
|
|
@@ -113,7 +117,8 @@ Provider 对象是由本地、经过审查的 adapter 解释的数据。
|
|
|
113
117
|
| `streamIdleTimeoutMs` | 否 | 正数空闲超时,默认 300000。 |
|
|
114
118
|
| `retryPolicy` | 否 | 由 DSH Provider 管理的重试策略;默认 normal/重试 2 次。 |
|
|
115
119
|
| `compat` | 否 | 有边界的 pi-ai OpenAI 兼容事实。 |
|
|
116
|
-
| `
|
|
120
|
+
| `modelSource` | 否 | `profile`(默认)或 `discovery`;后者通过受管 Key 请求 `/models`。 |
|
|
121
|
+
| `models` | `profile` 模式 | 1–128 个唯一模型条目;`discovery` 可省略,已配置条目作为能力声明。 |
|
|
117
122
|
|
|
118
123
|
`retryPolicy.mode` 可以是 `normal` 或 `always`。`always` 可能一直重试,直到成功、取消或销毁;没有明确产品决策时不应启用。该策略还会由 DSH 再次校验。
|
|
119
124
|
|
|
@@ -128,9 +133,12 @@ Provider 对象是由本地、经过审查的 adapter 解释的数据。
|
|
|
128
133
|
- `input` 可包含 `text`、`image` 或两者,默认 `text`;
|
|
129
134
|
- 可选的正数 `contextWindow` 和 `maxTokens`;
|
|
130
135
|
- 可选 `reasoning` 布尔值;
|
|
131
|
-
- 可选 `reasoningEfforts` 对象或 `false`;
|
|
136
|
+
- 可选 `reasoningEfforts` 对象或 `false`;对象键限于 `off`、`minimal`、`low`、`medium`、`high`、`xhigh`、`max`,且只有 `off` 的过线值可以为 `null`;
|
|
137
|
+
- 可选 `defaultReasoningEffort`,且必须是该模型在 `reasoningEfforts` 中声明的档位;若省略,旧的 Provider 级 `reasoning` 会就近回落到模型的有效档位,同距时取较低档;
|
|
132
138
|
- 可选的受限 `compat` 覆盖。
|
|
133
139
|
|
|
140
|
+
声明 `reasoningEfforts` 后,未列出的档位会被显式标记为不支持;档位 ID 与过线值分开保存,因此 `xhigh` 不会被静默改成 `max`。若模型支持 thinking 但不支持用户选择档位,可只将 `compat.supportsReasoningEffort` 设为 `false`;若模型完全不支持 thinking,则将 `reasoning` 或 `reasoningEfforts` 设为 `false`。
|
|
141
|
+
|
|
134
142
|
若模型支持 thinking,但不支持选择 reasoning effort,请设置:
|
|
135
143
|
|
|
136
144
|
```json
|
|
@@ -139,7 +147,7 @@ Provider 对象是由本地、经过审查的 adapter 解释的数据。
|
|
|
139
147
|
}
|
|
140
148
|
```
|
|
141
149
|
|
|
142
|
-
Adapter 会保留 Profile 的 thinking
|
|
150
|
+
Adapter 会保留 Profile 的 thinking 行为:忽略历史会话中用户选择的 effort,按该模型可用档位解析 Profile 默认值,仅向 PiAi 传递内部启用信号;`compat.supportsReasoningEffort: false` 保证 HTTP 请求不包含 `reasoning_effort`。该信号不会变成用户可选档位,Profile 的 `off` 仍可关闭支持关闭的模型。不会因为 Provider 不支持 effort 参数而拒绝整个请求。
|
|
143
151
|
|
|
144
152
|
## 禁止写入的秘密
|
|
145
153
|
|
|
@@ -4,14 +4,14 @@
|
|
|
4
4
|
|
|
5
5
|
This guide is for operators integrating `dsh-oidc` into their own DeepSeek Harness deployment. The result is a closed loop: users sign in through the organization's OIDC Provider, explicitly bind a revocable model runtime credential, inspect the enterprise Provider and model catalog, and call those models from ordinary DSH Web.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
The same OIDC implementation supports both desktop shells and local Web validation. It does not require Wails or an ECNU service. This guide uses Web commands; new desktop compositions use `backend: desktop` as described in [desktop integration](desktop-host.en.md).
|
|
8
8
|
|
|
9
9
|
## 1. Prerequisites
|
|
10
10
|
|
|
11
11
|
| Component | Minimum requirement |
|
|
12
12
|
| --- | --- |
|
|
13
|
-
| DSH Host | DeepSeek Harness `0.1.
|
|
14
|
-
| Institutional enterprise-model integration service |
|
|
13
|
+
| DSH Host | This candidate targets DeepSeek Harness `0.1.5-rc.1` on Node.js 22+; do not mix it with the historical stable package. |
|
|
14
|
+
| Institutional enterprise-model integration service | Identity-only mode needs OIDC. Managed models additionally require the fixed Key Binding API and OpenAI-compatible gateway. |
|
|
15
15
|
| Enterprise Profile | Trusted local JSON containing public configuration only. |
|
|
16
16
|
| Credential Provider | The current Web backend supports trusted single-user local storage only. |
|
|
17
17
|
|
|
@@ -25,13 +25,13 @@ Register a public client without a client secret. Its redirect URI must exactly
|
|
|
25
25
|
http://127.0.0.1:3080/oauth/callback
|
|
26
26
|
```
|
|
27
27
|
|
|
28
|
-
`127.0.0.1` and `/oauth/callback` are fixed. `3080` is the recommended DSH port; if the DSH WebServer port changes, the registered URI must use the same port. Do not register `localhost`, a LAN address, or a public address. Discovery must publish `authorization_endpoint`, `token_endpoint`, `jwks_uri`, and `userinfo_endpoint`. UserInfo must contain a non-empty `sub` matching the ID Token; provide the standard `name` claim for a human-readable label. The current release accepts RS256 ID Tokens only.
|
|
28
|
+
This fixed-port example is for local Web validation. New desktops default to a temporary random port; see [desktop integration](desktop-host.en.md) for fixed-port IdPs. `127.0.0.1` and `/oauth/callback` are fixed. `3080` is the recommended DSH port; if the DSH WebServer port changes, the registered URI must use the same port. Do not register `localhost`, a LAN address, or a public address. Discovery must publish `authorization_endpoint`, `token_endpoint`, `jwks_uri`, and `userinfo_endpoint`. UserInfo must contain a non-empty `sub` matching the ID Token; provide the standard `name` claim for a human-readable label. The current release accepts RS256 ID Tokens only.
|
|
29
29
|
|
|
30
30
|
See the complete [OIDC interoperability profile](oidc-interoperability.en.md).
|
|
31
31
|
|
|
32
32
|
## 3. Implement the complete institutional service
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
For managed enterprise models, provide OIDC, the Key Binding group below and an OpenAI-compatible gateway accepting the bound key. Identity-only deployments may skip this section. Internal systems may host different interfaces, but versioning, security, and operations have one accountable integration boundary. See the [server API specification](server-integration-contract.en.md).
|
|
35
35
|
|
|
36
36
|
The configured `keyBinding.baseURL` has four fixed operations:
|
|
37
37
|
|
|
@@ -42,7 +42,7 @@ POST /runtime-credential/resolve
|
|
|
42
42
|
POST /runtime-credential/renew
|
|
43
43
|
```
|
|
44
44
|
|
|
45
|
-
The Profile may additionally use optional `keyBinding.credentialRef` to isolate entries in the local DSH Credential Provider. It is not sent over the network and does not alter these operations.
|
|
45
|
+
The Profile may additionally use optional `keyBinding.credentialRef` to isolate entries in the local DSH Credential Provider. It is not sent over the network and does not alter these operations. Its default is `EDUWORK_API_KEY`; explicit use of that name is also accepted. Use another reference only for independently managed credentials. See the [Profile specification](enterprise-profile.en.md) for legacy migration and ownership checks.
|
|
46
46
|
|
|
47
47
|
Every request carries the OIDC Access Token as a Bearer credential. The service must validate issuer, audience, expiry, scopes, subject, and organization authorization. It must not trust `provider_id` by itself. Credential responses are `no-store`, and `api_key` must never enter logs, metrics labels, or error details.
|
|
48
48
|
|
|
@@ -56,10 +56,10 @@ The Profile is trusted deployment data, not a secret store. It must not contain
|
|
|
56
56
|
|
|
57
57
|
## 5. Install into ordinary DSH Web
|
|
58
58
|
|
|
59
|
-
The package is
|
|
59
|
+
The package is an installable DSH Bundle. Pin `0.2.0` with a coherent DSH `0.1.5-rc.1` host. Consult the npm registry for publication status; during release preparation use a frozen candidate or source checkout if the version is unavailable:
|
|
60
60
|
|
|
61
61
|
```bash
|
|
62
|
-
dsh plugin --profile web add @eduwork/dsh-oidc@0.
|
|
62
|
+
dsh plugin --profile web add @eduwork/dsh-oidc@0.2.0
|
|
63
63
|
```
|
|
64
64
|
|
|
65
65
|
For auditing, development, or testing unpublished changes, install from a local checkout instead:
|
|
@@ -78,16 +78,12 @@ From the parent directory, the equivalent explicit relative-path command is:
|
|
|
78
78
|
dsh plugin --profile web add ./dsh-oidc
|
|
79
79
|
```
|
|
80
80
|
|
|
81
|
-
DSH links the checkout into `$DSH_HOME/profiles/web`; it does not scan or copy the invoking directory. Keep the checkout in place and pin a reviewed commit for source-based deployments.
|
|
82
|
-
|
|
83
|
-
```bash
|
|
84
|
-
dsh plugin --profile web add @eduwork/dsh-oidc@alpha
|
|
85
|
-
```
|
|
81
|
+
DSH links the checkout into `$DSH_HOME/profiles/web`; it does not scan or copy the invoking directory. Keep the checkout in place and pin a reviewed commit for source-based deployments. Production and team Profiles should use an exact npm version and must not mix another DSH prerelease line.
|
|
86
82
|
|
|
87
83
|
Set the trusted local Profile path and start DSH on the fixed loopback host:
|
|
88
84
|
|
|
89
85
|
```bash
|
|
90
|
-
export
|
|
86
|
+
export EDUWORK_OIDC_PROFILE=/etc/dsh/enterprise-profile.json
|
|
91
87
|
dsh --profile web --host 127.0.0.1 --port 3080 --no-open
|
|
92
88
|
```
|
|
93
89
|
|
|
@@ -104,12 +100,12 @@ A product-owned Bundle may mount the plugin explicitly instead of using the defa
|
|
|
104
100
|
- id: enterprise-oidc
|
|
105
101
|
name: '@eduwork/dsh-oidc'
|
|
106
102
|
config:
|
|
107
|
-
profilePathEnv:
|
|
103
|
+
profilePathEnv: EDUWORK_OIDC_PROFILE
|
|
108
104
|
web:
|
|
109
105
|
returnPath: /
|
|
110
106
|
```
|
|
111
107
|
|
|
112
|
-
|
|
108
|
+
New desktop products should use `backend: desktop`, sharing the temporary loopback callback and official `nativeCommand`; see [desktop integration](desktop-host.en.md). Legacy hosts may still use `backend: native`, point `profilePathEnv` at the same standard Enterprise Profile used by Web, and supply the capability-detected `enterpriseAccounts` service. Product-owned institution, tenant, or account catalogs MUST be converted to an Enterprise Profile by the product assembly layer before `dsh-oidc` reads them. Wails, Electron, Tauri, and other hosts can implement that boundary; the plugin depends on neither a desktop framework nor a product catalog format. See [DSH integration](dsh-integration.en.md).
|
|
113
109
|
|
|
114
110
|
## 7. Acceptance checklist
|
|
115
111
|
|
|
@@ -134,4 +130,4 @@ The current Web backend does not support shared Web. A shared scenario needs a n
|
|
|
134
130
|
- **A subject string is shown instead of a name:** return a non-empty standard `name` from UserInfo under the `profile` scope; private JSON-path mappings are intentionally unsupported.
|
|
135
131
|
- **Login works but models do not:** inspect `/bootstrap`, explicit provisioning state, exact `provider_id` equality, and whether the model gateway accepts the bound key.
|
|
136
132
|
- **Thinking works but selectable effort does not:** set model `compat.supportsReasoningEffort` to `false`; thinking remains enabled while the unsupported effort parameter is removed.
|
|
137
|
-
- **
|
|
133
|
+
- **Where enterprise controls live:** the official `settings.models.footer` slot displays configured institutions while keeping personal API keys in the upstream Models settings. Institutions come from trusted distribution files; products may offer a file-opening action. The plugin does not expose a form for arbitrary endpoint changes.
|
package/docs/getting-started.md
CHANGED
|
@@ -16,8 +16,8 @@
|
|
|
16
16
|
|
|
17
17
|
| 组件 | 谁提供 | 最低要求 |
|
|
18
18
|
| --- | --- | --- |
|
|
19
|
-
| DSH Host | 部署方 | DeepSeek Harness `0.1.
|
|
20
|
-
| 机构企业模型集成服务 | 同一服务所有者 |
|
|
19
|
+
| DSH Host | 部署方 | 本版基线 DeepSeek Harness `0.1.5-rc.1`,Node.js 22+;不要与历史稳定包混用。 |
|
|
20
|
+
| 机构企业模型集成服务 | 同一服务所有者 | 纯身份档提供 OIDC;托管模型档再联合提供固定 Key Binding 与 OpenAI-compatible 模型网关。 |
|
|
21
21
|
| Enterprise Profile | 部署方 | 一份受信任的本地 JSON,只存公开配置,不存密钥或个人信息。 |
|
|
22
22
|
| Credential Provider | DSH Host | 当前 Web backend 仅支持可信单用户本机存储。 |
|
|
23
23
|
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
http://127.0.0.1:3080/oauth/callback
|
|
32
32
|
```
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
以下固定端口用于本机 Web 验证。新桌面默认临时随机端口,固定端口 IdP 的配置方法见 [桌面宿主接入](desktop-host.md)。`127.0.0.1` 和 `/oauth/callback` 固定不可配置。`3080` 是推荐的 DSH 端口;若修改 DSH WebServer 端口,OIDC 注册值必须使用相同端口。不要登记 `localhost`、局域网地址或公网地址。
|
|
35
35
|
|
|
36
36
|
OIDC Provider 必须通过 Discovery 发布 `authorization_endpoint`、`token_endpoint`、`jwks_uri` 和 `userinfo_endpoint`,支持 PKCE `S256`,并返回:
|
|
37
37
|
|
|
@@ -43,7 +43,7 @@ OIDC Provider 必须通过 Discovery 发布 `authorization_endpoint`、`token_en
|
|
|
43
43
|
|
|
44
44
|
## 3. 实现完整机构服务端
|
|
45
45
|
|
|
46
|
-
|
|
46
|
+
本节针对托管企业模型能力:需要上一节的 OIDC、下面的 Key Binding,以及接受绑定凭据的 OpenAI-compatible 模型网关。纯身份档可跳过本节。它们可以由内部不同系统承载,但必须有统一的版本、安全和运维责任。接口定义见[服务端接口规范](server-integration-contract.md)。
|
|
47
47
|
|
|
48
48
|
Key Binding 不是 OIDC 标准的一部分,而是 `dsh-oidc` 定义的企业模型凭据协议。Enterprise Profile 用 `baseURL` 指定接口组基址,插件固定调用:
|
|
49
49
|
|
|
@@ -54,7 +54,7 @@ POST {baseURL}/runtime-credential/resolve
|
|
|
54
54
|
POST {baseURL}/runtime-credential/renew
|
|
55
55
|
```
|
|
56
56
|
|
|
57
|
-
Profile 还可以用可选的 `keyBinding.credentialRef` 隔离本地 DSH Credential Provider
|
|
57
|
+
Profile 还可以用可选的 `keyBinding.credentialRef` 隔离本地 DSH Credential Provider 中的秘密条目。它不参与网络请求,也不改变下列接口;默认统一为 `EDUWORK_API_KEY`,也接受同名显式配置;只有需要独立管理的自定义引用才另行指定。旧自动名称兼容迁移和身份归属校验见 [Profile 规范](enterprise-profile.md)。
|
|
58
58
|
|
|
59
59
|
每个请求都携带 OIDC Access Token:
|
|
60
60
|
|
|
@@ -117,12 +117,14 @@ Authorization: Bearer <oidc-access-token>
|
|
|
117
117
|
|
|
118
118
|
Profile 是部署配置,不是用户输入。它可以声明模型事实和有限品牌 token,但不能加载脚本、CSS、工具、Skill 或远程 Provider adapter。字段全集和安全限制见 [Enterprise Profile 规范](enterprise-profile.md)。
|
|
119
119
|
|
|
120
|
-
## 5.
|
|
120
|
+
## 5. 安装到本机 DSH Web
|
|
121
|
+
|
|
122
|
+
本版采用精确的 `0.2.0` 与统一 DSH `0.1.5-rc.1`。发布状态以 npm registry 为准;若准备期间尚未发布,使用本地冻结候选或下方源码方式,不混装旧 DSH 依赖。
|
|
121
123
|
|
|
122
124
|
`dsh-oidc` 本身是可直接安装的 DSH Bundle。团队部署应从 npm 安装经过复核的精确版本:
|
|
123
125
|
|
|
124
126
|
```bash
|
|
125
|
-
dsh plugin --profile web add @eduwork/dsh-oidc@0.
|
|
127
|
+
dsh plugin --profile web add @eduwork/dsh-oidc@0.2.0
|
|
126
128
|
```
|
|
127
129
|
|
|
128
130
|
需要审计、开发或测试尚未发布的改动时,再从本地 checkout 安装:
|
|
@@ -141,23 +143,19 @@ dsh plugin --profile web add .
|
|
|
141
143
|
dsh plugin --profile web add ./dsh-oidc
|
|
142
144
|
```
|
|
143
145
|
|
|
144
|
-
DSH 会把本地 checkout 链接到 `$DSH_HOME/profiles/web`,不会扫描或复制当前目录;安装完成后不要移动或删除 checkout。源码部署应固定经过审核的 commit
|
|
145
|
-
|
|
146
|
-
```bash
|
|
147
|
-
dsh plugin --profile web add @eduwork/dsh-oidc@alpha
|
|
148
|
-
```
|
|
146
|
+
DSH 会把本地 checkout 链接到 `$DSH_HOME/profiles/web`,不会扫描或复制当前目录;安装完成后不要移动或删除 checkout。源码部署应固定经过审核的 commit。生产或团队 Profile 应使用精确 npm 版本,不要混装其他 DSH 预发布线。
|
|
149
147
|
|
|
150
148
|
设置 Enterprise Profile 路径,并让 DSH 监听固定 loopback host:
|
|
151
149
|
|
|
152
150
|
```bash
|
|
153
|
-
export
|
|
151
|
+
export EDUWORK_OIDC_PROFILE=/etc/dsh/enterprise-profile.json
|
|
154
152
|
dsh --profile web --host 127.0.0.1 --port 3080 --no-open
|
|
155
153
|
```
|
|
156
154
|
|
|
157
155
|
PowerShell 示例:
|
|
158
156
|
|
|
159
157
|
```powershell
|
|
160
|
-
$env:
|
|
158
|
+
$env:EDUWORK_OIDC_PROFILE = 'C:\dsh-config\enterprise-profile.json'
|
|
161
159
|
dsh --profile web --host 127.0.0.1 --port 3080 --no-open
|
|
162
160
|
```
|
|
163
161
|
|
|
@@ -174,12 +172,12 @@ dsh --profile web --host 127.0.0.1 --port 3080 --no-open
|
|
|
174
172
|
- id: enterprise-oidc
|
|
175
173
|
name: '@eduwork/dsh-oidc'
|
|
176
174
|
config:
|
|
177
|
-
profilePathEnv:
|
|
175
|
+
profilePathEnv: EDUWORK_OIDC_PROFILE
|
|
178
176
|
web:
|
|
179
177
|
returnPath: /
|
|
180
178
|
```
|
|
181
179
|
|
|
182
|
-
|
|
180
|
+
仅为兼容旧宿主,仍保留以下 native backend 示例:
|
|
183
181
|
|
|
184
182
|
```yaml
|
|
185
183
|
- insert:
|
|
@@ -191,7 +189,7 @@ dsh --profile web --host 127.0.0.1 --port 3080 --no-open
|
|
|
191
189
|
profilePathEnv: PRODUCT_ENTERPRISE_PROFILE
|
|
192
190
|
```
|
|
193
191
|
|
|
194
|
-
native backend 必须提供 `enterpriseAccounts` 服务,并与 Web 一样传入标准 Enterprise Profile。产品自有目录、租户或账号配置必须先由产品装配层转换为该 Profile,不能交给 `dsh-oidc` 解释。宿主可以由 Wails、Electron、Tauri 或其他技术实现;插件本身不依赖任何桌面框架或产品目录格式。接口和能力探测见 [DSH 集成说明](dsh-integration.md)。
|
|
192
|
+
上面是旧版 `native` 桥接示例;新 Wails/Electron 组合应使用 `backend: desktop`,共用临时 loopback 回调与官方 `nativeCommand`,无需另写认证桥。见 [桌面 Host 集成](desktop-host.md)。旧 native backend 必须提供 `enterpriseAccounts` 服务,并与 Web 一样传入标准 Enterprise Profile。产品自有目录、租户或账号配置必须先由产品装配层转换为该 Profile,不能交给 `dsh-oidc` 解释。宿主可以由 Wails、Electron、Tauri 或其他技术实现;插件本身不依赖任何桌面框架或产品目录格式。接口和能力探测见 [DSH 集成说明](dsh-integration.md)。
|
|
195
193
|
|
|
196
194
|
## 7. 上线前验收
|
|
197
195
|
|
|
@@ -234,6 +232,6 @@ native backend 必须提供 `enterpriseAccounts` 服务,并与 Web 一样传
|
|
|
234
232
|
|
|
235
233
|
插件会保留 thinking 行为并移除不受支持的 effort 参数,不会因此拒绝调用。
|
|
236
234
|
|
|
237
|
-
###
|
|
235
|
+
### 企业服务设置在哪里
|
|
238
236
|
|
|
239
|
-
|
|
237
|
+
插件通过官方 `settings.models.footer` 插槽显示已配置机构,保留官方“模型”设置页和个人 API Key。机构配置来自发行方的可信文件;产品可以提供打开配置文件的入口,插件不提供任意创建或修改机构端点的表单。
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
This document defines `worker-user-center-v1`, the enterprise management protocol used by `dsh-oidc` to bind an OIDC-authenticated subject to a model runtime API key. It is not part of OIDC.
|
|
8
8
|
|
|
9
|
-
It is
|
|
9
|
+
It is part of the managed-model tier of the [server API specification](server-integration-contract.en.md), delivered together with the OIDC Provider and model gateway. Identity-only Profiles do not require Key Binding.
|
|
10
10
|
|
|
11
11
|
The key words **MUST**, **MUST NOT**, **REQUIRED**, **SHALL**, **SHALL NOT**, **SHOULD**, **SHOULD NOT**, **RECOMMENDED**, **NOT RECOMMENDED**, **MAY**, and **OPTIONAL** are interpreted as described by RFC 2119 and RFC 8174.
|
|
12
12
|
|
|
@@ -105,7 +105,7 @@ Valid `runtime_credential.status` values are:
|
|
|
105
105
|
|
|
106
106
|
`subject` MAY carry informational management-plane display data. The client MUST NOT use it to replace OIDC `sub` or `name`.
|
|
107
107
|
|
|
108
|
-
`protocol_version`, if present, MUST be `worker-user-center/v1
|
|
108
|
+
`protocol_version`, if present, MUST be `worker.user-center.v1`, `worker-user-center/v1` or `eduwork-resources/v1` (aliases of the same v1 wire; unknown versions are rejected). It is optional during v1 adoption; a future major protocol can require explicit negotiation.
|
|
109
109
|
|
|
110
110
|
## 6. Provision
|
|
111
111
|
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
本文定义 `worker-user-center-v1`:`dsh-oidc` 用它把经 OIDC 认证的 subject 与模型运行时 API Key 绑定。这是企业管理协议,不属于 OIDC 标准。
|
|
8
8
|
|
|
9
|
-
它是[服务端接口规范](server-integration-contract.md)
|
|
9
|
+
它是[服务端接口规范](server-integration-contract.md)中托管模型能力档的组成部分,需与 OIDC Provider 和模型网关共同实现。纯身份 Profile 不要求 Key Binding。
|
|
10
10
|
|
|
11
11
|
关键词 **必须(MUST)**、**不得(MUST NOT)**、**必需(REQUIRED)**、**应该(SHOULD)**、**不应该(SHOULD NOT)**、**建议(RECOMMENDED)**、**不建议(NOT RECOMMENDED)**、**可以(MAY)** 和 **可选(OPTIONAL)** 按 RFC 2119 与 RFC 8174 解释。
|
|
12
12
|
|
|
@@ -105,7 +105,7 @@ Accept: application/json
|
|
|
105
105
|
|
|
106
106
|
`subject` 可以携带仅供管理面显示的信息。客户端不得用它替换 OIDC `sub` 或 `name`。
|
|
107
107
|
|
|
108
|
-
若返回 `protocol_version`,其值必须是 `worker-user-center/v1
|
|
108
|
+
若返回 `protocol_version`,其值必须是 `worker.user-center.v1`、`worker-user-center/v1` 或 `eduwork-resources/v1`(三个别名共享同一组 v1 字段与路径,未知版本拒绝)。该字段在 v1 采用阶段可选;未来 major 协议可以要求显式协商。
|
|
109
109
|
|
|
110
110
|
## 6. Provision
|
|
111
111
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[简体中文](oidc-interoperability.md) | **English**
|
|
4
4
|
|
|
5
|
-
OIDC is
|
|
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.
|
|
6
6
|
|
|
7
7
|
## Standards
|
|
8
8
|
|
|
@@ -93,8 +93,8 @@ The plugin intentionally has no JSON path mapping or private profile endpoint. O
|
|
|
93
93
|
|
|
94
94
|
## Refresh and logout
|
|
95
95
|
|
|
96
|
-
If the access token is within 90 seconds of expiry and a refresh token exists, the plugin refreshes it. On `invalid_grant`, the stored OIDC session and local model credential are removed and login is required. A rotated refresh token replaces the previous one. An expired session without a refresh token is handled the same way when an active session is next required.
|
|
96
|
+
If the access token is within 90 seconds of expiry and a refresh token exists, the plugin refreshes it. On `invalid_grant`, the stored OIDC session and its still-owned local model credential are removed and login is required. A rotated refresh token replaces the previous one. An expired session without a refresh token is handled the same way when an active session is next required.
|
|
97
97
|
|
|
98
|
-
Logout attempts RFC 7009 revocation when Discovery publishes `revocation_endpoint`, then removes
|
|
98
|
+
Logout attempts RFC 7009 revocation when Discovery publishes `revocation_endpoint`, then removes the OIDC session record and only a model credential still owned by that session. A key written by another profile into the shared reference is preserved. Remote revocation failure is logged without blocking local cleanup.
|
|
99
99
|
|
|
100
100
|
The plugin does not implement RP-Initiated Logout or front/back-channel logout in this version.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
**简体中文** | [English](oidc-interoperability.en.md)
|
|
4
4
|
|
|
5
|
-
OIDC 是[服务端接口规范](server-integration-contract.md)
|
|
5
|
+
OIDC 是[服务端接口规范](server-integration-contract.md)的身份能力档,纯身份 Profile 可只实现本文件。只有需要托管模型 Key 和自动配置企业模型时,才必须同时提供 Key Binding 和模型网关。
|
|
6
6
|
|
|
7
7
|
## 标准依据
|
|
8
8
|
|
|
@@ -95,6 +95,6 @@ TLS 信任和 DNS 解析仍由 Node.js 宿主和操作系统负责。
|
|
|
95
95
|
|
|
96
96
|
当 access token 距离过期不足 90 秒且存在 refresh token 时,插件会刷新会话。若收到 `invalid_grant`,会删除已存 OIDC 会话和本地模型凭据,并要求重新登录。轮换后的 refresh token 会替换旧值。没有 refresh token 的过期会话在下次需要活动会话时按同样方式处理。
|
|
97
97
|
|
|
98
|
-
退出登录时,如果 Discovery 发布 `revocation_endpoint`,插件会尝试按 RFC 7009 撤销 token
|
|
98
|
+
退出登录时,如果 Discovery 发布 `revocation_endpoint`,插件会尝试按 RFC 7009 撤销 token;随后在本地删除该 Profile 的 OIDC 会话与归属于它的托管模型凭据;共享引用已被其他登录改写时不会删除另一方的 Key。远程撤销失败会被记录,但不阻止本地清理。
|
|
99
99
|
|
|
100
100
|
当前版本不实现 RP-Initiated Logout、front-channel logout 或 back-channel logout。
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# EduWork public identity and resource protocol v1
|
|
2
|
+
|
|
3
|
+
[简体中文](public-resource-protocol.md) | **English**
|
|
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.
|
|
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 |
|
|
18
|
+
| --- | --- | --- |
|
|
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
|
+
|
|
49
|
+
|
|
50
|
+
|
|
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.
|