@monotykamary/dsh-web-identity 0.1.0-rc.7
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/LICENSE +21 -0
- package/README.i18n.yaml +6 -0
- package/README.md +28 -0
- package/README.zh.md +28 -0
- package/lib/index.js +1241 -0
- package/lib/invariant.js +27 -0
- package/lib/types/constants.d.ts +44 -0
- package/lib/types/credential-store.d.ts +46 -0
- package/lib/types/factory.d.ts +17 -0
- package/lib/types/header-provider.d.ts +23 -0
- package/lib/types/index.d.ts +85 -0
- package/lib/types/invariant.d.ts +16 -0
- package/lib/types/login-page.d.ts +14 -0
- package/lib/types/passkey-routes.d.ts +77 -0
- package/lib/types/proxy-allowlist.d.ts +20 -0
- package/lib/types/session-cookie.d.ts +66 -0
- package/lib/types/types.d.ts +170 -0
- package/lib/types/user-store.d.ts +45 -0
- package/package.json +50 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 DeepSeek
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.i18n.yaml
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
|
|
2
|
+
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
|
3
|
+
# after editing either side, bring the other along and re-record with:
|
|
4
|
+
# pnpm run verify-translation-pairing --write packages/identity/web-identity/README.md
|
|
5
|
+
README.md: 052917f13cf3b7d3bcb4b654f34e9a42c74a9f04
|
|
6
|
+
README.zh.md: 5f22bfbd0e7f20ba8d982415659df53ca10d339c
|
package/README.md
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# `@monotykamary/dsh-web-identity`
|
|
2
|
+
|
|
3
|
+
English | [中文](README.zh.md)
|
|
4
|
+
|
|
5
|
+
Web identity authority for `dsh web`: a function plugin that resolves a per-request identity, exposes it as the optional `ctx.identity` service the connection layer gates through, partitions sessions by user, and (for passkey) mounts the `/auth/*` login flow. With no `identity` config the plugin provides nothing and every request is the operator tier — behavior byte-identical to a deployment without this package.
|
|
6
|
+
|
|
7
|
+
Two providers, with the defaults the localterm identity design established:
|
|
8
|
+
|
|
9
|
+
- **`header`** trusts a proxy-set identity header (default `x-forwarded-user`) only from a trusted-proxy source allowlist (default `loopback`). No gate: a trusted-proxy request with no header is the operator tier, so a reverse proxy (Cloudflare Access, Pomerium, Authelia) can front the server without any in-app login.
|
|
10
|
+
- **`passkey`** makes dsh its own identity authority via WebAuthn. A register/login flow under `/auth/passkey/*` issues a signed HMAC session cookie, and the gate rejects unauthenticated `/api` requests and WebSocket upgrades with 401. The operator bearer token — configured, or auto-generated on first boot, persisted in the state directory, and printed once — admits the operator tier from anywhere.
|
|
11
|
+
|
|
12
|
+
Every request admitted as a non-operator user is scoped to that user's partition: `session.list` and search return exactly the user's sessions, every other session-addressing RPC answers `session-not-found` for a cross-tenant id, the mux/host streams carry only the user's frames, and created sessions record the owner durably on the session header so the partition survives restart. The operator tier (owner `null`) sees everything and keeps the privileged method plane; a partitioned user is refused privileged methods even on loopback — the token is how the operator works in passkey mode.
|
|
13
|
+
|
|
14
|
+
The browser half of the connection layer attaches a stored operator token (`localStorage['dsh.operatorToken']`, set by the login page's operator form) as an `Authorization: Bearer` header and redirects to `/auth/passkey/login` on HTTP 401.
|
|
15
|
+
|
|
16
|
+
## Model Experience
|
|
17
|
+
|
|
18
|
+
None, as the package gates HTTP requests and partitions sessions; nothing here reaches a model request.
|
|
19
|
+
|
|
20
|
+
#### KV Cache effect
|
|
21
|
+
|
|
22
|
+
None; this package neither assembles nor sends a provider request.
|
|
23
|
+
|
|
24
|
+
## Known Limitations and Deferred Work
|
|
25
|
+
|
|
26
|
+
- **Workspace live pushes are operator-only** — a partitioned user's workspace picker re-baselines through the filtered `workspace.list` RPC instead of receiving `host/workspace-changed` frames.
|
|
27
|
+
- **Passkeys bind to the RP origin** — a passkey registered on the loopback surface does not work on the tailnet/portless surface and vice versa (inherent to WebAuthn), and `127.0.0.1` is not a registrable RP ID (use `localhost` or a tailnet/portless https origin).
|
|
28
|
+
- **OIDC is deferred** — the provider union covers `header` and `passkey`; an OIDC provider would add a redirect flow over the same signed cookie.
|
package/README.zh.md
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# `@monotykamary/dsh-web-identity`
|
|
2
|
+
|
|
3
|
+
[English](README.md) | 中文
|
|
4
|
+
|
|
5
|
+
`dsh web` 的 Web 身份权威:一个函数插件,为每个请求解析身份,以可选的 `ctx.identity` 服务暴露给连接层做门禁,按用户分区会话,并在 passkey 模式下挂载 `/auth/*` 登录流程。未配置 `identity` 时插件不提供任何服务,每个请求都是运营者层级——行为与不安装本包完全一致。
|
|
6
|
+
|
|
7
|
+
两种提供者,沿用 localterm 身份设计确立的默认值:
|
|
8
|
+
|
|
9
|
+
- **`header`** 只信任来自受信代理来源白名单(默认 `loopback`)的代理身份头(默认 `x-forwarded-user`)。没有门禁:来自受信代理、未带头部的请求即运营者层级,因此反向代理(Cloudflare Access、Pomerium、Authelia)可以直接挡在服务器前面,无需应用内登录。
|
|
10
|
+
- **`passkey`** 让 dsh 通过 WebAuthn 成为自己的身份权威。`/auth/passkey/*` 下的注册/登录流程签发 HMAC 签名会话 Cookie,门禁以 401 拒绝未认证的 `/api` 请求与 WebSocket 升级。运营者 Bearer 令牌——可配置,或首次启动时自动生成、持久化到状态目录并只打印一次——可从任何来源以运营者层级进入。
|
|
11
|
+
|
|
12
|
+
每个以非运营者用户身份放行的请求都被限制在该用户的分区内:`session.list` 与搜索只返回该用户的会话,其他所有按会话寻址的 RPC 对跨租户 id 一律回答 `session-not-found`,mux/host 流只携带该用户的帧,新会话把属主持久化在会话头里,分区跨重启存活。运营者层级(属主 `null`)看到一切并保有特权方法面;分区用户即使在 loopback 上也拿不到特权方法——在 passkey 模式下运营者通过令牌工作。
|
|
13
|
+
|
|
14
|
+
连接层的浏览器半边会把已存储的运营者令牌(`localStorage['dsh.operatorToken']`,由登录页的运营者表单写入)作为 `Authorization: Bearer` 头附加,并在 HTTP 401 时跳转到 `/auth/passkey/login`。
|
|
15
|
+
|
|
16
|
+
## 模型体验
|
|
17
|
+
|
|
18
|
+
无:本包只做 HTTP 门禁与会话分区,没有任何内容进入模型请求。
|
|
19
|
+
|
|
20
|
+
#### KV 缓存影响
|
|
21
|
+
|
|
22
|
+
无:本包既不组装也不发送任何提供者请求。
|
|
23
|
+
|
|
24
|
+
## 已知限制与后续工作
|
|
25
|
+
|
|
26
|
+
- **工作区实时推送仅限运营者** —— 分区用户的工作区选择器通过过滤后的 `workspace.list` RPC 重新建立基线,而不是接收 `host/workspace-changed` 帧。
|
|
27
|
+
- **Passkey 绑定 RP 源** —— 在 loopback 面上注册的 passkey 不能在 tailnet/portless 面上使用,反之亦然(WebAuthn 的固有属性);且 `127.0.0.1` 不是可注册的 RP ID(请用 `localhost` 或 tailnet/portless 的 https 源)。
|
|
28
|
+
- **OIDC 待后续** —— 提供者联合类型目前覆盖 `header` 与 `passkey`;OIDC 提供者将在同一签名 Cookie 之上增加重定向流程。
|