Skip to content

Conversation

Copy link

Copilot AI commented Jan 7, 2026

Summary

Implements Phase 2 of the multiuser feature per docs/multiuser/implementation_plan.md. Adds JWT-based authentication layer on top of Phase 1's database schema and auth utilities.

New Components:

  • Authentication Dependencies (auth_dependencies.py): FastAPI dependency functions for JWT token validation and admin enforcement
  • Auth Router (routers/auth.py): REST endpoints for login, logout, user info, and initial admin setup
  • Service Integration: Wires user service into InvocationServices and ApiDependencies
  • Custom Email Validation: Allows special-use domains (.local, .test, localhost) for testing/development while maintaining validation for production domains

API Endpoints:

POST /api/v1/auth/setup   - Create initial admin (one-time, no auth)
POST /api/v1/auth/login   - Authenticate, returns JWT token
POST /api/v1/auth/logout  - Logout (no-op for stateless JWT)
GET  /api/v1/auth/me      - Get current user info

Usage Example:

from invokeai.app.api.auth_dependencies import CurrentUser, AdminUser

@router.get("/protected")
async def protected_endpoint(current_user: CurrentUser):
    # current_user: TokenData with user_id, email, is_admin
    pass

@router.post("/admin-only")
async def admin_endpoint(admin_user: AdminUser):
    # Automatically enforces admin privileges (403 if not admin)
    pass

Security:

  • Bcrypt password hashing with strength validation (8+ chars, uppercase, lowercase, digits)
  • JWT tokens signed with HMAC-SHA256, configurable expiration (1 day / 7 days)
  • Bearer token authentication via HTTP Authorization header
  • User existence and active status validated on each request
  • Custom email validation accepts special-use domains for testing while maintaining security

Email Validation:
The implementation includes a custom email validator (validate_email_with_special_domains()) that:

  • Accepts special-use domains like .local, .test, and localhost for testing/development
  • Uses standard email-validator library for production domains (e.g., @example.com)
  • Falls back to basic syntax validation for special-use domains
  • Still rejects malformed emails (no @, empty parts, etc.)

Bug Fixes:

  • Fixed email validation to accept special-use domains (.local, .test, localhost) for testing
  • Fixed system user in migration_25 to NOT be admin (is_admin = FALSE), allowing /auth/setup to work on fresh databases. The system user is only for backward compatibility with pre-existing data.

⚠️ Production Note: SECRET_KEY in token_service.py is hardcoded for development. Move to secure configuration before production deployment.

Related Issues / Discussions

Implements Phase 2 of multiuser implementation plan as specified in docs/multiuser/implementation_plan.md

QA Instructions

Quick Test:

  1. Start server with in-memory DB:

    python -m invokeai.app.run_app --use_memory_db
  2. Create initial admin (now works with .local domains and fresh databases):

    curl -X POST http://localhost:9090/api/v1/auth/setup \
      -H "Content-Type: application/json" \
      -d '{"email":"admin@test.local","display_name":"Admin","password":"Admin123!"}'
  3. Login to get token:

    curl -X POST http://localhost:9090/api/v1/auth/login \
      -H "Content-Type: application/json" \
      -d '{"email":"admin@test.local","password":"Admin123!","remember_me":false}'
  4. Use token for authenticated requests:

    curl -X GET http://localhost:9090/api/v1/auth/me \
      -H "Authorization: Bearer <token>"

Expected Behavior:

  • Setup succeeds on fresh database (no "Administrator account already configured" error)
  • Setup accepts emails with special-use domains like admin@test.local
  • Login returns token with correct expiration
  • Authenticated endpoints work with valid token

Merge Plan

No special considerations. Database migration runs automatically on startup. The system user fix ensures fresh installations can create their first admin user properly.

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]: Implement Phase 2 of multiuser implementation plan</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?

This feature should implement Phase 2 of the multiuser feature implementation plan described in docs/multiuser/implementation_plan.md

Alternatives

No response

Additional Content

In the PR notes, please describe how to test the functionality of this feature.</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 2 commits January 7, 2026 03:56
…ervice integration

