Skip to content

feat(auth): add advanced authentication system#4931

Merged
qinxuye merged 15 commits into
mainfrom
feat/advanced-auth
May 20, 2026
Merged

feat(auth): add advanced authentication system#4931
qinxuye merged 15 commits into
mainfrom
feat/advanced-auth

Conversation

@m199369309
Copy link
Copy Markdown
Collaborator

@m199369309 m199369309 commented May 20, 2026

Summary

  • Adds an optional advanced authentication mode (XINFERENCE_AUTH_ADVANCED=1) as an alternative to the existing file-based auth config
  • JWT-based auth with refresh tokens (rotation on use), encrypted API key management with per-model access control, user management with admin/user roles, and password change enforcement
  • Backend: new xinference/api/oauth2/advanced/ module with SQLite storage, crypto utilities, and xinference-migrate-auth CLI
  • Frontend: user management, API key management, and change password pages with refresh token rotation support

Configuration

Set these environment variables to enable:

XINFERENCE_AUTH_ADVANCED=1
XINFERENCE_AUTH_JWT_SECRET_KEY=<your-secret>
XINFERENCE_AUTH_ENCRYPTION_KEY=<your-encryption-key>
XINFERENCE_AUTH_DB_PATH=<optional, defaults to ~/.xinference/auth/auth.db>

Changes

Backend

  • xinference/api/oauth2/advanced/ — Full auth module (auth_service, database, cache, crypto, migrate, routes)
  • xinference/constants.py — New env var constants for advanced auth
  • xinference/api/restful_api.py — Advanced auth initialization, model access control (_check_model_access)
  • xinference/api/routers/admin.py — Conditional /token route, auth_advanced in UI config
  • setup.cfgxinference-migrate-auth entry point

Frontend

  • fetchWrapper.js — Refresh token mechanism with token rotation support
  • MenuSide.js — User management, API key management, logout menu items
  • router/index.js — Routes for new pages
  • New pages: change_password/, apikey_management/, user_management/
  • login.js — Refresh token + must-change-password handling
  • locales/ — i18n strings for new features

Security Improvements (code review feedback)

  • Initial admin password output to console only (no plain-text file)
  • API keys for non-existent users default to disabled
  • Refresh token rotation: old token invalidated on use, new token issued
  • AES-GCM decryption failures handled gracefully
  • list_users N+1 query optimized to batch fetch
  • update_user allows setting nullable fields to NULL

Test plan

  • Verify existing file-based auth still works when XINFERENCE_AUTH_ADVANCED is not set
  • Enable advanced auth and test login/logout/refresh token rotation flow
  • Test API key creation, listing, deletion, and per-model access restrictions
  • Test user management (create, update roles, password reset)
  • Test xinference-migrate-auth CLI tool
  • Verify mutual exclusion error when both --auth-config and XINFERENCE_AUTH_ADVANCED are set
  • Verify refresh token rotation: after refresh, old token rejected, new token works

m199369309 and others added 10 commits May 15, 2026 19:01
…ighting

- Refactor DetailRow to three-column table (Action/Field/Value) with Table/JSON tabs
- Add fieldFilters state with backend `filters` query parameter support
- Implement HighlightText multi-keyword support with two-layer highlighting
- Add collapsed row Level/Node column highlighting
- Sync Level/LogType chip selections with DetailRow highlighting
- Add i18n keys for DetailRow component

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Add copy button to DetailRow JSON tab with ContentCopy/Check icons
- Implement copyToClipboard with navigator.clipboard + execCommand fallback for HTTP
- Show copied feedback with 1.5s auto-reset and tooltip
- Add useEffect cleanup for timer to prevent stale setState
- Add i18n keys: copyJson, copied

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Add backend GET /v1/cluster/logs/context endpoint with older/newer dual ES queries
- Add ContextDialog component with editable load count and newest-first ordering
- Support row expansion in ContextDialog reusing DetailRow component
- Isolate ContextDialog filter state from main page filters
- Support anchor switching within dialog (replaces nested dialogs)
- Add DetailRow onViewContext prop for custom "view surrounding documents" behavior
- Add i18n keys for context dialog UI

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Add Enter key support on load count TextField to trigger loading
- Add filter chips bar in ContextDialog showing active local filters
- Implement filterRows for client-side data filtering (OR within same key, AND across keys)
- Anchor row always visible regardless of filter state

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Use OR (terms/bool.should) for same-field filters instead of AND
- Parallelize context API ES queries with asyncio.gather
- Sort highlight keywords by length descending to prevent partial matches
- Fix prettier formatting for index.js

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Change filters parameter from comma-delimited string to list[str] via Query([])
- Frontend uses params.append instead of params.set with join(',')
- Fixes data loss when filter values contain commas (e.g. message fields)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…d user management

