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]