docs(techstack): add Identity & auth section
Document the auth/identity subsystem: crypto-only (scrypt + TOTP MFA), opaque sliding sessions over cookie/bearer/query transports, rotating native refresh tokens, BizGaze IdP + signed SSO, roles & tenancy, bzc_ API keys, server-side directory search, and the audit log. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
5f755fbf6c
commit
7ec6c3f227
1 file changed
+42
-1
+42
-1
@@ -1,6 +1,6 @@
|
|||||||
# Tech Stack — BizGaze Connect
|
# Tech Stack — BizGaze Connect
|
||||||
|
|
||||||
> Living document. **Last updated: 2026-10-27.** Update this file whenever a dependency, platform, service, or
|
> Living document. **Last updated: 2026-10-27** (rev 2). Update this file whenever a dependency, platform, service, or
|
||||||
> tool is added/removed/version-bumped. See [Maintaining this file](#maintaining-this-file) and the
|
> tool is added/removed/version-bumped. See [Maintaining this file](#maintaining-this-file) and the
|
||||||
> [Changelog](#changelog) at the bottom.
|
> [Changelog](#changelog) at the bottom.
|
||||||
|
|
||||||
@@ -38,6 +38,45 @@ file access). Real-time via WebSockets; meeting media via WebRTC (P2P mesh, or L
|
|||||||
- **Cache / pub-sub:** **Redis 7** (`redis` `^4.7`) for cross-instance real-time fan-out (chat/presence) —
|
- **Cache / pub-sub:** **Redis 7** (`redis` `^4.7`) for cross-instance real-time fan-out (chat/presence) —
|
||||||
**optional**, only when `PUBSUB_BACKEND=redis`; default is in-memory single-instance (`pubsub.js`).
|
**optional**, only when `PUBSUB_BACKEND=redis`; default is in-memory single-instance (`pubsub.js`).
|
||||||
|
|
||||||
|
## Identity & auth
|
||||||
|
|
||||||
|
No external auth library — Node's built-in **`crypto`** only (`server/auth.js`): scrypt password hashing (64-byte
|
||||||
|
hash, per-user salt, timing-safe compare), opaque random session tokens, SHA-256-hashed token storage, and
|
||||||
|
**TOTP MFA** (RFC 6238, SHA-1, 30s, 6 digits) with `otpauth://` enrollment URLs.
|
||||||
|
|
||||||
|
- **Sessions** (`sessions_auth` table, resolved in `server/session.js`): one opaque bearer token accepted over
|
||||||
|
three transports — a `sid` **HttpOnly cookie** (web), `Authorization: Bearer <token>` (native desktop/mobile
|
||||||
|
+ WS upgrade), or a `?access_token=`/`?token=` query param (browser WS fallback). **90-day TTL, sliding** —
|
||||||
|
any `/api/me` hit re-stamps the cookie and pushes the expiry out, so active users stay signed in indefinitely
|
||||||
|
and only lapse after 90 days of no use (or logout).
|
||||||
|
- **Native refresh tokens** (`refresh_tokens`): 90-day, one-time-use **with rotation**, stored only as a hash;
|
||||||
|
`POST /api/auth/refresh` swaps a refresh token for a fresh access token so mobile/desktop never re-prompt for
|
||||||
|
a password.
|
||||||
|
- **MFA:** optional TOTP second factor. A `requireMfa` gate in `currentUser` holds a session back until
|
||||||
|
`mfa_passed`; flow is `/api/mfa/setup` (secret/QR) → `/api/mfa/enable` (confirm) → `/api/login/mfa` (step-2
|
||||||
|
code).
|
||||||
|
- **Identity providers:**
|
||||||
|
- **Local password** accounts — dev/test and self-contained runs.
|
||||||
|
- **BizGaze as IdP** (`server/bizgaze.js`, active when `BIZGAZE_LOGIN_URL` is set): credentials are verified
|
||||||
|
against BizGaze's `ValidateAndLogin` and BizGaze becomes the **sole authority** (local passwords rejected
|
||||||
|
unless `ALLOW_LOCAL_LOGIN=1`). A local user row is provisioned/synced (name, avatar, role, tenant) on every
|
||||||
|
login, keyed on the **BizGaze person-id** (not the typed email/phone) so signing in with either identifier
|
||||||
|
resolves to one account — legacy duplicates are auto-merged.
|
||||||
|
- **BizGaze SSO** (`GET /sso`): an HMAC-SHA256-signed, time-boxed token (`SSO_SECRET`) signs an agent straight
|
||||||
|
in (auto-provisioning the user) and redirects to `/connect`.
|
||||||
|
- **Roles & tenancy:** every user belongs to a **team (tenant)**; roles are **`admin` / `technician` / `viewer`**
|
||||||
|
(default `technician`). Admins manage members (`/api/users`, `/api/users/manage`: add / reset-password /
|
||||||
|
rename / activate / deactivate / delete) and see tenant-wide views. Role is synced from BizGaze `isAdmin` each
|
||||||
|
login; `ADMIN_EMAILS` is a lockout safety-net.
|
||||||
|
- **Registration** (`POST /api/register`): first run creates the team + admin user; closed afterward unless
|
||||||
|
`ALLOW_REGISTRATION=1`.
|
||||||
|
- **Third-party API keys** (`api_keys`, `apiKeyFromReq`): `bzc_`-prefixed, stored hashed, comma-scoped (`*` =
|
||||||
|
all), presented via `X-API-Key` or `Authorization: Bearer bzc_…` — for the roadmap's 3rd-party integration.
|
||||||
|
- **Directory search** (`server/directory.js`, `/api/directory/search`): server-side BizGaze cross-tenant user
|
||||||
|
lookup; the directory auth token stays **server-side** and is never exposed to the browser.
|
||||||
|
- **Audit log** (`audit_log`): logins, SSO/BizGaze provisioning, account merges, and every admin action on a
|
||||||
|
member are recorded.
|
||||||
|
|
||||||
## Real-time & media
|
## Real-time & media
|
||||||
|
|
||||||
- **WebRTC** for calls/meetings: built-in **P2P mesh** by default; **LiveKit SFU** when configured.
|
- **WebRTC** for calls/meetings: built-in **P2P mesh** by default; **LiveKit SFU** when configured.
|
||||||
@@ -155,4 +194,6 @@ Bump the **Last updated** date at the top and add a line to the Changelog below.
|
|||||||
|
|
||||||
## Changelog
|
## Changelog
|
||||||
|
|
||||||
|
- **2026-10-27 (rev 2)** — Added the **Identity & auth** section (sessions/cookies + bearer, refresh tokens,
|
||||||
|
TOTP MFA, BizGaze IdP/SSO, roles & tenancy, API keys, directory, audit).
|
||||||
- **2026-10-27** — Initial tech-stack document created.
|
- **2026-10-27** — Initial tech-stack document created.
|
||||||
Reference in new issue
Block a user