Skip to content

Conversation

Copy link

Copilot AI commented Jan 21, 2026

Summary

Production-readiness for multiuser support: JWT secret now stored in database with cryptographically secure generation, multiuser mode gated behind config flag (default off), and reduced log noise. Frontend now properly bypasses authentication in single-user mode. Model manager UI visibility fixed to work correctly in both single-user and multiuser modes.

JWT Secret Management

  • Migration 27: adds app_settings table for app-level configuration
  • JWT secret generated once during migration (256-bit entropy via secrets.token_hex(32))
  • AppSettingsService manages persistent key-value storage
  • token_service.py refactored: module-level secret initialized at startup from database

Multiuser Configuration

  • New config field: multiuser (default: false)
  • Backend: Added multiuser_enabled field to /auth/status endpoint response
  • Single-user mode (default):
    • System user elevated to admin with full privileges
    • Frontend bypasses all authentication, no login screen shown
    • Auth endpoints (/auth/login, /auth/setup) return 403
    • Direct access to app without credentials
    • Model manager UI fully accessible
  • Multi-user mode (multiuser: true):
    • Full authentication flow enabled
    • Login screen shown, user credentials required
    • User data isolation enforced
    • Model manager UI restricted to admins

Example usage in invokeai.yaml:

# Enable multiuser support
multiuser: true

Frontend Authentication Handling

  • SetupChecker component checks multiuser_enabled field and routes directly to app when disabled
  • ProtectedRoute component allows access without authentication in single-user mode
  • TypeScript schema updated to include multiuser_enabled field

Model Manager UI Visibility

  • Created useIsModelManagerEnabled hook that checks multiuser status and user permissions
  • Model manager UI for adding, deleting, and modifying models now:
    • Visible in single-user mode (default)
    • Hidden in multiuser mode for non-admin users
    • Visible in multiuser mode for admin users
  • Updated all model manager components (ModelManager, ModelPane, ModelView, ModelHeader, ModelListBulkActions, and all default settings components) to use the new hook

Logging

  • Session queue isolation messages downgraded from info to debug in sockets.py

Test Updates

  • Updated auth test fixtures to enable multiuser mode for testing
  • Fixed regression in test_security.py, test_auth.py, test_boards_multiuser.py, and test_client_state_multiuser.py
  • Tests now properly validate authentication behavior in multiuser mode

Related Issues / Discussions

N/A

QA Instructions

Test single-user mode (default):

  1. Start InvokeAI without config changes (or with multiuser: false)
  2. Verify frontend goes directly to app without showing login screen
  3. Verify system user has admin privileges
  4. Verify /auth/login and /auth/setup return 403
  5. Verify model manager UI is fully accessible (add, delete, modify models)

Test multi-user mode:

  1. Set multiuser: true in invokeai.yaml
  2. Restart and verify login screen is shown
  3. Verify initial admin setup works if no admin exists
  4. Create additional users and verify authentication
  5. Verify user data isolation
  6. Login as admin user and verify model manager UI is accessible
  7. Login as non-admin user and verify model manager UI is hidden

Test migration:

  1. Run with existing database - migration 27 should execute
  2. Verify JWT secret exists in app_settings table
  3. Verify tokens work correctly after migration

Merge Plan

N/A - migration 27 is additive and backward compatible

Checklist

  • The PR has a short but descriptive title, suitable for a changelog
  • Tests added / updated (if applicable)
  • ❗Changes to a redux slice have a corresponding migration
  • Documentation added / updated (if applicable)
  • Updated What's New copy (if doing a release after this PR)
Original prompt

This section details on the original issue you should resolve

<issue_title>[enhancement]: Make multiuser support ready for production</issue_title>
<issue_description>### Is there an existing issue for this?

  • I have searched the existing issues

Contact Details

No response

What should this feature add?

To make the multiuser feature ready for production, the following changes need to be implemented:

  1. Authorization token key - Currently the key used to generate JWT tokens is hard coded. Instead, it should be generated randomly at the time of database schema creation or migration and stored safely in the InvokeAI database.
  2. Configuration option to enable multiuser support - By default, multiuser features should not be active. InvokeAI should not ask for login credentials, and should use a default account with Administrator privileges. I believe there is already an account used for legacy behavior called system. To enable multiuser support, the user must add the InvokeAI configuration option multiuser: true (default false) to invokeai.yaml.
  3. Debugging log messages which were added to support session queue isolation (in commit 6ae8a74) should be converted from info log level to debug log level.

Alternatives

No response

Additional Content

No response</issue_description>

Comments on the Issue (you are @copilot in this section)


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI and others added 5 commits January 21, 2026 05:32
Co-authored-by: lstein <111189+lstein@users.noreply.github.com>
Co-authored-by: lstein <111189+lstein@users.noreply.github.com>
Co-authored-by: lstein <111189+lstein@users.noreply.github.com>
Co-authored-by: lstein <111189+lstein@users.noreply.github.com>
Co-authored-by: lstein <111189+lstein@users.noreply.github.com>
Copilot AI changed the title [WIP] Enhance multiuser support for production readiness feat: make multiuser support production-ready Jan 21, 2026
Copilot AI requested a review from lstein January 21, 2026 05:45
@lstein
Copy link
Owner

lstein commented Jan 21, 2026

@copilot The frontend is still asking for my login credentials, even when multiuser is absent from the config file and the backend is running on an in-memory database which has no users or credentials. When I enter credentials, the message "Multiuser mode is disabled. Authentication is not required in single-user mode." appears, which is correct. However, the system does not allow me to access the generation or gallery pages.

