@eduwork/dsh-oidc 0.2.3 → 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 (84) hide show
  1. package/CHANGELOG.en.md +6 -38
  2. package/CHANGELOG.md +7 -39
  3. package/CODE_OF_CONDUCT.en.md +1 -1
  4. package/CODE_OF_CONDUCT.md +1 -1
  5. package/CONTRIBUTING.en.md +1 -1
  6. package/CONTRIBUTING.md +1 -1
  7. package/README.md +21 -130
  8. package/README_EN.md +36 -0
  9. package/SECURITY.en.md +1 -1
  10. package/SECURITY.md +1 -1
  11. package/SUPPORT.en.md +1 -1
  12. package/SUPPORT.md +1 -1
  13. package/docs/EDUWORK-MIGRATION.en.md +3 -31
  14. package/docs/EDUWORK-MIGRATION.md +3 -31
  15. package/docs/account-extensions.en.md +6 -6
  16. package/docs/account-extensions.md +3 -3
  17. package/docs/architecture.en.md +12 -117
  18. package/docs/architecture.md +12 -118
  19. package/docs/compatibility.en.md +6 -62
  20. package/docs/compatibility.md +6 -62
  21. package/docs/decisions/0001-one-plugin-composition-boundary.en.md +2 -2
  22. package/docs/decisions/0001-one-plugin-composition-boundary.md +2 -2
  23. package/docs/desktop-host.en.md +54 -55
  24. package/docs/desktop-host.md +63 -64
  25. package/docs/development.en.md +44 -44
  26. package/docs/development.md +6 -6
  27. package/docs/dsh-integration.en.md +13 -48
  28. package/docs/dsh-integration.md +14 -49
  29. package/docs/ecnu-reference.en.md +4 -61
  30. package/docs/ecnu-reference.md +4 -61
  31. package/docs/enterprise-profile.en.md +10 -31
  32. package/docs/enterprise-profile.md +11 -32
  33. package/docs/gateway-auth/README.md +168 -0
  34. package/docs/gateway-auth/README_EN.md +70 -0
  35. package/docs/gateway-auth/experimental-oidc-llm.en.md +53 -0
  36. package/docs/gateway-auth/experimental-oidc-llm.md +53 -0
  37. package/docs/gateway-auth/litellm-setup.en.md +114 -0
  38. package/docs/gateway-auth/litellm-setup.md +114 -0
  39. package/docs/gateway-auth/oidc-llm-draft.en.md +141 -0
  40. package/docs/gateway-auth/oidc-llm-draft.md +141 -0
  41. package/docs/getting-started.en.md +17 -122
  42. package/docs/getting-started.md +16 -225
  43. package/docs/key-binding-protocol.en.md +10 -220
  44. package/docs/key-binding-protocol.md +10 -220
  45. package/docs/oidc-interoperability.en.md +1 -1
  46. package/docs/oidc-interoperability.md +1 -1
  47. package/docs/open-integration.en.md +11 -0
  48. package/docs/open-integration.md +11 -0
  49. package/docs/public-resource-protocol.en.md +8 -44
  50. package/docs/public-resource-protocol.md +8 -43
  51. package/docs/release-checklist.en.md +7 -61
  52. package/docs/release-checklist.md +7 -61
  53. package/docs/security-model.en.md +10 -132
  54. package/docs/security-model.md +10 -132
  55. package/docs/server-integration-contract.en.md +12 -811
  56. package/docs/server-integration-contract.md +12 -823
  57. package/examples/ecnu.enterprise-profile.example.json +14 -19
  58. package/examples/enterprise-profile.example.json +73 -78
  59. package/examples/identity-only.example.json +1 -1
  60. package/examples/litellm.enterprise-profile.example.json +9 -0
  61. package/examples/oidc-llm.enterprise-profile.example.json +12 -0
  62. package/examples/resources-discovery.example.json +6 -9
  63. package/lib/callback-page.js +5 -5
  64. package/lib/client.js +31 -48
  65. package/lib/desktop-oidc.js +7 -11
  66. package/lib/gateway-backend.js +443 -0
  67. package/lib/gateway-protocol.js +6 -0
  68. package/lib/index.js +14 -15
  69. package/lib/litellm-protocol.js +117 -0
  70. package/lib/model-resource-transport.js +19 -0
  71. package/lib/oidc-llm-protocol.js +88 -0
  72. package/lib/oidc.js +37 -323
  73. package/lib/profile.js +34 -40
  74. package/lib/provider/authorization-scope.js +46 -0
  75. package/lib/provider/index.js +11 -2
  76. package/lib/provider/transforms.js +0 -1
  77. package/lib/typert-schemas.js +1 -1
  78. package/lib/typert.host.js +38 -38
  79. package/lib/typert.remote-client.js +37 -37
  80. package/package.json +7 -6
  81. package/protocol/openapi.yaml +33 -240
  82. package/protocol/resources.openapi.yaml +8 -9
  83. package/schema/enterprise-profile.v1alpha1.schema.json +595 -193
  84. package/README.en.md +0 -186
