proposal: migrate to external API authentication

Create OpenSpec proposal for migrating from local database authentication
to external API authentication using Microsoft Azure AD.

Changes proposed:
- Replace local username/password auth with external API
- Integrate with https://pj-auth-api.vercel.app/api/auth/login
- Use Azure AD tokens instead of local JWT
- Display user 'name' from API response in UI
- Maintain backward compatibility with feature flag

Benefits:
- Single Sign-On (SSO) capability
- Leverage enterprise identity management
- Reduce local user management overhead
- Consistent authentication across applications

Database changes:
- Add external_user_id for Azure AD user mapping
- Add display_name for UI display
- Keep existing schema for rollback capability

Implementation includes:
- Detailed migration plan with phased rollout
- Comprehensive task list for implementation
- Test script for API validation
- Risk assessment and mitigation strategies

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
egg
2025-11-14 15:14:48 +08:00
parent b048f2d640
commit 28e419f5fa
3 changed files with 577 additions and 0 deletions

View File

@@ -0,0 +1,171 @@
# Change: Migrate to External API Authentication
## Why
The current local database authentication system has several limitations:
- User credentials are managed locally, requiring manual user creation and password management
- No centralized authentication with enterprise identity systems
- Cannot leverage existing enterprise authentication infrastructure (e.g., Microsoft Azure AD)
- No single sign-on (SSO) capability
- Increased maintenance overhead for user management
By migrating to the external API authentication service at https://pj-auth-api.vercel.app, the system will:
- Integrate with enterprise Microsoft Azure AD authentication
- Enable single sign-on (SSO) for users
- Eliminate local password management
- Leverage existing enterprise user management and security policies
- Reduce maintenance overhead
- Provide consistent authentication across multiple applications
## What Changes
### Authentication Flow
- **Current**: Local database authentication using username/password stored in MySQL
- **New**: External API authentication via POST to `https://pj-auth-api.vercel.app/api/auth/login`
- **Token Management**: Use JWT tokens from external API instead of locally generated tokens
- **User Display**: Use `name` field from API response for user display instead of local username
### API Integration
**Endpoint**: `POST https://pj-auth-api.vercel.app/api/auth/login`
**Request Format**:
```json
{
"username": "user@domain.com",
"password": "user_password"
}
```
**Success Response (200)**:
```json
{
"success": true,
"message": "認證成功",
"data": {
"access_token": "eyJ0eXAiOiJKV1Q...",
"id_token": "eyJ0eXAiOiJKV1Q...",
"expires_in": 4999,
"token_type": "Bearer",
"userInfo": {
"id": "42cf0b98-f598-47dd-ae2a-f33803f87d41",
"name": "ymirliu 劉念萱",
"email": "ymirliu@panjit.com.tw",
"jobTitle": null,
"officeLocation": "高雄",
"businessPhones": ["1580"]
},
"issuedAt": "2025-11-14T07:09:15.203Z",
"expiresAt": "2025-11-14T08:32:34.203Z"
},
"timestamp": "2025-11-14T07:09:15.203Z"
}
```
**Failure Response (401)**:
```json
{
"success": false,
"error": "用戶名或密碼錯誤",
"code": "INVALID_CREDENTIALS",
"timestamp": "2025-11-14T07:10:02.585Z"
}
```
### Database Schema Changes
- **users table modifications**:
- Remove/deprecate `hashed_password` column (keep for rollback)
- Add `external_user_id` (VARCHAR 255) - Store Azure AD user ID
- Add `display_name` (VARCHAR 255) - Store user display name from API
- Add `azure_email` (VARCHAR 255) - Store Azure AD email
- Add `last_token_refresh` (DATETIME) - Track token refresh timing
- Keep `username` for backward compatibility (can be email)
### Session Management
- Store external API tokens in session/cache instead of local JWT
- Implement token refresh mechanism based on `expires_in` field
- Use `expiresAt` timestamp for token expiration validation
## Impact
### Affected Capabilities
- `authentication`: Complete replacement of authentication mechanism
- `user-management`: Simplified to read-only user information from external API
- `session-management`: Modified to handle external tokens
### Affected Code
- **Backend Authentication**:
- `backend/app/api/v1/endpoints/auth.py`: Replace login logic with external API call
- `backend/app/core/security.py`: Modify token validation to use external tokens
- `backend/app/core/auth.py`: Update authentication dependencies
- `backend/app/services/auth_service.py`: New service for external API integration
- **Database Models**:
- `backend/app/models/user.py`: Update User model with new fields
- `backend/alembic/versions/`: New migration for schema changes
- **Frontend**:
- `frontend/src/services/authService.ts`: Update to handle new token format
- `frontend/src/stores/authStore.ts`: Modify to store/display user info from API
- `frontend/src/components/Header.tsx`: Display `name` field instead of username
### Dependencies
- Add `httpx` or `aiohttp` for async HTTP requests to external API (already present)
- No new package dependencies required
### Configuration
- New environment variables:
- `EXTERNAL_AUTH_API_URL` = "https://pj-auth-api.vercel.app"
- `EXTERNAL_AUTH_ENDPOINT` = "/api/auth/login"
- `EXTERNAL_AUTH_TIMEOUT` = 30 (seconds)
- `USE_EXTERNAL_AUTH` = true (feature flag for gradual rollout)
- `TOKEN_REFRESH_BUFFER` = 300 (refresh tokens 5 minutes before expiry)
### Security Considerations
- HTTPS required for all authentication requests
- Token storage must be secure (HTTPOnly cookies or secure session storage)
- Implement rate limiting for authentication attempts
- Log all authentication events for audit trail
- Validate SSL certificates for external API calls
- Handle network failures gracefully with appropriate error messages
### Rollback Strategy
- Keep existing authentication code with feature flag
- Maintain password column in database (don't drop immediately)
- Implement dual authentication mode during transition:
- If `USE_EXTERNAL_AUTH=true`: Use external API
- If `USE_EXTERNAL_AUTH=false`: Use local authentication
- Provide migration script to sync existing users with external system
### Migration Plan
1. **Phase 1**: Implement external API authentication alongside existing system
2. **Phase 2**: Test with subset of users (based on domain or user flag)
3. **Phase 3**: Gradual rollout to all users
4. **Phase 4**: Deprecate local authentication (keep code for emergency)
5. **Phase 5**: Remove local authentication code (after stable period)
## Risks and Mitigations
### Risks
1. **External API Unavailability**: Authentication service downtime blocks all logins
- *Mitigation*: Implement fallback to local auth, cache tokens, implement retry logic
2. **Token Expiration Handling**: Users may be logged out unexpectedly
- *Mitigation*: Implement automatic token refresh before expiration
3. **Network Latency**: Slower authentication due to external API calls
- *Mitigation*: Implement proper timeout handling, async requests, response caching
4. **Data Consistency**: User information mismatch between local DB and external system
- *Mitigation*: Regular sync jobs, use external system as single source of truth
5. **Breaking Change**: Existing sessions will be invalidated
- *Mitigation*: Provide migration window, clear communication to users
## Success Criteria
- All users can authenticate via external API
- Authentication response time < 2 seconds (95th percentile)
- Zero data loss during migration
- Automatic token refresh works without user intervention
- Proper error messages for all failure scenarios
- Audit logs capture all authentication events
- Rollback procedure tested and documented