Introduces an optional advanced authentication mode (XINFERENCE_AUTH_ADVANCED=1) that provides:
- JWT-based authentication with refresh tokens
- Encrypted API key management with per-model access control
- User management with role-based permissions (admin/user)
- Password change enforcement for first-time login
- SQLite-backed user/key storage with migration CLI tool
- Frontend: user management, API key management, and password change pages

This is an alternative to the existing file-based auth config, activated via
environment variables. Both modes are mutually exclusive.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@XprobeBot XprobeBot added this to the v2.x milestone May 20, 2026
Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a comprehensive advanced authentication system for Xinference, moving from a static JSON configuration to a dynamic SQLite-backed architecture. The new system supports JWT-based authentication, refresh tokens, and granular management of users and API keys with model-level access controls. Significant updates were made to both the backend services and the web UI to accommodate these features, including a new migration utility for existing setups. Review feedback highlights several critical security and performance improvements, such as avoiding plain-text storage of initial admin credentials, implementing refresh token rotation, handling cryptographic exceptions more robustly, and optimizing database queries to prevent N+1 performance issues.

Comment thread xinference/api/oauth2/advanced/auth_service.py Outdated
Comment thread xinference/api/oauth2/advanced/auth_service.py Outdated
Comment thread xinference/api/oauth2/advanced/auth_service.py Outdated
Comment thread xinference/api/oauth2/advanced/crypto.py Outdated
Comment thread xinference/api/oauth2/advanced/database.py
Comment thread xinference/api/oauth2/advanced/database.py
m199369309 and others added 4 commits May 20, 2026 18:03
Remove unused imports (Tuple, Any, Dict, List, Depends), fix type
annotations to satisfy mypy strict checks, and add None guards for
optional dict values.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Remove plain-text admin credential file, output to console only
- Default user_enabled to 0 (disabled) for non-existent users
- Implement refresh token rotation (invalidate on use, return new token)
- Catch AES-GCM decryption failures gracefully (return None)
- Optimize list_users to batch-fetch permissions (fix N+1 query)
- Allow update_user to set nullable fields to NULL

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@qinxuye qinxuye left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed current head b31bf04. I skipped the existing Gemini findings and only added non-duplicate issues. One additional blocker: the current lint check fails at the Prettier step for src/components/MenuSide.js, src/scenes/apikey_management/index.js, and src/scenes/user_management/index.js.

Comment thread xinference/api/oauth2/advanced/routes.py
Comment thread xinference/ui/web/ui/src/components/MenuSide.js
…ke token on logout

- create_api_key: non-admin users can only create keys for themselves
- list_api_keys: non-admin users can only see their own keys
- get_api_key: non-admin users can only view their own keys
- Logout now clears refresh_token from sessionStorage and calls
  /v1/auth/logout to revoke it server-side (best-effort)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@qinxuye qinxuye left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@qinxuye qinxuye merged commit 9a3d1b0 into main May 20, 2026
10 of 13 checks passed
@qinxuye qinxuye deleted the feat/advanced-auth branch May 20, 2026 13:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants