Unified Authentication ====================== The unified authentication system seamlessly handles both JWT and API tokens through a single interface. .. contents:: Table of Contents :local: :depth: 2 Core Implementation ------------------- From ``auth/unified_auth.py``: .. literalinclude:: ../../../ccat_ops_db_api/auth/unified_auth.py :language: python :lines: 1-50 Token Detection and Validation ------------------------------- The system automatically detects and validates token types: .. code-block:: python async def get_current_user( request: Request, credentials: HTTPAuthorizationCredentials = Depends(security), db: Session = Depends(get_db) ) -> User: token = credentials.credentials # Try JWT first user = verify_jwt_token(token, db) if user: request.state.token_type = "jwt" return user # Try API token result = verify_api_token(token, db, request) if result: user, api_token = result request.state.token_type = "api" request.state.api_token = api_token return user raise AuthenticationError() Using in Endpoints ------------------ **Standard authentication** (JWT or API tokens): .. code-block:: python from ccat_ops_db_api.auth import get_current_user, require_roles, require_permissions @router.get("/protected") async def protected_endpoint( current_user: User = Depends(get_current_user) ): return {"user": current_user.username} @router.post("/admin-only") @require_roles("admin") async def admin_endpoint( current_user: User = Depends(get_current_user) ): return {"message": "Admin access granted"} @router.get("/observations") @require_permissions("read:observations") async def get_observations( current_user: User = Depends(get_current_user) ): # Permission check validates token scopes for API tokens # or role permissions for JWT tokens ... **Service account only** (API tokens with service role): .. code-block:: python from ccat_ops_db_api.auth import get_service_user, require_service_token @router.post("/executed_obs_units/start") @require_service_token async def start_observation( data: ObsUnitCreate, current_user: User = Depends(get_service_user) ): # Only service account tokens accepted # JWT tokens will be rejected ... Next Steps ---------- * :doc:`github-oauth` - OAuth implementation * :doc:`api-tokens` - API token management * :doc:`roles-permissions` - RBAC system