@@ -1,257 +1,50 @@
1
1
  openapi: 3.1.0
2
2
  info:
3
- title: dsh-oidc Worker User Center Key Binding API
3
+ title: EduWork Identity and Resource Protocol
4
4
  version: 1.0.0
5
5
  description: >-
6
- The fixed worker-user-center-v1 protocol used by dsh-oidc to exchange an
7
- OIDC Bearer access token for a short-lived or revocable model runtime
8
- credential. Endpoint paths and wire field names are deliberately not
9
- configurable. See docs/key-binding-protocol.md for normative requirements.
10
- license:
11
- name: MIT
12
- identifier: MIT
6
+ Model discovery for a local single-user client with explicit gateway authorization.
7
+ Requests use the current Access Token. The client does not provision model API keys.
8
+ Quota and activity heartbeat remain optional institution extensions.
9
+ license: { name: MIT, identifier: MIT }
13
10
  servers:
14
- - url: https://ai.example.edu/api/worker/v1
15
- description: Example baseURL from an Enterprise Profile
11
+ - url: https://ai.example.edu/open/api/v1
16
12
  security:
17
- - oidcAccessToken: []
13
+ - accessToken: []
18
14
  paths:
19
- /bootstrap:
15
+ /models:
20
16
  get:
21
- operationId: bootstrap
22
- summary: Read subject-independent integration state and credential lifecycle state
17
+ operationId: listResourceModels
23
18
  responses:
24
19
  '200':
25
- description: Current provider and runtime credential state
26
- headers:
27
- Cache-Control:
28
- schema: { type: string }
29
- description: MUST contain no-store
20
+ description: Available model identifiers; reviewed capabilities remain in the client Profile
30
21
  content:
31
22
  application/json:
32
- schema: { $ref: '#/components/schemas/BootstrapResponse' }
33
- '401': { $ref: '#/components/responses/Unauthorized' }
34
- '403': { $ref: '#/components/responses/Forbidden' }
23
+ schema:
24
+ type: object
25
+ required: [data]
26
+ properties:
27
+ data:
28
+ type: array
29
+ minItems: 1
30
+ maxItems: 128
31
+ items:
32
+ type: object
33
+ required: [id]
34
+ properties:
35
+ id: { type: string, minLength: 1, maxLength: 256 }
36
+ '401': { description: Access Token is invalid or expired }
37
+ '403': { description: Model discovery is not permitted }
38
+ '404': { description: Discovery endpoint is unavailable }
35
39
  '429': { $ref: '#/components/responses/RateLimited' }
36
- '5XX': { $ref: '#/components/responses/ServerError' }
37
- /runtime-credential/provision:
38
- post:
39
- operationId: provisionRuntimeCredential
40
- summary: Provision and return a runtime credential for the authenticated subject
41
- parameters:
42
- - $ref: '#/components/parameters/IdempotencyKey'
43
- requestBody:
44
- required: true
45
- content:
46
- application/json:
47
- schema: { $ref: '#/components/schemas/RuntimeCredentialRequest' }
48
- responses:
49
- '200': { $ref: '#/components/responses/RuntimeCredential' }
50
- '201': { $ref: '#/components/responses/RuntimeCredential' }
51
- '400': { $ref: '#/components/responses/BadRequest' }
52
- '401': { $ref: '#/components/responses/Unauthorized' }
53
- '403': { $ref: '#/components/responses/Forbidden' }
54
- '409': { $ref: '#/components/responses/Conflict' }
55
- '429': { $ref: '#/components/responses/RateLimited' }
56
- '5XX': { $ref: '#/components/responses/ServerError' }
57
- /runtime-credential/resolve:
58
- post:
59
- operationId: resolveRuntimeCredential
60
- summary: Resolve the active runtime credential for the authenticated subject
61
- requestBody:
62
- required: true
63
- content:
64
- application/json:
65
- schema: { $ref: '#/components/schemas/RuntimeCredentialRequest' }
66
- responses:
67
- '200': { $ref: '#/components/responses/RuntimeCredential' }
68
- '400': { $ref: '#/components/responses/BadRequest' }
69
- '401': { $ref: '#/components/responses/Unauthorized' }
70
- '403': { $ref: '#/components/responses/Forbidden' }
71
- '404': { $ref: '#/components/responses/NotFound' }
72
- '429': { $ref: '#/components/responses/RateLimited' }
73
- '5XX': { $ref: '#/components/responses/ServerError' }
74
- /runtime-credential/renew:
75
- post:
76
- operationId: renewRuntimeCredential
77
- summary: Rotate an expiring or expired runtime credential
78
- parameters:
79
- - $ref: '#/components/parameters/IdempotencyKey'
80
- requestBody:
81
- required: true
82
- content:
83
- application/json:
84
- schema:
85
- allOf:
86
- - $ref: '#/components/schemas/RuntimeCredentialRequest'
87
- - type: object
88
- required: [api_key_id]
89
- responses:
90
- '200': { $ref: '#/components/responses/RuntimeCredential' }
91
- '201': { $ref: '#/components/responses/RuntimeCredential' }
92
- '400': { $ref: '#/components/responses/BadRequest' }
93
- '401': { $ref: '#/components/responses/Unauthorized' }
94
- '403': { $ref: '#/components/responses/Forbidden' }
95
- '404': { $ref: '#/components/responses/NotFound' }
96
- '409': { $ref: '#/components/responses/Conflict' }
97
- '429': { $ref: '#/components/responses/RateLimited' }
98
- '5XX': { $ref: '#/components/responses/ServerError' }
40
+ '5XX': { $ref: '#/components/responses/Unavailable' }
99
41
  components:
