pierrejeambrun opened a new pull request, #74232:
URL: https://github.com/apache/airflow/pull/74232

   ### What
   
   `action_logging` builds the audit `Log` row's `dag_id` (and `task_id` / 
`run_id`) from the request's **query *and* path** parameters merged together:
   
   ```python
   params = {**request.query_params, **request.path_params}
   ...
   dag_id=params.get("dag_id")
   ```
   
   So a query parameter can file an unrelated write under a Dag. `POST 
/api/v2/connections?dag_id=some_dag` lands a connection write among 
`some_dag`'s **Dag-scoped** audit rows — the rows the per-Dag event-log 
endpoints return to anyone who can read that Dag (since #70759 split Dag-scoped 
rows out from the admin-only `All Audit Logs`). The actor needs write access to 
the resource and secrets are still masked, so what surfaces is metadata (a 
connection id, host, login), but it surfaces to the wrong audience.
   
   This was documented as a known limitation in #72247 (closed) and belongs in 
core, independent of the viewer-access feature discussed there.
   
   ### The change
   
   The Dag an audit row belongs to must come from the route the request 
actually targets — its **path**, or the **body** of an endpoint that names one 
— never a query filter:
   
   ```python
   scope = {**request.path_params}
   if has_json_body:
       scope.update(masked_body_json)
   dag_id = scope.get("dag_id")
   ```
   
   - **Path** keeps every `/dags/{dag_id}/…` operation Dag-scoped.
   - **Body** keeps `create_backfill` Dag-scoped (a backfill names its `dag_id` 
in the body, not the path) — covered by the existing `test_create_backfill` 
audit assertion.
   - **Query** no longer scopes a row, so the connection/variable/pool writes 
above stay out of any Dag's audit log.
   
   `_resolve_team_name` is handed that same path/body `dag_id`, so a spurious 
`?dag_id=` no longer defers a team-scoped resource's team to an unrelated Dag 
either.
   
   ### Tests
   
   - `TestActionLoggingDagScope`: query `dag_id` / `task_id` / `run_id` do not 
scope the row; path and body `dag_id` do.
   - `test_a_query_param_dag_id_does_not_hijack_the_resource_team`: under 
multi-team, the team still comes from the resource.
   - All existing decorator, backfill (`create_backfill`, body-sourced 
`dag_id`) and `favorite_dag` (path-sourced `dag_id`) audit assertions are 
unchanged and pass. Every existing non-null `dag_id` audit assertion in the 
route tests is path- or body-sourced.
   
   No new access is granted — this only narrows which audit rows are considered 
Dag-scoped — so it does not re-open the direction declined on #72247.
   
   related: #72238, #72247
   
   ---
   
   ##### Was generative AI tooling used to co-author this PR?
   
   - [X] Yes — Claude Code (Opus 4.8)
   
   Generated-by: Claude Code (Opus 4.8) following [the 
guidelines](https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#gen-ai-assisted-contributions)
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code)
   


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