Co-authored-by: lstein <111189+lstein@users.noreply.github.com>
…rove documentation

Co-authored-by: lstein <111189+lstein@users.noreply.github.com>
Copilot AI changed the title [WIP] Implement Phase 2 of multiuser implementation plan Implement Phase 2: Authentication Service with JWT and FastAPI Integration Jan 7, 2026
Copilot AI requested a review from lstein January 7, 2026 04:05
@lstein
Copy link
Owner

lstein commented Jan 8, 2026

@copilot
Bug: when the /auth/setup endpoint is used with the email admin@test.local, I get this error:

{"detail":[{"type":"value_error","loc":["body","email"],"msg":"value is not a valid email address: The part after the @-sign is a special-use or reserved name that cannot be used with email.","input":"admin@test.local","ctx":{"reason":"The part after the @-sign is a special-use or reserved name that cannot be used with email."}}]}

…ting

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

Copilot AI commented Jan 8, 2026

@copilot
Bug: when the /auth/setup endpoint is used with the email admin@test.local, I get this error:

...

Fixed in commit fe5b447. The email validator now accepts special-use domains like .local, .test, and localhost for testing/development purposes while still validating email syntax for malformed addresses.

The validator works by:

  1. First attempting standard email validation for production domains (e.g., @example.com)
  2. If that fails due to special-use domains, falling back to basic syntax validation
  3. Accepting domains with dots (like .local, .test) or localhost
  4. Rejecting truly malformed emails (no @, empty parts, etc.)

You can now use admin@test.local successfully with the /auth/setup endpoint.

@lstein
Copy link
Owner

lstein commented Jan 8, 2026

@copilot When I call the /auth/setup endpoint, I now get the message "Administrator account already configured". This happens on a fresh restart using an in-memory sql database.

… database

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

Copilot AI commented Jan 8, 2026

@copilot When I call the /auth/setup endpoint, I now get the message "Administrator account already configured". This happens on a fresh restart using an in-memory sql database.

Fixed in commit 5dffaeb. The system user created during migration was incorrectly set as an admin (is_admin = TRUE), which caused has_admin() to return true even on fresh databases, blocking the initial setup.

Changed the system user to is_admin = FALSE. The system user is only for backward compatibility with existing data from before multi-user support - it should not be an admin. Real admin users are created through /auth/setup.

The /auth/setup endpoint now works correctly on fresh in-memory databases.

@lstein
Copy link
Owner

lstein commented Jan 8, 2026

@copilot There doesn't seem to be any endpoint for creating non-admin users. Is this coming in Phase 3?

Copy link
Author

Copilot AI commented Jan 8, 2026

@copilot There doesn't seem to be any endpoint for creating non-admin users. Is this coming in Phase 3?

Correct - Phase 2 focuses on the core authentication infrastructure (login, logout, token validation) and initial admin setup. User management endpoints (creating/updating/deleting users, managing invitations) are not explicitly detailed in the implementation plan but would typically be added in a subsequent phase.

The database schema already includes a user_invitations table (from migration_25), so the backend is ready for it. For a complete multiuser system, you'd typically add:

Admin-only user management endpoints:

  • POST /api/v1/users - Create new user (admin only)
  • GET /api/v1/users - List all users (admin only)
  • PUT /api/v1/users/{user_id} - Update user (admin only)
  • DELETE /api/v1/users/{user_id} - Delete user (admin only)
  • POST /api/v1/invitations - Create invitation (admin only)

Self-service endpoints:

  • GET /api/v1/invitations/{code} - Validate invitation
  • POST /api/v1/users/register - Register with invitation code

These would logically fit after Phase 3 (when authentication is required on endpoints) and before Phase 5 (frontend development). The users service already has create(), update(), delete(), and list_users() methods implemented, so it's mainly a matter of adding the API routes with proper AdminUser dependencies.

@lstein lstein marked this pull request as ready for review January 8, 2026 04:32
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.

Tested endpoints and working as advertised.
Code reviewed.

@lstein lstein merged commit 48232a2 into lstein-master Jan 8, 2026
7 of 13 checks passed
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]: Implement Phase 2 of multiuser implementation plan

2 participants