wilsonjefferson opened a new issue, #71277: URL: https://github.com/apache/airflow/issues/71277
### Under which category would you file this issue? Providers ### Apache Airflow version 3.3.0 ### What happened and how to reproduce it? With `core.multi_team=True` and the Keycloak auth manager, `GET /api/v2/dags`, `GET /api/v2/variables` and `GET /api/v2/connections` return resources belonging to every team, regardless of the requesting user's team membership. The docs state that Multi-Team is for organisations that "need resource isolation (Variables, Connections, Secrets, etc) between teams **at the UI and API level**" and that a use case is "You want separate views per team in the Airflow UI" ([Multi-Team → When to Use Multi-Team Mode](https://airflow.apache.org/docs/apache-airflow/stable/core-concepts/multi-team.html#when-to-use-multi-team-mode)). The Work in Progress section lists "Some UI elements may not be fully team-aware" as a known 3.4+ gap. This report concerns the **API** layer — the leak reproduces against the REST endpoints directly, not only through the UI — so it appears to fall outside that caveat. Write operations and Task Execution API access **are** correctly scoped; only list/read appears to be unfiltered. **Setup** Two teams, `team-a` and `team-b`, created via `airflow teams create` and `airflow keycloak-auth-manager create-team`. Per-team Dag bundles: ``` AIRFLOW__DAG_PROCESSOR__DAG_BUNDLE_CONFIG_LIST: [{"name": "team_a_dags", "classpath": "airflow.dag_processing.bundles.local.LocalDagBundle", "kwargs": {"path": "/opt/airflow/dags/team-a"}, "team_name": "team-a"}, {"name": "team_b_dags", "classpath": "airflow.dag_processing.bundles.local.LocalDagBundle", "kwargs": {"path": "/opt/airflow/dags/team-b"}, "team_name": "team-b"}, {"name": "shared_dags", "classpath": "airflow.dag_processing.bundles.local.LocalDagBundle", "kwargs": {"path": "/opt/airflow/dags/shared"}}] ``` `airflow dags list` confirms the association: `dag_id | bundle_name check_dag_running | team_a_dags test_owner_dag | team_b_dags test_dag | shared_dags` `user-a` is a member of Keycloak group `/team-a` only, with realm role `Admin` (explicitly **not** `SuperAdmin`). Decoded access token: ```json "realm_access": { "roles": ["default-roles-airflow", "offline_access", "uma_authorization", "Admin"] }, "groups": ["team-a"] ``` **Steps to reproduce** 1. Configure two teams with per-team Dag bundles as above. 2. Log in as `user-a` (member of `team-a` only). 3. `GET /api/v2/dags` **Observed:** all three Dags returned, including `test_owner_dag` from `team_b_dags`. Same in the UI Dags list. **Expected:** only `check_dag_running` (team-a) and `test_dag` (global). `GET /api/v2/variables` behaves the same way: `user-a` sees entries with `"team_name": "team-b"`, including their values where the key name does not happen to match the sensitive-keyword masker. **What IS correctly scoped** Write operations — `user-a` cannot edit or delete `team-b` Variables or Connections. Task Execution API, Variables — a task in a `team-a` Dag: `BLOCKED user-b-var: AirflowRuntimeError: VARIABLE_NOT_FOUND READ OK shared_var = everyone` Task Execution API, Connections — a `SQLExecuteQueryOperator` using a `team-b` connection succeeds in a `team-b` Dag, and the identical task in a `team-a` Dag fails: > AirflowNotFoundException: The conn_id user-b-conn-postgres isn't defined > File ".../airflow/sdk/execution_time/context.py", line 230 in _get_connection So enforcement is working at the Execution API and for writes, but not for list/read. ### What you think should happen instead? List endpoints should filter by the requesting user's team, consistent with the documented "resource isolation ... at the UI and API level". As it stands, a user in `team-a` can enumerate `team-b`'s Dag IDs and Variable keys via the REST API, and read Variable values whose names don't match the sensitive-keyword list. Execution-layer isolation is working correctly, so this looks like a bounded gap in the list/read endpoints rather than a design problem. Filing separately from the known "some UI elements may not be fully team-aware" caveat because it reproduces against the API directly. ### Operating System _No response_ ### Deployment None ### Apache Airflow Provider(s) _No response_ ### Versions of Apache Airflow Providers _No response_ ### Official Helm Chart version Not Applicable ### Kubernetes Version _No response_ ### Helm Chart configuration _No response_ ### Docker Image customizations Based on apache/airflow:3.3.0 with apache-airflow-providers-keycloak==0.8.2. No changes to core Airflow. ### Anything else? Keycloak 26 auth manager, CeleryExecutor, Postgres 16 metadata DB, Python 3.13. Reproduces consistently. Note: the Keycloak client's resource-server decision strategy must be set to Affirmative — under the default Unanimous, role-specific permissions veto access and every endpoint returns 403. ### 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: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
