You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Part of #5261 (epic). Prerequisite for the manual DB-wired test — without it you cannot act as director@ vs Bob vs Carol vs engineering@ on localhost, so none of the per-user capability flow is testable by hand.
Redesign (supersedes the env-token approach)
The original cut was an env-var token table (IRONCLAW_REBORN_USER_TOKENS → StaticUserTokenAuthenticator, PR #5286). That is superseded. Users are created through REST — the same admin surface the future UI will drive — not pre-listed in an env var. IRONCLAW_REBORN_USER_TOKENS and StaticUserTokenAuthenticator are removed.
This issue owns identity (users / roles / auth); #5268 owns capability policy (what those users can do). The two are independent admin surfaces on the same gateway.
POST /api/webchat/v2/admin/users{ user_id, role } → create the user; returns { user_id, role, token } (the token is a local-dev affordance so you can "be" that user without SSO).
PUT /api/webchat/v2/admin/users/{user_id}/role{ role } → set/change role (the UI's "role setting").
GET /api/webchat/v2/admin/users → list. DELETE /api/webchat/v2/admin/users/{user_id} → remove.
Dynamic authenticator (ironclaw_reborn_webui_ingress) — resolves a bearer against the user store → WebuiAuthentication{ user_id, role }, layered over the operator EnvBearerAuthenticator (which stays as the bootstrap admin that creates the first users + keeps the SSO signing key / runtime-owner pin). Does not grant operator_webui_config; admin-ness travels via the role.
UI-reusability (by design)
The endpoints live on the canonical WebChat-v2 gateway behind the standard descriptor-driven body/rate-limit + bearer middleware, and the handlers consume an authenticated caller{user, role}agnostic to how auth happened. So the future UI (user-creation + role-setting screens) issues these exact calls; only the authenticator differs (local-dev token vs production session/SSO). Token-minting is decoupled from the user/role semantics so the SSO path reuses create-user + set-role unchanged.
Flow
operator (env-bearer, bootstrap) → POST /admin/users creates director@(Admin) / Bob / Carol / engineering@ → each gets a token → they act with it; director@ grants capabilities via #5268. All durable across restart.
Scope guardrails
Local-dev / standalone only. Production multi-user uses SessionAuthenticator / OidcAuthenticator; this issue does not change that.
The turn-runner already isolates each caller's threads per-turn via ThreadScopeResolver::resolve_for_turn, so multiple users through one process are supported at the scope layer.
Part of #5261 (epic). Prerequisite for the manual DB-wired test — without it you cannot act as
director@vsBobvsCarolvsengineering@on localhost, so none of the per-user capability flow is testable by hand.Redesign (supersedes the env-token approach)
The original cut was an env-var token table (
IRONCLAW_REBORN_USER_TOKENS→StaticUserTokenAuthenticator, PR #5286). That is superseded. Users are created through REST — the same admin surface the future UI will drive — not pre-listed in an env var.IRONCLAW_REBORN_USER_TOKENSandStaticUserTokenAuthenticatorare removed.This issue owns identity (users / roles / auth); #5268 owns capability policy (what those users can do). The two are independent admin surfaces on the same gateway.
What
Durable user store —
user_id → { role, token_hash }plus atoken_hash → user_idindex, persisted over the durable/tenantsmount (survives restart, like the feat(reborn): scoped-lifecycle admin install store (#3288) — availability foundation for #5261 #4544 grants). Tokens stored hashed, never plaintext.Admin REST surface (admin-gated by
WebUiAuthenticatedCaller::is_admin(), the [capability-policy] Reborn DB-backed user role + admin gate (UserRole Owner>Admin>Member) #5266 role) — the durable contract the UI will reuse:POST /api/webchat/v2/admin/users{ user_id, role }→ create the user; returns{ user_id, role, token }(thetokenis a local-dev affordance so you can "be" that user without SSO).PUT /api/webchat/v2/admin/users/{user_id}/role{ role }→ set/change role (the UI's "role setting").GET /api/webchat/v2/admin/users→ list.DELETE /api/webchat/v2/admin/users/{user_id}→ remove.Dynamic authenticator (
ironclaw_reborn_webui_ingress) — resolves a bearer against the user store →WebuiAuthentication{ user_id, role }, layered over the operatorEnvBearerAuthenticator(which stays as the bootstrap admin that creates the first users + keeps the SSO signing key / runtime-owner pin). Does not grantoperator_webui_config; admin-ness travels via the role.UI-reusability (by design)
The endpoints live on the canonical WebChat-v2 gateway behind the standard descriptor-driven body/rate-limit + bearer middleware, and the handlers consume an authenticated
caller{user, role}agnostic to how auth happened. So the future UI (user-creation + role-setting screens) issues these exact calls; only the authenticator differs (local-dev token vs production session/SSO). Token-minting is decoupled from the user/role semantics so the SSO path reuses create-user + set-role unchanged.Flow
operator (env-bearer, bootstrap) →
POST /admin/userscreatesdirector@(Admin) /Bob/Carol/engineering@→ each gets a token → they act with it;director@grants capabilities via #5268. All durable across restart.Scope guardrails
SessionAuthenticator/OidcAuthenticator; this issue does not change that.ThreadScopeResolver::resolve_for_turn, so multiple users through one process are supported at the scope layer.Depends on: #5266 (the
UserRoleon the caller).