100
- securitySchemes:
101
- oidcAccessToken:
102
- type: http
103
- scheme: bearer
104
- bearerFormat: JWT or opaque OIDC access token
105
- description: >-
106
- Access token issued to the public OIDC client declared in the matching
107
- Enterprise Profile. The server validates issuer, audience, expiry,
108
- required scopes, and the authenticated subject.
109
- parameters:
110
- IdempotencyKey:
111
- name: Idempotency-Key
112
- in: header
113
- required: true
114
- description: Opaque UUID generated for one logical mutating operation.
115
- schema:
116
- type: string
117
- format: uuid
118
- schemas:
119
- BootstrapResponse:
120
- type: object
121
- additionalProperties: false
122
- required: [provider, capabilities, runtime_credential]
123
- properties:
124
- protocol_version:
125
- type: string
126
- enum: [worker.user-center.v1, worker-user-center/v1, eduwork-resources/v1]
127
- description: Optional during v1 adoption; all three version labels share the deployed credential lifecycle wire.
128
- subject:
129
- $ref: '#/components/schemas/InformationalSubject'
130
- provider:
131
- type: object
132
- additionalProperties: false
133
- required: [id]
134
- properties:
135
- id:
136
- type: string
137
- pattern: '^[a-z][a-z0-9-]{0,63}$'
138
- capabilities:
139
- type: array
140
- maxItems: 256
141
- uniqueItems: true
142
- items: { type: string, minLength: 1, maxLength: 128 }
143
- runtime_credential:
144
- $ref: '#/components/schemas/RuntimeCredentialState'
145
- InformationalSubject:
146
- type: object
147
- additionalProperties: true
148
- description: >-
149
- Optional management-plane display data. dsh-oidc MUST NOT use it to
150
- replace the identity established by the OIDC ID Token and UserInfo.
151
- properties:
152
- sub: { type: string }
153
- name: { type: string }
154
- affiliation: { type: string }
155
- RuntimeCredentialState:
156
- type: object
157
- additionalProperties: false
158
- required: [status]
159
- properties:
160
- status:
161
- enum: [missing, active, expiring, expired, suspended, unavailable]
162
- api_key_id:
163
- type: string
164
- minLength: 1
165
- maxLength: 256
166
- expires_at:
167
- type: string
168
- format: date-time
169
- provisioning:
170
- type: object
171
- additionalProperties: false
172
- properties:
173
- allowed: { type: boolean }
174
- reason: { type: string, maxLength: 500 }
175
- RuntimeCredentialRequest:
176
- type: object
177
- additionalProperties: false
178
- required: [provider_id]
179
- properties:
180
- provider_id:
181
- type: string
182
- pattern: '^[a-z][a-z0-9-]{0,63}$'
183
- api_key_id:
184
- type: string
185
- minLength: 1
186
- maxLength: 256
187
- RuntimeCredentialResponse:
188
- type: object
189
- additionalProperties: false
190
- required: [provider_id, api_key, status]
191
- properties:
192
- provider_id:
193
- type: string
194
- pattern: '^[a-z][a-z0-9-]{0,63}$'
195
- api_key:
196
- type: string
197
- minLength: 1
198
- maxLength: 16384
199
- description: Secret value. It MUST appear only in this TLS response and MUST NOT be logged.
200
- api_key_id:
201
- type: string
202
- minLength: 1
203
- maxLength: 256
204
- status:
205
- const: active
206
- expires_at:
207
- type: string
208
- format: date-time
209
- Problem:
210
- type: object
211
- additionalProperties: true
212
- required: [type, title, status]
213
- properties:
214
- type: { type: string, format: uri-reference }
215
- title: { type: string }
216
- status: { type: integer, minimum: 400, maximum: 599 }
217
- detail: { type: string }
218
- instance: { type: string, format: uri-reference }
219
- code: { type: string, description: Stable machine-readable service code }
220
42
  responses:
221
- RuntimeCredential:
222
- description: Active runtime credential
223
- headers:
224
- Cache-Control:
225
- schema: { type: string }
226
- description: MUST contain no-store
227
- Pragma:
228
- schema: { type: string }
229
- description: SHOULD be no-cache for compatibility
230
- content:
231
- application/json:
232
- schema: { $ref: '#/components/schemas/RuntimeCredentialResponse' }
233
- BadRequest:
234
- description: Invalid request
235
- content: { application/problem+json: { schema: { $ref: '#/components/schemas/Problem' } } }
236
- Unauthorized:
237
- description: Missing, invalid, expired, or wrong-audience access token
238
- headers:
239
- WWW-Authenticate: { schema: { type: string } }
240
- content: { application/problem+json: { schema: { $ref: '#/components/schemas/Problem' } } }
241
- Forbidden:
242
- description: Authenticated subject lacks the required scope or organization entitlement
243
- content: { application/problem+json: { schema: { $ref: '#/components/schemas/Problem' } } }
244
- NotFound:
245
- description: Requested runtime credential does not exist
246
- content: { application/problem+json: { schema: { $ref: '#/components/schemas/Problem' } } }
247
- Conflict:
248
- description: Idempotency conflict or incompatible credential lifecycle state
249
- content: { application/problem+json: { schema: { $ref: '#/components/schemas/Problem' } } }
250
43
  RateLimited:
251
- description: Rate limit exceeded
44
+ description: Temporarily limited; current client reports unavailable and allows a later manual refresh
252
45
  headers:
253
- Retry-After: { schema: { type: string } }
254
- content: { application/problem+json: { schema: { $ref: '#/components/schemas/Problem' } } }
255
- ServerError:
256
- description: Server-side failure with no secret material
257
- content: { application/problem+json: { schema: { $ref: '#/components/schemas/Problem' } } }
46
+ Retry-After: { schema: { type: string }, description: Seconds or HTTP date for a future retry; never a refresh-token grant }
47
+ Unavailable:
48
+ description: Temporary resource failure; do not clear identity or the model key
49
+ securitySchemes:
50
+ accessToken: { type: http, scheme: bearer, description: Model runtime credential }
@@ -3,15 +3,14 @@ info:
3
3
  title: EduWork Identity and Resource Protocol
4
4
  version: 1.0.0
5
5
  description: >-
6
- Optional resource integration for a local single-user OIDC client.
7
- Management uses worker-user-center-v1 bootstrap and credential operations. Quota and activity heartbeat are institution extensions, absent from this contract.
8
- Model discovery uses the resulting runtime API key, never the
9
- identity token. Pure OIDC deployments may omit resource integration.
6
+ Model discovery for a local single-user client with explicit gateway authorization.
7
+ Requests use the current Access Token. The client does not provision model API keys.
8
+ Quota and activity heartbeat remain optional institution extensions.
10
9
  license: { name: MIT, identifier: MIT }
11
10
  servers:
12
11
  - url: https://ai.example.edu/open/api/v1
13
12
  security:
14
- - runtimeKey: []
13
+ - accessToken: []
15
14
  paths:
16
15
  /models:
17
16
  get:
@@ -34,9 +33,9 @@ paths:
34
33
  required: [id]
35
34
  properties:
36
35
  id: { type: string, minLength: 1, maxLength: 256 }
37
- '401': { description: Runtime key is invalid or expired }
38
- '403': { description: Model discovery is not permitted; keep the reviewed catalog }
39
- '404': { description: Discovery not supported; client keeps reviewed model catalog }
36
+ '401': { description: Access Token is invalid or expired }
37
+ '403': { description: Model discovery is not permitted }
38
+ '404': { description: Discovery endpoint is unavailable }
40
39
  '429': { $ref: '#/components/responses/RateLimited' }
41
40
  '5XX': { $ref: '#/components/responses/Unavailable' }
42
41
  components:
@@ -48,4 +47,4 @@ components:
48
47
  Unavailable:
49
48
  description: Temporary resource failure; do not clear identity or the model key
50
49
  securitySchemes:
51
- runtimeKey: { type: http, scheme: bearer, description: Model runtime credential }
50
+ accessToken: { type: http, scheme: bearer, description: Model runtime credential }