@lstein
Copy link
Owner

lstein commented Jan 21, 2026

@copilot There are a few python regression test errors:

TestSessionSecurity.test_logout_invalidates_session ______________

self = <auth.test_security.TestSessionSecurity object at 0x7fad28cd3110>
monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7fad28b482d0>
mock_invoker = <invokeai.app.services.invoker.Invoker object at 0x7fad2855bd10>
client = <starlette.testclient.TestClient object at 0x7fad2850b410>

    def test_logout_invalidates_session(self, monkeypatch: Any, mock_invoker: Invoker, client: TestClient):
        """Test that logout invalidates the session.
    
        Note: Current implementation uses JWT which is stateless.
        This test documents expected behavior for future server-side session tracking.
        """
        monkeypatch.setattr("invokeai.app.api.routers.auth.ApiDependencies", MockApiDependencies(mock_invoker))
        monkeypatch.setattr("invokeai.app.api.auth_dependencies.ApiDependencies", MockApiDependencies(mock_invoker))
    
        # Create user and login
        setup_test_user(mock_invoker, "test@example.com", "TestPass123")
    
        login_response = client.post(
            "/api/v1/auth/login",
            json={
                "email": "test@example.com",
                "password": "TestPass123",
                "remember_me": False,
            },
        )
    
>       token = login_response.json()["token"]
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
E       KeyError: 'token'

Here's another:


mock_invoker = <invokeai.app.services.invoker.Invoker object at 0x7fad282034d0>
client = <starlette.testclient.TestClient object at 0x7fad28211790>
monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7fad28008ad0>
email = 'user1@example.com', password = 'TestPass123', is_admin = False

    def create_user_and_login(
        mock_invoker: Invoker, client: TestClient, monkeypatch: Any, email: str, password: str, is_admin: bool = False
    ) -> tuple[str, str]:
        """Helper to create a user, login, and return (user_id, token)."""
        monkeypatch.setattr("invokeai.app.api.routers.auth.ApiDependencies", MockApiDependencies(mock_invoker))
        monkeypatch.setattr("invokeai.app.api.auth_dependencies.ApiDependencies", MockApiDependencies(mock_invoker))
    
        user_service = mock_invoker.services.users
        user_data = UserCreateRequest(
            email=email,
            display_name=f"User {email}",
            ***
            is_admin=is_admin,
        )
        user = user_service.create(user_data)
    
        # Login to get token
        response = client.post(
            "/api/v1/auth/login",
            json={
                "email": email,
                "password": password,
                "remember_me": False,
            },
        )
    
>       assert response.status_code == 200
E       assert 403 == 200
E        +  where 403 = <Response [403 Forbidden]>.status_code

tests/app/services/auth/test_data_isolation.py:64: AssertionError

Co-authored-by: lstein <111189+lstein@users.noreply.github.com>
Copy link
Author

Copilot AI commented Jan 21, 2026

@copilot The frontend is still asking for my login credentials, even when multiuser is absent from the config file and the backend is running on an in-memory database which has no users or credentia...

Fixed in commit 3c5ee94. The frontend now checks the multiuser_enabled field from the /auth/status endpoint and bypasses all authentication when multiuser mode is disabled (default). The app will now go directly to the main interface without showing the login screen in single-user mode.

Auth tests were failing because the login and setup endpoints now return 403 when multiuser mode is disabled (the default). Updated test fixtures to enable multiuser mode for all auth-related tests.

Co-authored-by: lstein <111189+lstein@users.noreply.github.com>
Copy link
Author

Copilot AI commented Jan 21, 2026

@copilot There are a few python regression test errors:

TestSessionSecurity.test_logout_invalidates_session ______________

...

Fixed in commit 61b0379. The test failures were caused by my changes blocking /auth/login and /auth/setup endpoints when multiuser: false (the default). Updated all auth test fixtures to enable multiuser mode before running tests.

Copy link
Owner

@lstein lstein left a comment

Choose a reason for hiding this comment

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

@copilot When not running in multiuser mode, the model manager UI for adding, deleting and modifying models is hidden. The desired behavior is for this UI to be available when running in legacy single user mode, for it to be hidden in multiuser mode when an unprivileged user is logged in, and for it to be available when running in multiuser mode and an Administrator is logged in.

Model manager UI for adding, deleting and modifying models is now:
- Visible in single-user mode (multiuser: false, the default)
- Hidden in multiuser mode for non-admin users
- Visible in multiuser mode for admin users

Created useIsModelManagerEnabled hook that checks multiuser_enabled status
and returns true when multiuser is disabled OR when user is admin.

Updated all model manager components to use this hook instead of direct
is_admin checks.

Co-authored-by: lstein <111189+lstein@users.noreply.github.com>
Copy link
Author

Copilot AI commented Jan 21, 2026

@copilot When not running in multiuser mode, the model manager UI for adding, deleting and modifying models is hidden. The desired behavior is for this UI to be available when running in legacy single...

Fixed in commit 0ba2924. Created a useIsModelManagerEnabled hook that checks if multiuser mode is disabled (returns true for single-user mode) or if the user is an admin (returns true in multiuser mode). Updated all model manager components to use this hook. Model manager UI is now:

  • Visible in single-user mode (default)
  • Hidden for non-admin users in multiuser mode
  • Visible for admin users in multiuser mode

Copilot AI requested a review from lstein January 21, 2026 17:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[enhancement]: Make multiuser support ready for production

2 participants