Repository navigation
Fix missing and incorrect endpoints in the API permission reference - #74871
Merged
vincbeck merged 1 commit intoOct 19, 2026
Merged
Conversation
Pushkal-Gupta
requested review from
amoghrajesh,
ashb,
bugraoz93,
gopidesupavan,
jason810496,
jscheffl,
potiuk and
vincbeck
as code owners
October 16, 2026 16:45
Pushkal-Gupta
force-pushed
the
fix-permission-ref-missing-endpoints
branch
from
October 18, 2026 23:47
aeb7fdd to
9abdb66
Compare
vincbeck
approved these changes
Oct 19, 2026
Contributor
Backport successfully created: v3-4-testNote: As of Merging PRs targeted for Airflow 3.X In matter of doubt please ask in #release-management Slack channel.
|
vatsrahul1001
added a commit
that referenced
this pull request
Oct 20, 2026
… reference (#74871) (#75099) * [v3-4-test] Fix missing and incorrect endpoints in the API permission reference (#74871) (cherry picked from commit a26f9f9) Co-authored-by: Pushkal Gupta <161060351+Pushkal-Gupta@users.noreply.github.com> * Regenerate FAB auth manager REST API permission table The cherry-pick updated airflow-core's api_permissions_ref.rst but not the FAB provider's generated access-control.rst table, so the generate-fab-permissions-doc prek hook failed. Regenerate it with scripts/ci/prek/fab_permissions_doc.py. --------- Co-authored-by: Pushkal Gupta <161060351+Pushkal-Gupta@users.noreply.github.com> Co-authored-by: Rahul Vats <43964496+vatsrahul1001@users.noreply.github.com>
vatsrahul1001
added a commit
that referenced
this pull request
Oct 20, 2026
… reference (#74871) (#75099) * [v3-4-test] Fix missing and incorrect endpoints in the API permission reference (#74871) (cherry picked from commit a26f9f9) Co-authored-by: Pushkal Gupta <161060351+Pushkal-Gupta@users.noreply.github.com> * Regenerate FAB auth manager REST API permission table The cherry-pick updated airflow-core's api_permissions_ref.rst but not the FAB provider's generated access-control.rst table, so the generate-fab-permissions-doc prek hook failed. Regenerate it with scripts/ci/prek/fab_permissions_doc.py. --------- Co-authored-by: Pushkal Gupta <161060351+Pushkal-Gupta@users.noreply.github.com> Co-authored-by: Rahul Vats <43964496+vatsrahul1001@users.noreply.github.com>
10 of 93 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The generated API permission reference lists
PUT /api/v2/backfills, which is not a real endpoint, and leaves out six endpoints that are. It also prints five paths with a:pathsuffix that no client ever calls.What's wrong
airflow-core/docs/security/api_permissions_ref.rstis generated byscripts/ci/prek/extract_permissions.py, which statically reads the route decorators underapi_fastapi/core_api/routes/public/. I compared what it produces against FastAPI's ownv2-rest-api-generated.yaml, which covers the same routers, so the two should agree exactly. The spec has 134 operations. 22 of them are missing from the doc, and 17 rows in the doc have no matching operation.Six of the missing ones are backfill endpoints:
backfills.pyis the one route file that passes the path as a keyword:The extractor only read
decorator.args[0], so for all eight routes in that file the path came out empty andfull_pathended up as just the router prefix,/api/v2/backfills. Dedup then folded eight operations into three rows, and one of those three isPUT /api/v2/backfills, which doesn't exist, since PUT only appears on the sub-paths. 126 routes in the repo pass the path positionally and 8 pass it aspath=, which is probably why nobody hit this.The other 16 rows are a smaller thing. Routes declared as
/{pool_name:path}get printed with the converter still attached. That's Starlette's matching syntax rather than part of the URL, and the OpenAPI spec and the real request path are both/{pool_name}. It affects pools, variables, xcoms and the two state-store paths.The FAB page comes out of the same extractor, so it has the same holes. There it also means an operator looking up any of the six backfill endpoints finds no row telling them which FAB permissions and minimum role it needs.
The fix
Read the path whichever way the decorator passes it, and drop the converter so the documented path is the one clients call. If a decorator has no path at all, raise instead of quietly falling back to the prefix, since that fallback is what turned a parsing gap into wrong documentation.
After the change the doc covers all 134 operations with nothing left over: both the 22 missing and the 17 phantom rows go to 0, and the entry count goes from 137 to 142.
I made the same two changes in
fab_permissions_doc.py, and also let it walkasync defhandlers the wayextract_permissions.pyalready does. Nothing there is broken today, since every FAB route is a syncdefwith a positional path, but it would drop rows silently rather than fail if that changed. I left its tolerantcontinuefor a non-constant path alone rather than making that raise too, since that part isn't what this PR is about.Tests
Unit tests for both helpers, including the
path=form taken frombackfills.pyand a decorator with no path at all, plus two end-to-end cases on synthetic route files for the keyword path and the converter.The guard I most wanted is an invariant rather than a snapshot: every route decorator in the source has to produce its own row. Against the current code it fails with
backfills.py declares 8 routes but the table holds 3 distinct operations, so it would have caught this whenbackfills.pywas written. There's a second check that no documented path contains a converter.All four of those fail without the change.
scripts/tests/goes from 1684 to 1698 passed, 1 skipped. ruff, mypy and the 43 prek checks that apply to these five files are clean, and both hooks pass leaving the docs byte-identical on a second run.No newsfragment, since this is a generated doc and the tooling behind it, with no user-facing code change.
Was generative AI tooling used to co-author this PR?