shashank-iitbhu opened a new issue, #73232:
URL: https://github.com/apache/airflow/issues/73232

   ### Under which category would you file this issue?
   
   Providers
   
   ### Apache Airflow version / provider version
   
   Apache Airflow 3.3.0 with `apache-airflow-providers-keycloak==0.8.1`. The 
same `_is_authorized` 400 path is still present on provider **0.10.0** and on 
`main`.
   
   ### What happened and how to reproduce it?
   
   **Issue Description**
   
   `POST /auth/token` with `client_credentials` returns an Airflow JWT whose 
`exp` follows `[api_auth] jwt_expiration_time` (default 24h). The Keycloak 
access token nested in that session still expires on Keycloak’s 
`accessTokenLifespan` (often 1h). Service-account tokens have no refresh token 
(`refresh_user` returns `None`).
   
   After the inner Keycloak bearer expires, API calls such as `POST 
/api/v2/dags/{dag_id}/dagRuns` still present a valid Airflow JWT. Authorization 
then calls Keycloak’s UMA ticket grant 
(`grant_type=urn:ietf:params:oauth:grant-type:uma-ticket`) with that expired 
bearer.
   
   Keycloak answers **HTTP 400**:
   
   ```json
   {"error":"invalid_grant","error_description":"Invalid bearer token"}
   ```
   
   `KeycloakAuthManager._is_authorized` only maps:
   
   - 401 → `False` ([#59281](https://github.com/apache/airflow/pull/59281))
   - 403 → `False`
   - 400 `invalid_resource` on a team resource → `False` 
([#69028](https://github.com/apache/airflow/pull/69028))
   
   Any other 400, including `invalid_grant`, does:
   
   ```python
   raise AirflowException(
       f"Request not recognized by Keycloak. {error.get('error')}. 
{error.get('error_description')}"
   )
   ```
   
   Starlette/FastAPI turns that unhandled exception into **HTTP 500**. Clients 
that remint only on 401/403 keep retrying the dead token and stay in a 500 loop 
until they mint a new Airflow JWT.
   
   This is distinct from 
[#59359](https://github.com/apache/airflow/issues/59359) / 
[#59361](https://github.com/apache/airflow/pull/59361) (UI `refresh_user` when 
the *refresh* token is dead) and from 
[#59277](https://github.com/apache/airflow/issues/59277) (401 path only). 
Keycloak often returns **400**, not 401, for this UMA grant.
   
   **Steps to reproduce**
   
   1. Configure Airflow 3.3+ with `KeycloakAuthManager`.
   2. Set Keycloak client/realm `accessTokenLifespan` shorter than `[api_auth] 
jwt_expiration_time` (e.g. 60s vs 24h).
   3. `POST /auth/token` with `grant_type=client_credentials`.
   4. Wait until the Keycloak access token expires but the Airflow JWT is still 
valid.
   5. `POST /api/v2/dags/{dag_id}/dagRuns` with `Authorization: Bearer 
<airflow-jwt>`.
   
   Observed: API 500, api-server log `AirflowException: Request not recognized 
by Keycloak. invalid_grant. Invalid bearer token`. Keycloak event 
`PERMISSION_TOKEN_ERROR` / `invalid_token` on `uma-ticket`.
   
   Still true on current `main` in `_is_authorized` / `_is_batch_authorized`:
   
   
https://github.com/apache/airflow/blob/main/providers/keycloak/src/airflow/providers/keycloak/auth_manager/keycloak_auth_manager.py
   
   ### What you think should happen instead?
   
   Treat UMA `400 invalid_grant` the same as `401`: deny (`return False` / 
empty set) so the API returns **403** (or 401), not 500. Callers can then 
remint.
   
   Refreshing/reminting the nested Keycloak token for `client_credentials` 
would be a larger follow-up. Mapping `invalid_grant` to unauthorized is the 
same class of fix as [#59281](https://github.com/apache/airflow/pull/59281).
   
   ### Operating System
   
   Linux (Kubernetes)
   
   ### Deployment
   
   Official Apache Airflow Helm Chart
   
   ### Apache Airflow Provider(s)
   
   keycloak
   
   ### Versions of Apache Airflow Providers
   
   `apache-airflow-providers-keycloak==0.8.1` (also unfixed in 0.10.0 and 
`main`)
   
   ### Official Helm Chart version
   
   Not Applicable
   
   ### Kubernetes Version
   
   Not Applicable
   
   ### Helm Chart configuration
   
   Not Applicable
   
   ### Docker Image customizations
   
   Not Applicable
   
   ### Anything else?
   
   Related:
   
   - [#59277](https://github.com/apache/airflow/issues/59277) / 
[#59281](https://github.com/apache/airflow/pull/59281) — 401 → 403; does not 
cover Keycloak 400 `invalid_grant`
   - [#56614](https://github.com/apache/airflow/issues/56614) — UI 500 on 
expired access token
   - [#59359](https://github.com/apache/airflow/issues/59359) — `refresh_user` 
`KeycloakPostError` on dead refresh token
   - [#69028](https://github.com/apache/airflow/pull/69028) — 400 
`invalid_resource` only
   
   I am submitting a PR that maps `invalid_grant` to deny in `_is_authorized` 
and `_is_batch_authorized`.
   
   ### Are you willing to submit PR?
   
   - [x] Yes I am willing to submit a PR!
   
   ### Code of Conduct
   
   - [x] I agree to follow this project's [Code of 
Conduct](https://github.com/apache/airflow/blob/main/CODE_OF_CONDUCT.md)


-- 
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]

Reply via email to