gaurav0107 opened a new pull request, #65685: URL: https://github.com/apache/airflow/pull/65685
## Summary Closes #60897. The FastAPI API server's auth gate rejected anonymous users with 401 even when `AUTH_ROLE_PUBLIC` was set in `webserver_config.py`, because the gate only consulted Flask's config. The Flask legacy webserver honored it; FastAPI did not. ## Approach Per @jason810496's proposal (endorsed by @vincbeck in the issue thread): 1. New `[fab] auth_role_public` Airflow config — the canonical source going forward. 2. New `BaseAuthManager.get_public_user()` hook (returns `None` by default). 3. `FabAuthManager.get_public_user()` resolves the configured role, builds an `AnonymousUser` with `_roles`/`_perms` pre-populated inside `app_context()`, and returns it. 4. `resolve_user_from_token()` in the FastAPI security layer consults `auth_manager.get_public_user()` before raising 401. 5. Startup bridge in `providers/fab/www/app.py` copies `[fab] auth_role_public` into Flask's `AUTH_ROLE_PUBLIC` so the legacy webserver's existing code paths stay in sync — no behavior change for users on `webserver_config.py` only. ### Why the `AnonymousUser._roles` direct-write? FAB's `AnonymousUser.roles` is a lazy property that calls `security_manager.get_public_role()` on every access, which requires a Flask request context. `get_public_user()` runs under FastAPI where there is no request context, so we build the user inside a brief `app_context()`, resolve permissions eagerly, and write them directly to `_roles`/`_perms` to freeze the snapshot. This is the minimum surface needed to avoid touching FAB's property implementation while keeping the call safe outside Flask. ## Type of change - [x] Bug fix (non-breaking change which fixes an issue) ## Testing - 28 new tests added in \`airflow-core/tests/unit/api_fastapi/core_api/test_security.py\` - 84 new tests added in \`providers/fab/tests/unit/fab/auth_manager/test_fab_auth_manager.py\` - Covers: happy path, unknown role name, precedence between \`[fab] auth_role_public\` and legacy \`AUTH_ROLE_PUBLIC\`, interaction with the existing bearer-token path, edge cases for FastAPI-without-Flask-request - Full suite: 476 targeted auth tests pass. \`ruff check\` and \`ruff format\` pass. ## Backwards compatibility Users relying on \`AUTH_ROLE_PUBLIC = \"Admin\"\` in \`webserver_config.py\` continue to work unchanged — the Flask webserver keeps consulting that value, and the FastAPI gate now also honors it via the startup bridge. cc @vincbeck @jason810496 🤖 Generated with [Claude Code](https://claude.com/claude-code) -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
