@eduwork/dsh-oidc 0.1.0-alpha.11

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 (50) hide show
  1. package/CHANGELOG.en.md +120 -0
  2. package/CHANGELOG.md +120 -0
  3. package/LICENSE +21 -0
  4. package/README.en.md +184 -0
  5. package/README.md +143 -0
  6. package/THIRD_PARTY_NOTICES.en.md +51 -0
  7. package/THIRD_PARTY_NOTICES.md +53 -0
  8. package/cordis.patch.yml +8 -0
  9. package/docs/EDUWORK-MIGRATION.en.md +23 -0
  10. package/docs/EDUWORK-MIGRATION.md +23 -0
  11. package/docs/architecture.en.md +125 -0
  12. package/docs/architecture.md +125 -0
  13. package/docs/compatibility.en.md +61 -0
  14. package/docs/compatibility.md +61 -0
  15. package/docs/decisions/0001-one-plugin-composition-boundary.en.md +34 -0
  16. package/docs/decisions/0001-one-plugin-composition-boundary.md +34 -0
  17. package/docs/dsh-integration.en.md +171 -0
  18. package/docs/dsh-integration.md +171 -0
  19. package/docs/ecnu-reference.en.md +66 -0
  20. package/docs/ecnu-reference.md +66 -0
  21. package/docs/enterprise-profile.en.md +159 -0
  22. package/docs/enterprise-profile.md +159 -0
  23. package/docs/getting-started.en.md +137 -0
  24. package/docs/getting-started.md +239 -0
  25. package/docs/key-binding-protocol.en.md +227 -0
  26. package/docs/key-binding-protocol.md +227 -0
  27. package/docs/oidc-interoperability.en.md +100 -0
  28. package/docs/oidc-interoperability.md +100 -0
  29. package/docs/release-checklist.en.md +60 -0
  30. package/docs/release-checklist.md +60 -0
  31. package/docs/security-model.en.md +138 -0
  32. package/docs/security-model.md +138 -0
  33. package/docs/server-integration-contract.en.md +706 -0
  34. package/docs/server-integration-contract.md +706 -0
  35. package/examples/ecnu.enterprise-profile.example.json +81 -0
  36. package/examples/enterprise-profile.example.json +77 -0
  37. package/lib/client.js +5855 -0
  38. package/lib/index.js +59 -0
  39. package/lib/oidc.js +649 -0
  40. package/lib/profile.js +371 -0
  41. package/lib/provider/core.js +138 -0
  42. package/lib/provider/index.js +156 -0
  43. package/lib/provider/transform-adapter.js +65 -0
  44. package/lib/provider/transforms.js +59 -0
  45. package/lib/typert-schemas.js +84 -0
  46. package/lib/typert.host.js +38 -0
  47. package/lib/typert.remote-client.js +37 -0
  48. package/package.json +120 -0
  49. package/protocol/openapi.yaml +257 -0
  50. package/schema/enterprise-profile.v1alpha1.schema.json +174 -0
