Fix 403 Forbidden for artifact list via query param when default_permission=NO_PERMISSIONS#21220
Merged
WeichenXu123 merged 7 commits intomasterfrom Mar 4, 2026
Merged
Conversation
Co-authored-by: WeichenXu123 <19235986+WeichenXu123@users.noreply.github.com>
Copilot
AI
changed the title
[WIP] Fix 403 Forbidden error when calling load_model with MLFlow 3.10
Fix 403 Forbidden for artifact list via query param when Feb 28, 2026
default_permission=NO_PERMISSIONS
11 tasks
WeichenXu123
reviewed
Mar 2, 2026
Contributor
|
Documentation preview for f450d4d is available at: More info
|
Contributor
There was a problem hiding this comment.
Pull request overview
Fixes a permission-check regression in the basic-auth plugin when listing artifacts via the mlflow-artifacts proxy endpoint using a ?path=... query parameter, particularly when default_permission=NO_PERMISSIONS.
Changes:
- Extend experiment-id extraction for artifact-proxy authorization to fall back to
request.args["path"]when noartifact_pathURL parameter is present. - Add an auth config fixture with
default_permission = NO_PERMISSIONSto reproduce the restrictive-default scenario. - Add a regression test ensuring artifact listing via query param honors explicit experiment permissions.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
mlflow/server/auth/__init__.py |
Updates experiment-id extraction logic for artifact-proxy authorization to support query-param paths. |
tests/server/auth/fixtures/no_permission_auth.ini |
Adds a test auth configuration with default_permission=NO_PERMISSIONS. |
tests/server/auth/test_auth.py |
Adds a regression test covering artifact list via ?path=... under restrictive defaults. |
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Signed-off-by: WeichenXu <weichen.xu@databricks.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Signed-off-by: WeichenXu <weichen.xu@databricks.com>
This reverts commit 8ab6c65. Signed-off-by: Weichen Xu <weichen.xu@databricks.com>
WeichenXu123
reviewed
Mar 2, 2026
| params={"path": f"{experiment_id}/models/m-abc123/artifacts"}, | ||
| auth=(username1, password1), | ||
| ) | ||
| assert response.status_code != 403 |
Collaborator
There was a problem hiding this comment.
the test is only for auth layer, the backend flask server does not fully set up artifact storage configure, so response.status_code == 200 will fail
daniellok-db
pushed a commit
to daniellok-db/mlflow
that referenced
this pull request
Mar 5, 2026
…mission=NO_PERMISSIONS` (mlflow#21220) Signed-off-by: WeichenXu <weichen.xu@databricks.com> Signed-off-by: Weichen Xu <weichen.xu@databricks.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: WeichenXu123 <19235986+WeichenXu123@users.noreply.github.com> Co-authored-by: WeichenXu <weichen.xu@databricks.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
daniellok-db
pushed a commit
to daniellok-db/mlflow
that referenced
this pull request
Mar 5, 2026
…mission=NO_PERMISSIONS` (mlflow#21220) Signed-off-by: WeichenXu <weichen.xu@databricks.com> Signed-off-by: Weichen Xu <weichen.xu@databricks.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: WeichenXu123 <19235986+WeichenXu123@users.noreply.github.com> Co-authored-by: WeichenXu <weichen.xu@databricks.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
daniellok-db
pushed a commit
that referenced
this pull request
Mar 5, 2026
…mission=NO_PERMISSIONS` (#21220) Signed-off-by: WeichenXu <weichen.xu@databricks.com> Signed-off-by: Weichen Xu <weichen.xu@databricks.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: WeichenXu123 <19235986+WeichenXu123@users.noreply.github.com> Co-authored-by: WeichenXu <weichen.xu@databricks.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
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.
Closes #21201
When
default_permission = NO_PERMISSIONSis configured, users with explicit experiment permissions get 403 when callingload_model()on a logged model in MLflow 3.10. The artifact download triggers a list request using a query parameter (?path=…) rather than a URL path parameter, causing permission extraction to fail and fall through to the restrictive default.Root Cause
_get_experiment_id_from_view_args()only readrequest.view_args["artifact_path"](the path parameter used by download/upload/delete endpoints). The list artifacts endpoint usesGET /mlflow-artifacts/artifacts?path=<experiment_id>/models/<model_id>/artifacts— a query parameter — so the experiment ID was never extracted, and permission checks silently fell back todefault_permission.Fix
mlflow/server/auth/__init__.py: Checkrequest.args.get("path")as a fallback when the URL path parameter is absent:tests/server/auth/fixtures/no_permission_auth.ini: New auth config fixture withdefault_permission = NO_PERMISSIONSto reproduce the bug scenario.tests/server/auth/test_auth.py: Regression testtest_proxy_artifact_list_query_param_uses_experiment_permission— verifies an authorized user (MANAGE) is not blocked on artifact list via query param, and an unauthorized user still gets 403.How is this PR tested?
Does this PR require documentation update?
Does this PR require updating the MLflow Skills repository?
Release Notes
Is this a user-facing change?
Fixed a regression in the basic-auth plugin where loading a logged model artifact (
load_model()) returned 403 Forbidden for users with explicit experiment permissions when the server was configured withdefault_permission = NO_PERMISSIONS.What component(s), interfaces, languages, and integrations does this PR affect?
Components
area/tracking: Tracking Service, tracking client APIs, autologgingHow should the PR be classified in the release notes? Choose one:
rn/bug-fix- A user-facing bug fix worth mentioning in the release notesShould this PR be included in the next patch release?
Warning
Firewall rules blocked me from connecting to one or more addresses (expand for details)
I tried to connect to the following addresses, but was blocked by firewall rules:
api.openai.com/home/REDACTED/work/_temp/setup-uv-cache/builds-v0/.tmpDhavJd/bin/python /home/REDACTED/work/_temp/setup-uv-cache/builds-v0/.tmpDhavJd/bin/python -m uvicorn mlflow.server.auth:create_app --host 127.0.0.1 --port 33221 /dev/null -lFoundation 0/x64/bin/git uname -p(dns block)/home/REDACTED/work/_temp/setup-uv-cache/builds-v0/.tmpDhavJd/bin/python /home/REDACTED/work/_temp/setup-uv-cache/builds-v0/.tmpDhavJd/bin/python -m uvicorn mlflow.server.auth:create_app --host 127.0.0.1 --port 49913 d -n 10(dns block)If you need me to access, download, or install something from one of these locations, you can either:
Original prompt
This section details on the original issue you should resolve
<issue_title>[BUG] 403 Forbiden when calling
load_model()MLFlow 3.10</issue_title><issue_description>### Issues Policy acknowledgement
Where did you encounter this bug?
Local machine
MLflow version
System information
Describe the problem
The same permissions that work on MLFlow 3.9 doesnt work anymore on MLFlow 3.10 when trying to call
load_model().The only solution is to grant the user admin right.
Tracking information
Code to reproduce issue
Stack trace