Login UX and Identity Provider Gap v1¶
As of: April 14, 2026
Purpose¶
Define the target login screen direction and the platform gaps for supporting GitHub, Google, and Hugging Face sign-in.
This is a product and architecture planning document. It does not replace the
current auth contracts in doc/api/openapi.draft.yaml.
Current Implementation¶
The current /auth/login screen is implemented as a single-pane sign-in card:
- Primary SSO:
- optional work email or tenant slug hint,
Continue with SSOthroughGET /api/v1/auth/oidc/authorize,- optional
Continue with SAMLwhenNEXT_PUBLIC_AUTH_SAML_ENABLED=true. - Social provider shortcuts:
- GitHub and Hugging Face are enabled by default unless explicitly disabled,
- Google is available when
NEXT_PUBLIC_AUTH_SOCIAL_GOOGLE_ENABLED=true, - provider buttons use
provider_hinton the OIDC authorize endpoint and Keycloak broker routing remains server-side. - Password login:
- hidden behind
Use password instead, - controlled by
NEXT_PUBLIC_AUTH_PERSONAL_ENABLED, - platform-control/release image builds default this flag to
false, - local kind/dev builds keep it enabled for bootstrap and test users.
- Rate-limit state:
429usesRetry-After.- Error state:
- mapped through canonical API error handling and preserves correlation data.
Current feature flags:
NEXT_PUBLIC_AUTH_PERSONAL_ENABLED- controls whether personal username/password controls are shown.
NEXT_PUBLIC_AUTH_SAML_ENABLED- controls whether the SAML button is shown.
NEXT_PUBLIC_AUTH_SOCIAL_GITHUB_ENABLED- controls whether the GitHub shortcut is shown; default is enabled.
NEXT_PUBLIC_AUTH_SOCIAL_HUGGINGFACE_ENABLED- controls whether the Hugging Face shortcut is shown; default is enabled.
NEXT_PUBLIC_AUTH_SOCIAL_GOOGLE_ENABLED- controls whether the Google shortcut is shown; default is disabled.
Target UX Direction¶
Move login to a single-pane screen.
The screen should make the recommended production path obvious while keeping dev/personal login available only when enabled.
Primary Layout¶
Sign in to GPUaaS
Access GPU workspaces, notebooks, clusters, and inference apps.
[ Email or workspace __________________________ ]
[ Continue ]
or
[ Continue with SSO ]
[ GitHub ] [ Google ] [ Hugging Face ] only when enabled
Use password instead only when personal/dev login enabled
Need access? Contact your workspace admin or platform support.
Visual Direction¶
Use GPUaaS styling, not a generic consumer-login clone:
- one centered card,
- subdued infrastructure/cloud background,
- strong primary blue action,
- compact provider buttons,
- no tab strip by default,
- support and access guidance in the footer,
- clear rate-limit and correlation-id error states.
Interaction Model¶
- User enters email or workspace.
Continuedecides which advisory hint to send:- email address ->
identity_hint, - workspace/tenant slug ->
tenant_hint. - Server remains authoritative for tenant/provider resolution.
- If password login is enabled,
Use password insteadexpands the personal username/password form inside the same card. - If signup is enabled, show
Don't have access? Request accessorSign up, depending on product policy.
Do not show signup as a default affordance unless self-service account creation is intentionally enabled for the environment.
Signup Product Decision¶
The existing personal signup API creates a personal tenant and default project. That is useful for dev and possible self-service users, but it is not the same as enterprise workspace access.
Before showing Sign up broadly, decide:
- Is public self-service signup allowed?
- Does signup create a personal tenant or request access to an existing tenant?
- Does signup require email verification?
- Does signup require billing setup before provisioning?
- Is personal signup disabled in platform-control/prod by default?
Recommended first production behavior:
- show
Need access? Contact your workspace admin, - keep personal signup hidden unless explicitly enabled,
- add an access-request flow later if tenant admins should approve users.
Provider Support Options¶
There are two viable implementation models.
Option A: Broker Providers Through Keycloak¶
Keycloak owns GitHub, Google, Hugging Face, and other social/provider integrations. GPUaaS continues to use the existing OIDC authorize/exchange flow.
Benefits:
- smallest GPUaaS API change,
- Keycloak handles provider-specific OAuth/OIDC details,
- centralized callback and client secret configuration,
- compatible with current JWT/JWKS validation path.
Required GPUaaS work:
- decide whether provider buttons map to Keycloak
kc_idp_hintor equivalent, - add a safe API contract for provider hinting instead of browser-building Keycloak URLs directly,
- bind callback state to provider hint,
- map brokered identities to local users,
- define account-linking and duplicate-email behavior,
- audit provider selected, resolved issuer, and local user binding.
Option B: GPUaaS Owns Provider Integrations¶
GPUaaS adds first-class /auth/social/* or provider-aware authorize endpoints.
Benefits:
- full control over provider-specific UX and policy,
- less dependency on Keycloak identity-broker behavior,
- easier to enforce GPUaaS-specific account-linking rules in one place.
Costs:
- more API surface,
- provider-specific OAuth client management in GPUaaS,
- more security review,
- more callback and token-validation code,
- more operational secret management.
Recommendation:
Start with Option A through Keycloak brokering, but make the GPUaaS API the public contract. The browser should call GPUaaS, not construct provider URLs or Keycloak-specific hints directly.
Provider-Specific Notes¶
Google¶
Google can be:
- enterprise Google Workspace federation,
- consumer/social Google sign-in.
For enterprise Google Workspace, use tenant federation and verified domain binding. For consumer Google sign-in, require explicit account-linking or self-service personal signup policy.
GitHub¶
GitHub is usually social/developer identity, not tenant federation by default.
Before enabling GitHub, decide:
- Is GitHub sign-in only for personal tenants?
- Can tenant admins allowlist GitHub organizations or teams?
- Is GitHub email verification required?
- What happens when GitHub returns a private email or multiple emails?
- Can a GitHub identity link to an existing enterprise account?
Do not grant project access from GitHub org/team membership until that is an explicit contract with audit and tenant-admin control.
Hugging Face¶
Hugging Face is the better default third provider for GPUaaS because users are likely to bring model identities, model repositories, gated-model access, and inference workflows.
Hugging Face sign-in should still be treated as identity only:
- signing in with Hugging Face does not grant GPUaaS project access by itself,
- model access tokens are separate runtime secrets, not login credentials,
- private or gated model access must be explicitly requested through a runtime secret binding flow,
- Hugging Face organization membership should not map to GPUaaS tenant access until tenant admins opt into that policy,
- verified email and account-linking rules still apply.
Recommended first behavior:
- show
Continue with Hugging Faceonly after provider discovery reports it, - request only identity scopes needed for login first,
- add model/token scopes later as part of a separate runtime-secret feature,
- never store user Hugging Face tokens in app profile config or launch params.
Microsoft¶
Microsoft should not be a default social button for GPUaaS. Treat Microsoft as enterprise SSO unless a specific product decision is made to support consumer Microsoft accounts.
Enterprise Microsoft Entra ID should be modeled as tenant federation:
- tenant admin configures Entra ID OIDC or SAML,
- tenant domain binding resolves the tenant,
- membership or invite gates authorization,
- no implicit access is granted just because the user has a Microsoft identity.
If consumer Microsoft sign-in is added later, it should follow the same account-linking and personal-tenant policy as Google/GitHub.
Contract Gaps¶
Current OpenAPI already defines:
GET /api/v1/auth/oidc/authorize,POST /api/v1/auth/oidc/exchange,GET /api/v1/auth/saml/authorize,POST /api/v1/auth/saml/callback,POST /api/v1/auth/personal/login,POST /api/v1/auth/personal/signup.
Needed before social/provider buttons are production:
- Provider hint contract.
- Add a server-validated query field such as
provider_hint. - Allowed values should be server-configured, for example
sso,github,google,huggingface. - Do not let the browser pass arbitrary IdP aliases.
- Provider discovery/read model.
- UI needs to know which buttons to show per environment or tenant.
- Candidate endpoint:
GET /api/v1/auth/providers. - Account-linking model.
- Store provider issuer/name, subject, verified email, and link state.
- Prevent silent takeover when email matches an existing local user.
- Signup/request-access policy.
- Separate personal login from personal signup.
- Add environment and policy controls for whether public signup is visible.
- Invite or membership gate.
- Enterprise federation and social login authenticate identity only.
- Authorization still requires tenant/project membership or approved invite.
- Error taxonomy.
- Existing codes may be enough for MVP, but product copy needs specific details for no provider, no membership, account already linked, and signup disabled cases.
- Audit events.
- Log provider selected, provider resolved, link created, link failed, membership denied, and signup created.
Data Model Gaps¶
The current users model has OIDC issuer/subject fields, but multi-provider
identity linking needs a separate table.
Recommended table direction:
user_identity_links (
id uuid primary key,
user_id uuid not null references users(id),
provider_type text not null,
provider_name text not null,
issuer text null,
subject text not null,
email text null,
email_verified boolean not null default false,
link_state text not null,
created_at timestamptz not null default now(),
updated_at timestamptz not null default now(),
deleted_at timestamptz null
)
Required constraints:
- unique active provider identity:
(provider_name, subject), - no automatic merge by email alone,
- soft-delete for audit continuity.
Security Requirements¶
- Callback state remains opaque, single-use, TTL-limited, and provider-bound.
- Provider hints are advisory and server-validated.
- Issuer and audience validation are exact-match.
- Social sign-in cannot bypass membership or invite checks.
- Account linking requires proof of current session or approved invite.
- Provider secrets live in Vault or encrypted provider config.
- Query-string auth tokens remain prohibited.
- Login errors must avoid account enumeration.
Updated Login Screen Acceptance Criteria¶
- Production default shows a single card, not Work/Personal tabs.
- The primary field accepts email or workspace slug.
- Continue with email sends
identity_hint. - Continue with workspace slug sends
tenant_hint. - Provider buttons appear only when the API reports them enabled.
- Password login is collapsed behind
Use password insteadand appears only when personal/dev auth is enabled. - Signup is hidden unless signup policy explicitly enables it.
- Rate-limit, provider resolution failure, no-membership, and callback failure states render actionable copy.
- Correlation ID is shown when the API returns one.
- Existing callback/session behavior remains unchanged.
Recommended Execution Plan¶
Phase 1: UX-only simplification¶
- Replace tabs with one centered card.
- Keep current OIDC/SAML/personal APIs.
- Collapse password login behind
Use password instead. - Hide signup unless a new frontend flag enables it.
- Do not show GitHub/Google/Hugging Face buttons yet.
Phase 2: Provider discovery and button rendering¶
- Add contract for provider discovery.
- Add provider hint to authorize contract.
- Wire buttons to GPUaaS authorize endpoint with provider hint.
- Keep Keycloak as provider broker behind GPUaaS.
Phase 3: Account linking and signup policy¶
- Add identity-link data model.
- Add explicit account-linking rules.
- Add invite/request-access flow.
- Add tenant-admin controls for allowed providers.
Phase 4: Enterprise federation maturity¶
- Finish tenant federation admin UX.
- Support Microsoft Entra ID and Google Workspace as tenant IdPs.
- Add verified domain binding UX.
- Add runbooks and audit surfaces for auth failures.
Open Questions¶
- Should platform-control allow personal signup at all?
- Should GitHub/Google/Hugging Face create personal tenants, or only link to invited users?
- Should provider availability be global, tenant-specific, or both?
- Should Hugging Face login unlock any model-developer experience directly, or should model repository/token access remain a separate app runtime feature?
- Do we need password reset UX, or should password login remain dev-only?
- Do tenant admins need an access-request queue before self-service signup is exposed?
- Should Microsoft ever be shown as a social provider, or only as tenant SSO
through labels like
Continue with your work account?
Related Docs¶
doc/product/ux-mocks/user-auth.mddoc/product/UX_Implementation_Spec.mddoc/architecture/Tenant_Federation_SSO_Model.mddoc/architecture/Platform_IAM_Model_v1.mddoc/api/openapi.draft.yaml- Hugging Face Hub OAuth docs:
https://huggingface.co/docs/hub/oauth - Hugging Face Hub Spaces OAuth docs:
https://huggingface.co/docs/hub/spaces-oauth