y-sudharshan opened a new pull request, #61283:
URL: https://github.com/apache/airflow/pull/61283

   ## Fix DAG-level RBAC by using claim_token per UMA specification
   
   closes: #61137
   
   ### Description
   
   This PR fixes a bug in the Keycloak Auth Manager where context attributes 
(such as `dag_id`) were not being properly transmitted to Keycloak during 
authorization requests, preventing DAG-level RBAC policies from functioning.
   
   ### Problem
   
   When attempting to configure DAG-level authorization policies in Keycloak, 
the `dag_id` and other context attributes were not available to 
JavaScript-based policies. Network traces showed that instead of sending the 
actual attribute values, the literal string `context=attributes` was being 
transmitted in the authorization request.
   
   **Root Cause:**
   The original implementation used a non-standard `context` parameter with a 
nested dictionary:
   ```python
   payload["context"] = {"attributes": attributes}
   ```
   
   This approach failed because:
   1. It is not compliant with the UMA (User-Managed Access) specification
   2. Nested dictionaries in form-urlencoded requests cannot be properly 
serialized by the `requests` library
   3. Keycloak does not recognize the `context` parameter for authorization 
requests
   
   ### Solution
   
   Implemented the correct UMA specification for pushing claims to Keycloak by 
using the `claim_token` parameter:
   
   ```python
   claims = {key: [value] for key, value in attributes.items()}
   claim_json = json.dumps(claims)
   claim_token = base64.b64encode(claim_json.encode()).decode()
   payload["claim_token"] = claim_token
   payload["claim_token_format"] = "urn:ietf:params:oauth:token-type:jwt"
   ```
   
   **Key changes:**
   - Use `claim_token` parameter instead of `context` (per UMA spec)
   - Base64-encode the JSON data
   - Format claim values as arrays of strings (required by Keycloak)
   - Add `claim_token_format` parameter
   
   **Reference:** [Keycloak Authorization Services - Pushing 
Claims](https://www.keycloak.org/docs/latest/authorization_services/index.html#_service_authorization_pushing_claims)
   
   ### Impact
   
   After this fix:
   - ✅ DAG-level RBAC policies will work correctly
   - ✅ `dag_id` and other context attributes are accessible in Keycloak policies
   - ✅ Fine-grained authorization per DAG is now possible
   
   Example Keycloak policy that now works:
   ```javascript
   const context = $evaluation.getContext();
   const attributes = context.getAttributes();
   const dagId = attributes.getValue('dag_id').asString(0);
   
   if (dagId === 'sensitive_dag') {
       // Apply specific permissions
       $evaluation.grant();
   }
   ```
   
   ### Testing
   
   - Code passes `ruff format` and `ruff check` validation
   - Tested claim_token encoding/decoding with validation script
   - Verified form-urlencoded transmission preserves data correctly
   - Confirmed backwards compatibility (no impact when attributes are not 
provided)
   
   ### Changes Made
   
   **Modified files:**
   1. 
`providers/keycloak/src/airflow/providers/keycloak/auth_manager/keycloak_auth_manager.py`
      - Added `import base64`
      - Updated `_get_payload()` method to use `claim_token` parameter
   
   2. `providers/keycloak/docs/changelog.rst`
      - Added bug fix entry for version 0.5.2
   
   ---
   
   ##### Was generative AI tooling used to co-author this PR?
   
   - [X] Yes (please specify the tool below)
   
   Generated-by: GitHub Copilot
   
   


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