@@ -0,0 +1,60 @@
1
+ # Public release checklist
2
+
3
+ [简体中文](release-checklist.md) | **English**
4
+
5
+ Record reviewer names, date, command output links, and exceptions in the release pull request. An unchecked item blocks public release unless a maintainer and security maintainer document why it is not applicable.
6
+
7
+ ## Authority and project metadata
8
+
9
+ - [ ] Repository owner confirmed public release and the MIT license.
10
+ - [ ] The `freedomkk-qfeng/dsh-oidc` remote is confirmed; npm package ownership is approved separately if npm publication is planned.
11
+ - [ ] Maintainer, security, and release-manager rosters recorded with backups.
12
+ - [ ] GitHub Private Vulnerability Reporting is enabled and its entry point has been checked without sensitive data.
13
+ - [ ] ECNU/ChatECNU name, example text, colors, and trademark notice approved.
14
+
15
+ ## Source and protocol review
16
+
17
+ - [ ] Two-person review completed for OIDC, Key Binding, model-gateway invariants, Profile validation, Provider credentials, and native boundary.
18
+ - [ ] Enterprise Profile JSON Schema matches runtime behavior.
19
+ - [ ] OpenAPI matches normative Key Binding prose and implementation.
20
+ - [ ] OIDC standard references and limitations are current.
21
+ - [ ] No unnecessary local reimplementation of a supported DSH capability.
22
+ - [ ] Compatibility matrix and changelog updated.
23
+
24
+ ## Security and privacy
25
+
26
+ - [ ] Threat model reviewed for actual topology.
27
+ - [ ] Single-user versus multi-user Credential Provider boundary verified.
28
+ - [ ] OIDC success and negative conformance suite passed against staging.
29
+ - [ ] Cross-user/tenant Key Binding authorization tests passed.
30
+ - [ ] API-key expiry, rotation, suspension, and remote revocation behavior tested.
31
+ - [ ] Confirmed the WebServer listens only on `127.0.0.1` and no reverse proxy, port forward, or tunnel exposes the local session to other users.
32
+ - [ ] Remote TLS, CSP, cookies, CSRF, egress, clock, logging, APM, and backups reviewed.
33
+ - [ ] Privacy/legal review completed for identity and audit data.
34
+ - [ ] Secret scans of both the current tree and publishable Git history found no production hosts, IDs, keys, logs, personal paths, or personal data.
35
+
36
+ ## Supply chain
37
+
38
+ - [ ] Clean `npm ci` completed on Windows and Linux with Node 22.
39
+ - [ ] `npm audit` and static analysis reviewed (not merely run).
40
+ - [ ] Every direct/transitive license and exception reviewed.
41
+ - [ ] npm install scripts reviewed; unexpected scripts denied.
42
+ - [ ] Lockfile diff reviewed and dependency versions pinned as intended.
43
+ - [ ] GitHub Actions pinned to immutable commits before public release.
44
+
45
+ ## Product acceptance
46
+
47
+ - [ ] Plain Web DSH: login, callback, display name/sub fallback, provision, model call, refresh, check, logout.
48
+ - [ ] Native desktop: current ChatECNU Work experience unchanged.
49
+ - [ ] Native multimodal and text-only + image-transform routes tested.
50
+ - [ ] Unsupported reasoning-effort model still runs with thinking enabled.
51
+ - [ ] Failure UX tested: Discovery, token, UserInfo, bootstrap, policy denial, model key, expiry, network timeout.
52
+
53
+ ## Build and publish
54
+
55
+ - [ ] `npm run check` passes from a clean checkout.
56
+ - [ ] `npm pack --dry-run` and extracted tarball reviewed; only intended files included.
57
+ - [ ] Source maps contain no private absolute paths or secrets.
58
+ - [ ] Tag/release notes/checksums prepared.
59
+ - [ ] npm trusted publishing/provenance configured; no long-lived local publish token.
60
+ - [ ] Rollback/deprecation and vulnerability-notification plan confirmed.
@@ -0,0 +1,60 @@
1
+ # 公开发布检查表
2
+
3
+ **简体中文** | [English](release-checklist.en.md)
4
+
5
+ 在发布 Pull Request 中记录审查人、日期、命令输出链接和例外说明。任何未勾选项目都会阻止公开发布,除非维护者和安全维护者书面说明其不适用原因。
6
+
7
+ ## 授权与项目元数据
8
+
9
+ - [ ] 仓库所有者确认公开发布和 MIT 许可证。
10
+ - [ ] `freedomkk-qfeng/dsh-oidc` 远程仓库位置已确认;如发布 npm,`dsh-oidc` 包所有权另行确认。
11
+ - [ ] 维护者、安全维护者和发布经理名单及替补已记录。
12
+ - [ ] GitHub Private Vulnerability Reporting 已启用并完成一次无敏感数据的入口检查。
13
+ - [ ] ECNU/ChatECNU 名称、示例文字、颜色和商标声明获批。
14
+
15
+ ## 源码与协议审查
16
+
17
+ - [ ] OIDC、Key Binding、模型网关一致性、Profile 校验、Provider 凭据和 native 边界已完成双人审查。
18
+ - [ ] Enterprise Profile JSON Schema 与运行行为一致。
19
+ - [ ] OpenAPI 与 Key Binding 规范正文和实现一致。
20
+ - [ ] OIDC 标准引用和限制仍然有效。
21
+ - [ ] 没有重复实现 DSH 已支持且适用的能力。
22
+ - [ ] 兼容性矩阵和变更日志已更新。
23
+
24
+ ## 安全与隐私
25
+
26
+ - [ ] 已按实际部署拓扑审查威胁模型。
27
+ - [ ] 单用户/多用户 Credential Provider 边界已验证。
28
+ - [ ] 已在预发布环境通过 OIDC 成功和反向符合性测试。
29
+ - [ ] 已通过跨用户/跨 tenant Key Binding 授权测试。
30
+ - [ ] 已测试 API Key 过期、轮换、停用和远程撤销行为。
31
+ - [ ] 已确认 WebServer 仅监听 `127.0.0.1`,没有反向代理、端口转发或隧道把本地会话暴露给其他用户。
32
+ - [ ] 已审查远端 TLS、CSP、Cookie、CSRF、出口、时钟、日志、APM 和备份。
33
+ - [ ] 已完成身份和审计数据的隐私/法律审查。
34
+ - [ ] 当前树与待公开 Git 历史的密钥扫描均未发现生产 host、ID、Key、日志、个人路径或个人数据。
35
+
36
+ ## 供应链
37
+
38
+ - [ ] Windows 和 Linux 上使用 Node 22 完成干净 `npm ci`。
39
+ - [ ] `npm audit` 和静态分析结果经过审查,而不只是执行。
40
+ - [ ] 所有直接/间接许可证和例外已经审查。
41
+ - [ ] npm 安装脚本已经审查,未预期脚本被拒绝。
42
+ - [ ] Lockfile diff 已审查,依赖版本按预期锁定。
43
+ - [ ] 公开发布前,GitHub Actions 已固定到不可变 commit。
44
+
45
+ ## 产品验收
46
+
47
+ - [ ] 纯 Web DSH:登录、callback、显示 name/sub 降级、provision、模型调用、刷新、检查连接和退出。
48
+ - [ ] Native 桌面:现有 ChatECNU Work 体验无回退。
49
+ - [ ] 原生多模态和纯文本 + image-transform 路由均已测试。
50
+ - [ ] 不支持 reasoning effort 的模型仍能启用 thinking 并正常运行。
51
+ - [ ] 已测试失败 UX:Discovery、token、UserInfo、bootstrap、策略拒绝、模型 Key、过期和网络超时。
52
+
53
+ ## 构建与发布
54
+
55
+ - [ ] 在干净 checkout 中通过 `npm run check`。
56
+ - [ ] 已审查 `npm pack --dry-run` 和解压后的 tarball,且只包含预期文件。
57
+ - [ ] Source map 不包含私有绝对路径或秘密。
58
+ - [ ] Tag、发布说明和 checksum 已准备。
59
+ - [ ] npm trusted publishing/provenance 已配置,不使用长期本地 publish token。
60
+ - [ ] 已确认回滚、弃用和漏洞通知计划。
@@ -0,0 +1,138 @@
1
+ # Security model and deployment requirements
2
+
3
+ [简体中文](security-model.md) | **English**
4
+
5
+ ## Assets
6
+
7
+ `dsh-oidc` handles:
8
+
9
+ - OIDC authorization codes, access tokens, refresh tokens, and ID Tokens;
10
+ - stable OIDC subject identifiers and optional display claims;
11
+ - model runtime API keys;
12
+ - organization/provider/model configuration;
13
+ - account and capability state.
14
+
15
+ The organization password is not an asset of this plugin and MUST be entered only into the OIDC Provider.
16
+
17
+ ## Trust boundaries
18
+
19
+ 1. Browser to DSH Host callback/UI.
20
+ 2. DSH Host to OIDC Provider.
21
+ 3. DSH Host to Key Binding service.
22
+ 4. DSH Host to model gateway.
23
+ 5. Plugin to DSH Credential Provider.
24
+ 6. Trusted local executable plugin code versus declarative Enterprise Profile data.
25
+
26
+ The same institution may operate boundaries 2–4, but they remain separate protocol authorities and should use distinct audiences and credentials.
27
+
28
+ ## Security controls in this repository
29
+
30
+ ### OIDC
31
+
32
+ - Authorization Code + PKCE S256 only.
33
+ - Random state, nonce, and verifier.
34
+ - Ten-minute pending-flow expiry and bounded flow count.
35
+ - Fixed callback path and explicit public origin.
36
+ - Duplicate security-parameter rejection.
37
+ - RS256 signature/JWK/issuer/audience/azp/subject/nonce/time validation.
38
+ - `at_hash` validation when supplied.
39
+ - UserInfo `sub` equality with ID Token `sub`.
40
+ - Same-origin-only callback return path.
41
+ - HTTPS remote endpoints; explicit loopback-only HTTP development exception.
42
+ - One MiB maximum for OIDC and Key Binding JSON responses.
43
+
44
+ ### Configuration
45
+
46
+ - Unknown keys rejected.
47
+ - 512 KiB profile bound.
48
+ - No remote adapter/module/tool/skill selection.
49
+ - Fixed Key Binding paths and fields.
50
+ - HTTPS production URLs without embedded credentials/fragments.
51
+ - PNG/WebP-only data logos; no SVG data URL.
52
+ - Only bounded brand token overrides.
53
+
54
+ ### Secrets
55
+
56
+ - Public OIDC client; no client secret.
57
+ - Session and API key written only through DSH Credential Provider.
58
+ - The model adapter resolves the normalized Profile credential reference at request time; deterministic Provider-ID derivation is only the default when none is configured.
59
+ - Separate empty pi-ai auth store prevents ambient credentials shadowing the bound key.
60
+ - Credential response requires exact Provider ID.
61
+ - A native host's reported credential reference must match the Profile, preventing production/test cross-resolution.
62
+ - Logout clears both local session and model key.
63
+
64
+ ## Host assumptions
65
+
66
+ The plugin assumes:
67
+
68
+ - Node.js TLS and DNS trust are correctly administered;
69
+ - DSH plugins and profile files are writable only by trusted administrators;
70
+ - the DSH WebServer listens exactly on `127.0.0.1` and exact `/oauth/callback` routing is not bypassed;
71
+ - the active Credential Provider protects confidentiality and isolates intended users;
72
+ - logs and crash reports do not dump credential values or request bodies;
73
+ - no reverse proxy, port forward, or tunnel exposes the local WebServer to other users;
74
+ - system time is reasonably synchronized.
75
+
76
+ If any assumption fails, the plugin alone cannot restore the security boundary.
77
+
78
+ ## Single-user versus shared Web deployment
79
+
80
+ The Web backend stores one logical OIDC session per profile credential reference. In a local DSH process with a file-backed credential store, that is a **single-user process model**. Multiple browsers reaching the same process could observe or replace the same account state through the shared Host services.
81
+
82
+ The current Web backend therefore forces the DSH WebServer to listen on `127.0.0.1` and rejects both `publicBaseURL` and non-loopback hosts. It MUST NOT be exposed as a shared multi-user service.
83
+
84
+ A shared deployment requires the host—not this plugin—to provide:
85
+
86
+ - authenticated browser sessions;
87
+ - per-user service/request context;
88
+ - per-user Credential Provider namespaces;
89
+ - encrypted storage with rotation and backup policy;
90
+ - Secure, HttpOnly, SameSite cookies;
91
+ - CSRF protection for non-OIDC state-changing actions;
92
+ - tenant/subject isolation tests;
93
+ - session termination and administrator revocation;
94
+ - rate limiting and abuse monitoring.
95
+
96
+ Those capabilities require a future, separate host backend; they are not a reason to relax the current Web backend's loopback check. Until DSH exposes and this project tests those contracts, the supported Web topology is one trusted user per process/profile.
97
+
98
+ ## SSRF and endpoint policy
99
+
100
+ OIDC metadata is remote-controlled after the trusted issuer is configured. The standard permits cross-origin endpoints, so the plugin accepts them only over HTTPS. This prevents an arbitrary network-HTTP downgrade but does not stop a malicious or compromised issuer from naming private HTTPS endpoints.
101
+
102
+ Operators SHOULD apply egress policy so the DSH process can reach only approved identity, Key Binding, and model origins. Cloud deployments SHOULD block metadata-service ranges and internal control planes at the network layer. DNS rebinding protections belong at the HTTP agent/egress proxy layer and are not implemented here.
103
+
104
+ ## Browser security
105
+
106
+ The host SHOULD set a restrictive Content Security Policy. At minimum, review:
107
+
108
+ - `connect-src` for DSH/WebSocket traffic;
109
+ - `img-src` for HTTPS and approved `data:` images;
110
+ - `frame-ancestors 'none'` unless embedding is explicitly intended;
111
+ - `base-uri 'none'` and `object-src 'none'`;
112
+ - `Referrer-Policy: no-referrer` or similarly restrictive policy.
113
+
114
+ Remote brand images can reveal client IP/timing to their host even with no referrer. Package or proxy assets where that is unacceptable.
115
+
116
+ ## Known limitations
117
+
118
+ - RS256 only; no algorithm agility yet.
119
+ - No PAR/JAR/JARM, DPoP, mTLS, or encrypted tokens.
120
+ - No RP-Initiated, front-channel, or back-channel logout.
121
+ - In-memory pending login state is lost on restart and is not cluster-shared.
122
+ - Discovery is cached for the process lifetime; emergency endpoint changes require restart.
123
+ - Native backend security depends on the host `enterpriseAccounts` implementation.
124
+ - Key Binding has no remote credential-revoke operation in v1.
125
+ - Dependency integrity relies on npm lockfile and release controls; the repository does not vendor DSH/pi-ai source.
126
+
127
+ ## Security review checklist for deployments
128
+
129
+ - [ ] Exact issuer, client ID, redirect URI, and audiences approved.
130
+ - [ ] OIDC conformance and negative tests pass.
131
+ - [ ] Key Binding scopes and entitlement checks tested for cross-user/cross-tenant access.
132
+ - [ ] Provider/key mismatch and stale-key revocation tested.
133
+ - [ ] Credential Provider topology matches single-user or isolated multi-user requirements.
134
+ - [ ] Reverse proxy and CSP reviewed.
135
+ - [ ] Secrets absent from application, proxy, APM, and crash logs.
136
+ - [ ] Egress policy blocks unexpected private/metadata destinations.
137
+ - [ ] Dependency lockfile, install scripts, and licenses reviewed.
138
+ - [ ] Incident response contact and remote credential revocation procedure documented.
@@ -0,0 +1,138 @@
1
+ # 安全模型与部署要求
2
+
3
+ **简体中文** | [English](security-model.en.md)
4
+
5
+ ## 资产
6
+
7
+ `dsh-oidc` 会处理:
8
+
9
+ - OIDC authorization code、access token、refresh token 和 ID Token;
10
+ - 稳定 OIDC subject 标识符和可选显示 claim;
11
+ - 模型运行时 API Key;
12
+ - 机构、Provider 和模型配置;
13
+ - 账号与能力状态。
14
+
15
+ 机构密码不属于本插件资产,必须只输入 OIDC Provider。
16
+
17
+ ## 信任边界
18
+
19
+ 1. 浏览器到 DSH Host callback/UI。
20
+ 2. DSH Host 到 OIDC Provider。
21
+ 3. DSH Host 到 Key Binding 服务。
22
+ 4. DSH Host 到模型网关。
23
+ 5. 插件到 DSH Credential Provider。
24
+ 6. 受信任的本地可执行插件代码与声明式 Enterprise Profile 数据之间。
25
+
26
+ 同一机构可以运营第 2–4 项边界,但它们仍是彼此独立的协议权威,应该使用不同 audience 和凭据。
27
+
28
+ ## 本仓库实现的安全控制
29
+
30
+ ### OIDC
31
+
32
+ - 仅使用 Authorization Code + PKCE S256。
33
+ - 随机 state、nonce 和 verifier。
34
+ - 待处理流程十分钟过期,且数量受限。
35
+ - 固定 callback 路径和显式 public origin。
36
+ - 拒绝重复安全参数。
37
+ - 校验 RS256 签名、JWK、issuer、audience、azp、subject、nonce 和时间。
38
+ - 存在 `at_hash` 时校验它。
39
+ - UserInfo `sub` 必须等于 ID Token `sub`。
40
+ - Callback return path 只能同源。
41
+ - 远程 endpoint 必须 HTTPS;只有显式 loopback 开发环境可以使用 HTTP。
42
+ - OIDC 与 Key Binding JSON 响应最大 1 MiB。
43
+
44
+ ### 配置
45
+
46
+ - 拒绝未知字段。
47
+ - Profile 最大 512 KiB。
48
+ - 不允许远程选择 adapter、module、tool 或 Skill。
49
+ - Key Binding 路径和字段固定。
50
+ - 生产 URL 使用 HTTPS,且不得包含凭据或 fragment。
51
+ - Data logo 只允许 PNG/WebP,不允许 SVG。
52
+ - 只覆盖有边界的品牌 token。
53
+
54
+ ### 秘密
55
+
56
+ - 使用 OIDC public client,不使用 client secret。
57
+ - Session 和 API Key 只通过 DSH Credential Provider 写入。
58
+ - 模型 adapter 在请求时解析 Profile 规范化后的凭据引用;未配置时才按 Provider ID 确定性派生。
59
+ - 独立空 pi-ai auth store 防止环境凭据遮蔽已绑定 Key。
60
+ - 凭据响应必须精确匹配 Provider ID。
61
+ - Native 宿主报告的凭据引用必须与 Profile 一致,防止生产/测试环境交叉取 Key。
62
+ - 退出登录会清除本地会话和模型 Key。
63
+
64
+ ## 宿主假设
65
+
66
+ 插件假设:
67
+
68
+ - Node.js TLS 和 DNS 信任得到正确管理;
69
+ - DSH 插件和 Profile 文件只能由受信任管理员写入;
70
+ - DSH WebServer 精确监听 `127.0.0.1`,且 `/oauth/callback` 路由注册不会被绕过;
71
+ - 当前 Credential Provider 能保护机密性,并隔离目标用户;
72
+ - 日志和崩溃报告不会转储凭据值或请求 body;
73
+ - 没有反向代理、端口转发或隧道把本地 WebServer 暴露给其他用户;
74
+ - 系统时间基本同步。
75
+
76
+ 任何假设失效时,插件无法独自恢复安全边界。
77
+
78
+ ## 单用户与共享 Web 部署
79
+
80
+ Web 后端会按 Profile 凭据引用保存一个逻辑 OIDC 会话。在使用文件型凭据存储的本地 DSH 进程中,这属于**单用户进程模型**。访问同一进程的多个浏览器可能通过共用 Host 服务看到或替换同一账号状态。
81
+
82
+ 因此,当前 Web backend 强制 DSH WebServer 监听 `127.0.0.1`,并拒绝 `publicBaseURL` 或非 loopback host。它不得作为共享多用户服务公开。
83
+
84
+ 共享部署要求宿主而不是本插件提供:
85
+
86
+ - 已认证的浏览器 session;
87
+ - 每用户服务/请求上下文;
88
+ - 每用户 Credential Provider 命名空间;
89
+ - 带轮换和备份策略的加密存储;
90
+ - Secure、HttpOnly、SameSite Cookie;
91
+ - 对非 OIDC 状态变更操作的 CSRF 防护;
92
+ - tenant/subject 隔离测试;
93
+ - session 终止和管理员撤销;
94
+ - 限流和滥用监控。
95
+
96
+ 上述能力需要由未来新的宿主 backend 实现;它们不是放宽当前 Web backend loopback 检查的理由。在 DSH 暴露并且本项目验证这些契约前,支持的 Web 拓扑是每个进程/Profile 仅供一名受信任用户使用。
97
+
98
+ ## SSRF 与 endpoint 策略
99
+
100
+ 配置受信任 issuer 后,OIDC 元数据仍由远端控制。标准允许跨 origin endpoint,因此插件仅在 HTTPS 下接受它们。这样可阻止任意网络 HTTP 降级,但不能阻止恶意或已被攻陷的 issuer 指向私有 HTTPS endpoint。
101
+
102
+ 运维方应该实施出口策略,使 DSH 进程只能访问已批准的身份、Key Binding 和模型 origin。云部署应该在网络层阻断 metadata-service 地址段和内部控制面。DNS rebinding 防护属于 HTTP agent/出口代理职责,本插件尚未实现。
103
+
104
+ ## 浏览器安全
105
+
106
+ 宿主应该设置严格 Content Security Policy,至少审查:
107
+
108
+ - `connect-src`:DSH/WebSocket 流量;
109
+ - `img-src`:HTTPS 和批准的 `data:` 图片;
110
+ - `frame-ancestors 'none'`:除非明确需要嵌入;
111
+ - `base-uri 'none'` 和 `object-src 'none'`;
112
+ - `Referrer-Policy: no-referrer` 或同等严格策略。
113
+
114
+ 即便没有 referrer,远程品牌图片仍可能向其宿主暴露客户端 IP 和访问时间。无法接受时,应打包资产或通过受控代理提供。
115
+
116
+ ## 已知限制
117
+
118
+ - 只支持 RS256,尚无算法敏捷性。
119
+ - 不支持 PAR/JAR/JARM、DPoP、mTLS 或加密 token。
120
+ - 不支持 RP-Initiated、front-channel 或 back-channel logout。
121
+ - 进程重启会丢失内存中的待登录状态,且该状态不跨集群共享。
122
+ - Discovery 在进程生命周期内缓存;紧急 endpoint 变更需要重启。
123
+ - Native 后端安全性取决于宿主 `enterpriseAccounts` 实现。
124
+ - Key Binding v1 没有远程凭据撤销操作。
125
+ - 依赖完整性依靠 npm lockfile 和发布控制;仓库不 vendor DSH/pi-ai 源码。
126
+
127
+ ## 部署安全审查清单
128
+
129
+ - [ ] 精确 issuer、client ID、redirect URI 和 audience 已获批准。
130
+ - [ ] OIDC 符合性和反向测试通过。
131
+ - [ ] Key Binding scope 和授权已测试跨用户/跨 tenant 访问。
132
+ - [ ] Provider/Key 不匹配和旧 Key 撤销已测试。
133
+ - [ ] Credential Provider 拓扑符合单用户或隔离多用户要求。
134
+ - [ ] 反向代理和 CSP 已审查。
135
+ - [ ] 应用、代理、APM 和崩溃日志中没有秘密。
136
+ - [ ] 出口策略会阻断意外的私有/metadata 目标。
137
+ - [ ] 依赖 lockfile、安装脚本和许可证已审查。
138
+ - [ ] 事故响应联系人和远程凭据撤销流程已记录。