oclaw/uds-auth/README.md
oliver df97c5e042
Some checks are pending
ci / test (push) Waiting to run
ci / test-postgresql (push) Waiting to run
fix(uds-auth): emergency login workspaces, Desktop key prompts, persistent sessions
Emergency (fallback / sealed-box) admins lost the workspace sidebar and saw
"sign-in failed / add API key" on DSH Desktop because the remote.mux opens
anonymously at boot and every early call was rejected terminally.

- gateway: anonymous workspace/follow reaches dsh-acl's empty baseline;
  anonymous streams are parked until the carrier aborts instead of failing;
  anonymous workspace/initializeDefault answers "nothing created"
- request-auth: a dead UDS_SESSION cookie no longer shadows a valid WS ticket
  or bridge (sync + async variants used by all callers)
- dsh-acl: /api/* waits (bounded 15s) for the gateway ACL during Host startup
  instead of 403, so the Desktop welcome read no longer fails
- desktop-bootstrap: key/account projection is best-effort per reference
- client: emit connection/reset after login so boot-time caches (settings
  describe mirror -> Settings > Models) re-read under the real principal
- sessions: absolute lifetime fixed at 7 days (was min(ttl, 7d) = 30 min);
  bridge expiry slides with its session; MemoryStore persisted to
  sessions.json (bearer hash only, userData AES-256-GCM sealed)
- README: session lifetime/persistence and DSH compatibility notes

Also includes previously uncommitted uds-auth 0.3.x work in this tree.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 02:11:09 +08:00

84 lines
4.7 KiB
Markdown

# uds-auth
0.3.10: [升级与协议变更说明](docs/upgrade-0.3.10.zh.md) · [SBOM](docs/sbom.cdx.json) · [第三方许可证](docs/THIRD-PARTY-NOTICES.txt)
UDS authentication plugin for DeepSeek Harness (**trusted single-instance** access control — **not** strong multi-tenant isolation).
See `package.json` for the current 0.3.x version (breaking auth protocol vs 0.2.x — re-login required).
## Support boundary
| Item | Notes |
|------|--------|
| Runtime | Node `^22.19.0 \|\| >=24` (aligned with DSH Host) |
| Mode | Single Host, trusted enterprise users, controlled skills |
| Out of scope | Untrusted multi-tenant execution isolation; multi-instance without shared session store |
## Install
```bash
dsh plugin --profile web add -w "<abs>/oclaw/uds-auth"
# or clean tarball
dsh plugin add -w "<abs>/uds-auth-0.3.9.tgz"
```
Empty roles table requires `UDS_AUTH_INITIAL_ADMIN` or `initialAdminEmpNo`. Restart Harness after install.
`ctx.get('udsAuth').runAsHost(cb)` — Host background ALS.
`ctx.get('udsAuth').mintTaskCapability({ empNo, dshSessionId, scopes, ttlSeconds })` — inject `UDS_TASK_CAPABILITY` for cron/skill.
## Config
```yaml
uacBaseUrl: https://uac.zte.com.cn # HTTPS required at startup/merge
userSearchUrl: https://icenterapi.zte.com.cn/...
loginSystemCode: '100000455558'
initialAdminEmpNo: ''
allowOpenRegistration: true
allowRawAgentToken: false
outboundAllowedHosts: icenterapi.zte.com.cn,icentermsg.dt.zte.com.cn
trustedHosts: '' # empty = loopback Host only; proxies must set allowlist
retainSkillCredentialsOnLogout: true
skillCredentialTtlSeconds: 604800
```
Durable state defaults to `~/.uds-auth/` (roles / owners / credentials / bridge / sessions / `config.runtime.json`; override with `UDS_AUTH_DATA_DIR`). Security toggles take effect on the next request after Settings save. Empty outbound allowlist denies all.
## Sessions
- **Lifetime**: 30-minute idle timeout that slides on activity, 7-day absolute cap. The Desktop bridge token slides with its session.
- **Survives restarts**: the default in-memory store is persisted to `~/.uds-auth/sessions.json` and restored on Host start (emergency admins have no SSO re-login, so they depend on this).
- Only the SHA-256 hash of each session token is stored; user data (may include the UAC token) is AES-256-GCM encrypted with the plugin key `.uds-auth-secret-key`.
- Expired, undecryptable or tampered rows are dropped on load; disabled-account and emergency-password rotation checks still run on every request.
- **Delete `sessions.json` and restart to sign everyone out.** If the key file is unavailable, sessions are simply not persisted.
- Not used when a Redis session store is configured.
## Admin / emergency
- `super_admin` / `admin` / `fallback_admin` share the same admin-class permissions (identity labels, not stronger isolation).
- No shared default password. Set emergency password in Settings (≥10 chars; `Admin@123` rejected). Legacy default hashes are cleared on upgrade.
- Local unlock: `node scripts/seal-local-admin.mjs` (interactive / `--stdin` — **no argv passphrase**) → `UDS_AUTH_LOCAL_ADMIN_BOX`.
- Removing a user disables the account by default (open registration cannot auto-revive).
## DSH compatibility
Verified on **DeepSeek Harness Desktop 0.2.0-rc.2**. The plugin relies on DSH internals that are not a public API; after a DSH upgrade run `npm test` and check login, workspaces and Settings → Models on a real install:
- Gateway `prepareInvocation` / `resolveDescriptor` / `openRemoteEvents` / `receiveRemoteEventResult` (if missing, the ACL refuses to install instead of failing open);
- the client `connection/reset` event (emitted after login so boot-time caches such as the settings mirror re-read);
- endpoint names `workspace/follow`, `workspace/initializeDefault`, and the Desktop welcome reads `settings/describe`, `llm/listConfigurableProviders`, `credentials/describe`, `account/getState`.
Desktop opens its connection anonymously at boot and reconnects after login. The plugin therefore:
- parks anonymous stream calls (e.g. account state) without data instead of failing them (a failure is terminal for DSH and shows "sign-in failed / add API key");
- answers anonymous `workspace/follow` with an empty list and anonymous `workspace/initializeDefault` with "nothing created";
- holds `/api/*` requests for up to 15 s while the gateway ACL is still installing, instead of returning 403.
## Skill / cron
Prefer Host-minted `UDS_TASK_CAPABILITY` + `DSH_SESSION_ID` with `/uds-auth/outbound`. Raw `/agent-credentials` stays off unless explicitly enabled. Python helper: `skill-helpers/python/uds_skill_auth.py`.
Chinese docs: [README.zh.md](README.zh.md), [docs/skill-auth-standard.zh.md](docs/skill-auth-standard.zh.md).
## License
MIT