You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airflow.apache.org by "dhkim1920 (via GitHub)" <gi...@apache.org> on 2026/08/08 01:28:14 UTC
[I] Keycloak team Op permission is missing team DAG resource [airflow]
dhkim1920 opened a new issue, #71319:
URL: https://github.com/apache/airflow/issues/71319
### Under which category would you file this issue?
Providers
### Apache Airflow version
3.3.0
### What happened and how to reproduce it?
When using the Keycloak Auth Manager with multi-team support, the Op-{team} permission created by create-team does not include the DAG resource for the team.
The issue was noticed while investigating #70251 and #70906.
The Op-{team} permission includes team-scoped resources such as Connection, Pool, and Variable, but Dag:{team} is missing.
For example:
Enable multi-team support with the Keycloak Auth Manager.
Create a team:
airflow keycloak-auth-manager create-team team-analytics
Inspect the generated Op-team-analytics permission in Keycloak.
Check the resources attached to the permission.
Dag:team-analytics is not included.
As a result, a user with the team Op role does not receive the expected permission for the team's DAG resource.
This is separate from the UNANIMOUS decision strategy issue addressed by #70906.
### What you think should happen instead?
The Op-{team} permission should include the corresponding Dag:{team} resource.
For example, when creating team-analytics, the Op-team-analytics permission should include:
Dag:team-analytics
along with the other team-scoped resources.
### Operating System
_No response_
### Deployment
None
### Apache Airflow Provider(s)
keycloak
### Versions of Apache Airflow Providers
apache-airflow-providers-keycloak==0.8.1
### Official Helm Chart version
Not Applicable
### Kubernetes Version
_No response_
### Helm Chart configuration
_No response_
### Docker Image customizations
_No response_
### Anything else?
This issue is being created separately based on the discussion in #70251 and the review of #70906.
The missing team DAG resource is independent of the UNANIMOUS versus AFFIRMATIVE decision strategy issue fixed by #70906.
### Are you willing to submit PR?
- [ ] 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: commits-unsubscribe@airflow.apache.org.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [I] Keycloak team Op permission is missing team DAG resource [airflow]
Posted by "joshua-cogliati-inl (via GitHub)" <gi...@apache.org>.
joshua-cogliati-inl commented on issue #71319:
URL: https://github.com/apache/airflow/issues/71319#issuecomment-5285017857
FYI, this is the script I used as a workaround for this issue:
```bash
#!/usr/bin/env bash
set -euo pipefail
# fix-op-team-dag-resource.sh
#
# Workaround for environments running a keycloak provider version whose
# `_attach_team_permissions` omits DAG:{team} from the Op-{team}
# resource-based permission (see commands.py fix, tracked in [issue link]).
#
# Once every environment is on a provider version with the commands.py
# fix, this script is no longer needed and can be deleted.
#
# IMPORTANT: the Keycloak "update permission resources" endpoint REPLACES
# the resource list rather than merging (confirmed empirically). This
# script does explicit read -> merge -> write to avoid dropping the
# existing Connection/Variable/Pool resources already attached to
# Op-{team}.
#
# NOTE: deliberately avoids jq (not present in the stock Keycloak image).
# Uses `kcadm ... --format csv --noquotes` to get one ID/name per line
# instead, same pattern the rest of this repo's kcadm scripts already use.
#
# Usage:
# KEYCLOAK_ADMIN=admin KEYCLOAK_ADMIN_PASSWORD=... \
# ./fix-op-team-dag-resource.sh team-analytics ...
#
# Safe to re-run: if DAG:{team} is already attached, the script detects
# this and skips the write for that team.
kcadm=/opt/keycloak/bin/kcadm.sh
server=http://keycloak:8080
realm=airflow
if [[ $# -eq 0 ]]; then
echo "Usage: $0 <team-name> [<team-name> ...]"
exit 1
fi
"$kcadm" config credentials --server "$server" --realm master \
--user "$KEYCLOAK_ADMIN" --password "$KEYCLOAK_ADMIN_PASSWORD"
airflow_client_id=$("$kcadm" get clients -r "$realm" -q clientId=airflow \
--fields id --format csv --noquotes | head -n 1)
test -n "$airflow_client_id" || { echo "ERROR: could not resolve airflow client id"; exit 1; }
echo "airflow client id: $airflow_client_id"
echo
# Join an array of quoted strings with commas, e.g.:
# join_csv_json "a" "b" "c" -> "a","b","c"
join_csv_json() {
local IFS=,
echo "$*"
}
fix_op_dag_resource() {
local team=$1
local perm_name="Op-${team}"
# NOTE: resource is named "Dag:{team}" (confirmed casing from live
# kcadm output), not "DAG:{team}".
local dag_resource_name="Dag:${team}"
echo "=== $team ==="
local perm_id
perm_id=$("$kcadm" get "clients/$airflow_client_id/authz/resource-server/permission" -r "$realm" \
-q "name=$perm_name" --fields id --format csv --noquotes | head -n 1)
if [[ -z "$perm_id" ]]; then
echo " Skipping: permission '$perm_name' not found (team may not exist yet)"
echo
return
fi
local dag_resource_id
dag_resource_id=$("$kcadm" get "clients/$airflow_client_id/authz/resource-server/resource" -r "$realm" \
-q "name=$dag_resource_name" --fields _id --format csv --noquotes | head -n 1)
if [[ -z "$dag_resource_id" ]]; then
echo " Skipping: resource '$dag_resource_name' not found"
echo
return
fi
# Read current resources attached to the permission, one "id,name" pair
# per line via CSV (no jq). --fields order below matches the header-less
# csv output order.
local current_csv
current_csv=$("$kcadm" get "clients/$airflow_client_id/authz/resource-server/permission/$perm_id/resources" \
-r "$realm" --fields _id,name --format csv --noquotes)
local current_ids=()
local current_names=()
while IFS=, read -r id name; do
[[ -z "$id" ]] && continue
current_ids+=("$id")
current_names+=("$name")
done <<< "$current_csv"
echo " Current resources: ${current_names[*]:-(none)}"
# Check whether DAG is already present.
local id
for id in "${current_ids[@]}"; do
if [[ "$id" == "$dag_resource_id" ]]; then
echo " Already has $dag_resource_name attached. Skipping."
echo
return
fi
done
# Build merged ID list (existing + new), each quoted for the JSON array
# kcadm expects in -s 'resources=[...]'.
local quoted_ids=()
for id in "${current_ids[@]}"; do
quoted_ids+=("\"$id\"")
done
quoted_ids+=("\"$dag_resource_id\"")
local merged_json
merged_json="[$(join_csv_json "${quoted_ids[@]}")]"
echo " Adding: $dag_resource_name"
local before_count=${#current_ids[@]}
"$kcadm" update "clients/$airflow_client_id/authz/resource-server/permission/resource/$perm_id" \
-r "$realm" -s "resources=$merged_json"
# Verify: re-read and confirm count is exactly +1 and DAG is present.
local after_csv
after_csv=$("$kcadm" get "clients/$airflow_client_id/authz/resource-server/permission/$perm_id/resources" \
-r "$realm" --fields _id,name --format csv --noquotes)
local after_ids=()
local after_names=()
local found_dag=false
while IFS=, read -r id name; do
[[ -z "$id" ]] && continue
after_ids+=("$id")
after_names+=("$name")
[[ "$id" == "$dag_resource_id" ]] && found_dag=true
done <<< "$after_csv"
echo " After: ${after_names[*]:-(none)}"
local after_count=${#after_ids[@]}
if [[ "$after_count" -ne $((before_count + 1)) ]]; then
echo " WARNING: expected $((before_count + 1)) resources after update, got $after_count."
echo " Please inspect manually -- the merge may not have applied as expected."
elif [[ "$found_dag" != "true" ]]; then
echo " WARNING: resource count looks right but $dag_resource_name was not found in the after list."
echo " Please inspect manually."
else
echo " OK: $dag_resource_name added, existing resources preserved."
fi
echo
}
for team in "$@"; do
fix_op_dag_resource "$team"
done
echo "Done."
```
--
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: commits-unsubscribe@airflow.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [I] Keycloak team Op permission is missing team DAG resource [airflow]
Posted by "vincbeck (via GitHub)" <gi...@apache.org>.
vincbeck closed issue #71319: Keycloak team Op permission is missing team DAG resource
URL: https://github.com/apache/airflow/issues/71319
--
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: commits-unsubscribe@airflow.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [I] Keycloak team Op permission is missing team DAG resource [airflow]
Posted by "coleheflin (via GitHub)" <gi...@apache.org>.
coleheflin commented on issue #71319:
URL: https://github.com/apache/airflow/issues/71319#issuecomment-5284940427
I'll take this one on.
---
Drafted-by: Claude Code (Sonnet 5) (no human review before posting)
--
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: commits-unsubscribe@airflow.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org