Skip to content

Add RFC: Fine-grained sub-resource permissions - #32

Merged
B-Step62 merged 3 commits into
mlflow:mainfrom
rrrkharse:rfc/sub-resource-permissions
Sep 15, 2026
Merged

B-Step62 merged 3 commits into
mlflow:mainfrom
rrrkharse:rfc/sub-resource-permissions

Conversation

@rrrkharse

@rrrkharse rrrkharse commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Summary

Makes a curated set of child resource types independently grantable in MLflow RBAC, on top of an inheritance model (no configuration flag).

Problem: MLflow's RBAC recognizes only top-level resource types (experiment, registered_model, prompt, scorer, mcp_server, gateway_*, workspace). Sub-resources — runs, traces, assessments, logged models, and registry versions — resolve to their parent's permission, so there is no way to grant (or deny) different access on runs vs. traces vs. assessments within one experiment.

Model: A child is resolved on its own tier when the caller holds any grant on the child type; otherwise it falls back to the parent, exactly as today.

  • No child grant → inherits the parent (fully backward compatible, no config change).
  • Positive child grantraises the child above its inherited level (escalation).
  • NONE grantdenies the child even where the parent would allow (restriction). NONE is an absolute deny within its tier, evaluated ahead of max; the workspace-admin bypass is evaluated ahead of NONE.

A child grant, when present, is authoritative for its tier (higher or lower than the parent); the parent is consulted only on child absence. NONE does not override downward — a parent NONE reaches a child only via fallback.

Use cases:

  1. Run logging without experiment management (#11496)
  2. Assessment-only write access (evaluation/validation boundary)
  3. Registered-model-version logging without registry management
  4. Restriction via NONE (e.g. deny traces while keeping the experiment readable)

Enforcement (aligned with the merged pluggable-auth RFC, RFC 0008):

  • Core resolves the child's parent and wires it through on the AuthorizationRequirement as optional parent_resource_type/parent_resource_id fields — exactly as workspace is already wired through. One requirement, one authorize(), one Decision; no OR/combinator.
  • The default DB backend realizes the decision in get_role_permission_for_resource via a resource-type registry (grain per type), a grain-aware match key, and the tier-override fold (workspace-admin bypass → child tier → parent fallback → default).
  • No DB schema changes. Grants stay wildcard-grain; per-id grain is deferred (search-filter push-down, #24964). Workspace MANAGE continues to win over everything.

Related: mlflow/mlflow#11496

Propose making all DB-indexed resource types independently permissionable
behind a configuration flag. In simplified mode (default), behavior is
identical to today. In fine-grained mode, admins can grant on run, trace,
assessment, logged_model, model_version, and other sub-resources
independently.

Key use cases:
- Run access without experiment management (#11496)
- Assessment-only write access (evaluation boundary)
- Model version lifecycle separation from registered_model
What they want: `NO_PERMISSIONS` on experiments + `EDIT` on runs.

Today: impossible. The only workaround is granting experiment EDIT, which also
lets users create new experiments and get automatic MANAGE on them — the opposite

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you mean "users create new runs"? Experiment EDIT is not the create gate. Anyone that is authenticated when workspaces are off can create experiments. When workspaces are on, MANAGE I think is required when they are on.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, fixed

| Resource | DB table | API examples | Current resolution | Proposed resolution (fine-grained) |
|----------|----------|--------------|-------------------|-----------------------------------|
| `run` | `runs` | CreateRun, UpdateRun, DeleteRun, LogMetric, LogBatch | `_get_permission_from_run_id()` → experiment | `_get_permission_from_run_id()` → run |
| `trace` | `trace_info` | StartTrace, EndTrace, GetTrace, SearchTraces, SetTraceTag | `_get_permission_from_trace()` → experiment | `_get_permission_from_trace()` → trace |

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not straightforward to do with the current DB schema but a user experience enhancement could be granting read access at the trace session level. I'm thinking it'd be tedious to grant permissions to all traces in a chat bot session if you need a human to look at that specific session. The UI could have a "share session" button in the future.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I think this could be a good candidate for resource conditions level auth to handle, e.g. read to all traces with session tag X. Will track in that RFC PR.

- **Fail-closed enforcement for unregistered resource types** — today, routes
without a registered validator are fail-open (any authenticated user can
access). This proposal preserves that behavior.
- **Parent-scoped sub-resource grants** — in fine-grained mode, a grant like

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we reconsider this for certain resources such as assessments? The rationale being that if an experiment logically maps to a single agent's traces, you probably want to grant assessment access per agent, not globally at the workspace level.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can use Condition Based Access Control for this use case as well, and in this PR will just add the resource type.

| `logged_model` | `logged_models` | CreateLoggedModel, GetLoggedModel, DeleteLoggedModel | `_get_permission_from_model_id()` → experiment | `_get_permission_from_model_id()` → logged_model |
| `prompt_optimization_job` | `jobs` | CreatePromptOptimizationJob, GetPromptOptimizationJob | `_get_permission_from_prompt_optimization_job_id()` → experiment | `_get_permission_from_prompt_optimization_job_id()` → prompt_optimization_job |
| `review_queue` | `review_queues` | CreateReviewQueue, UpdateReviewQueue, AddItemsToReviewQueue | `_get_permission_from_review_queue_id()` → experiment | `_get_permission_from_review_queue_id()` → review_queue |
| `label_schema` | `label_schemas` | CreateLabelSchema, UpdateLabelSchema, DeleteLabelSchema | `_get_permission_from_label_schema_id()` → experiment | `_get_permission_from_label_schema_id()` → label_schema |

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think label_schema makes sense to keep at the experiment level since I think this additional granularity adds very little value.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make sense, updated


## Detailed design

### New resource types

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about the generic job endpoints?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure how we want to handle these since the existing APIs aren't part of the Auth Model, but I defined a criteria in the RFC for adding new resource types like job endpoints that should assist with future PRs.


| Resource | DB table | API examples | Current resolution | Proposed resolution (fine-grained) |
|----------|----------|--------------|-------------------|-----------------------------------|
| `model_version` | `model_versions` | CreateModelVersion, UpdateModelVersion, DeleteModelVersion | `_get_permission_from_model_version()` → registered_model | `_get_permission_from_model_version()` → model_version |

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A registered model without versions is not useful. I think if a user has permission to the registered model, the prompt, the MCP server, they should have access to the versions within it. Otherwise, you'd have to grant permission after every new version.

I then also question the value of having permissions granted directly on a versioned entity in the registry, but I'm not opposed to it.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah right now it's not useful, but with support for Condition based access control we could, for example, restrict updates to versions with labels like production, champion, QA, etc. to protect them from edit. (Registered model would have USE in this case to handle create case)


## Detailed design

### New resource types

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about the MCP registry endpoints?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added to scope

Search filtering follows the same pattern as today's `filter_search_experiments`:

```python
def filter_search_traces(user, traces, workspace):

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will be problematic in the UI. If the user just has permission to a single trace, then either most pages are empty or MLflow has to query every single trace in the experiment to see if the user has permission to it.

This is being solved by doing request level filtering rather than post response filtering:
mlflow/mlflow#24964

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Restricted new resources being added to * only for now instead of supporting ID as well. Can revisit once request level filtering implemented.

3. Sub-resource grants remain stored but have no effect — they can be cleaned up
or left in place for a future switch back

# Open questions

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you considered how the UI would work? If the user has access to one run, will they see the experiment the run is in?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They would need experiment READ permissions. I've reworked to a inheritance model so this should flow more naturally now.

before switching modes — see [Adoption strategy](#adoption-strategy) for the
safe transition path._

### Fine-grained mode (opt-in)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don’t like that the simplified/fine-grained choice is all-or-nothing. Have you considered keeping top-level grants as they are today (they apply to children) and let optional sub-resource grants raise permissions?

This is similar to how workspaces work where you can have a broad workspace permission grant but have a more specific permission within the workspace (e.g. read on workspace A but manage on experiment 2 in the workspace).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1, I think child resource should inherits from higher hierarchy by default.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can still support evaluator requirement by adding "NONE" as a configurable action.

# Evaluator: can view experiments and write assessments, but no read access to runs and models.
client.add_role_permission(pipeline_role.id, "experiment", "*", "READ")
client.add_role_permission(pipeline_role.id, "assessment", "*", "EDIT")
client.add_role_permission(pipeline_role.id, "run", "*", "NONE")
client.add_role_permission(pipeline_role.id, "logged_model", "*", "NONE")

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reworked to being the inheritance model y'all suggested given that it supports all the customer use cases I am aware of.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can still support evaluator requirement by adding "NONE" as a configurable action.

Current model takes max permissions only, which could work if NONE takes higher precedence than all other permissions. This would effectively introduce DENY functionality which I don't see downsides with but it seems to go against the original RBAC RFC proposal.

before switching modes — see [Adoption strategy](#adoption-strategy) for the
safe transition path._

### Fine-grained mode (opt-in)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1, I think child resource should inherits from higher hierarchy by default.

before switching modes — see [Adoption strategy](#adoption-strategy) for the
safe transition path._

### Fine-grained mode (opt-in)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can still support evaluator requirement by adding "NONE" as a configurable action.

# Evaluator: can view experiments and write assessments, but no read access to runs and models.
client.add_role_permission(pipeline_role.id, "experiment", "*", "READ")
client.add_role_permission(pipeline_role.id, "assessment", "*", "EDIT")
client.add_role_permission(pipeline_role.id, "run", "*", "NONE")
client.add_role_permission(pipeline_role.id, "logged_model", "*", "NONE")

- **Fine-grained auth for non-DB-indexed resources** (e.g., individual spans
within a trace) — these are stored in blob/artifact storage, not queryable as
independent DB entities.
- **Fail-closed enforcement for unregistered resource types** — today, routes

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This has been addressed in mlflow/mlflow#25308 very recently - MLflow auth will be fail-closed. This shouldn't affect RFC shape but fyi.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ack, yes the concern is more around the lack of enforcement for unregistered resource types.


| Resource | DB table | API examples | Current resolution | Proposed resolution (fine-grained) |
|----------|----------|--------------|-------------------|-----------------------------------|
| `gateway_endpoint_binding` | `gateway_endpoint_bindings` | CreateGatewayEndpointBinding, DeleteGatewayEndpointBinding | `validate_can_update_gateway_endpoint` → gateway_endpoint | `_get_permission_from_gateway_endpoint_binding()` → gateway_endpoint_binding |

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gateway endpoint binding is a link between an endpoint and a consumer of it e.g. scorer. In this case, I think this should be defined by minimum of the endpoint and the consumer permissions, not a dedicated permission entry.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently both endpoint and binding are managed by the endpoint's resource permissions. Min of either would go against the existing max model. So either approach is a breaking change.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's true when endpoint binding is treated as a separate permission entry, but I don't think we should treat it as such. An analogy is that if a trace is linked to a prompt and if I have read permission to both, it is strange I need another permission for a trace-prompt link object to see the lineage between two.

Tho the simple 'min' is probably not sufficient on second thought. This means that endpoint owner needs READ permission on every bound resources to see how many resources are using the endpoint. If the owner lacks permission on some of them, the reference count incorrectly say "0" and can cause an accidental deletion. I think we can handle it as follows:

  • List bindings from endpoint page: endpoint READ can see bindings as opaque reference and count, e.g. just "scorer" not its name.
  • View details of the bound scorers : additionally require scorer READ.
  • Remove binding: scorer EDIT and endpoint USE.
  • Delete endpoint: if any bindings exist, reject unless the caller explicitly confirms/forces deletion, which requires MANAGE on the endpoint.

"assessment",
"logged_model",
"model_version",
"prompt_optimization_job",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Prompt optimization job is a bit strange state today - it exists in data model but no real SDK/UI is built on top of it (just half abandoned for some reason). We should probably just clean it up.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense, removed from scope

Rework to the max/escalation model (top-level grants inherit; optional
child grants raise), address reviewer comments on the resource set,
resolution mechanics, scoping boundaries, and behavioral compatibility.
@B-Step62 B-Step62 mentioned this pull request Sep 1, 2026
5 tasks
@mprahl

mprahl commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator

@rrrkharse could you please address this comment #19 (comment) as well from the auth RFC that was just merged?

the child.

```
effective(child) = max(inherited_parent_permission, direct_child_grant)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this isn't intuitive. Could we model this after file permissions where the more granular one wins?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm now on the fence about this. What do you think @B-Step62 ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Granular wins would clash with the existing max permission wins model, e.g. currently workspace edit takes precedence experiment over read.

But if we were to model it:

  1. Parent perms present, no child perms --> Inherit parent perms
  2. No parent perms, child perms present --> Directly use child perms
  3. Parent perms weaker than child perms --> Directly use child perms
  4. Parent perms stronger than child perms --> Directly use child perms

In this way the decision tree is simplified as long as we map all the child parent relationships, and workspace already gets its own override in the decision tree logic today so can be a special case. Backwards compatibility is also maintained for today's parent only resource model.

I'll look into how this would integrate with the pluggable auth RFC.

@B-Step62 B-Step62 Sep 5, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rrrkharse The proposal makes sense to me, with the addition of NO_PERMISSION (or DENY, no strong preference on naming) entry!

I think the one thing we need to document carefully is workspace admin (workspace MANAGE). That one should keep winning against child resource declarations. Otherwise owner of the resource can prevent workspace admin from accessing the resource by setting lower permission like READ.


The experiment grant is `READ`, not lower: a user must be able to read an
experiment to discover and target it (`GetExperiment` / `SearchExperiments` require
experiment `can_read`), and must be a workspace member (workspace `USE`). Run

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and must be a workspace member (workspace USE)

I don't think this is true today. Are you proposing to add this as part of this RFC?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, will remove this

creation also permits managing the model entry.

- **Example user:** a data scientist who registers new versions of existing models.
- **Policy:** `(registered_model, *, READ)` + `(model_version, *, EDIT)`

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit:

Suggested change
- **Policy:** `(registered_model, *, READ)` + `(model_version, *, EDIT)`
- **Policy:** `(registered_model, *, READ)` + `(registered_model_version, *, EDIT)`

creation also permits managing the model entry.

- **Example user:** a data scientist who registers new versions of existing models.
- **Policy:** `(registered_model, *, READ)` + `(model_version, *, EDIT)`

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be out of scope for this RFC, but it'd be nice to have a finegrained permission for setting aliases (e.g. only user1 can set a registered model or prompt or MCP server alias to production). This is a customer use case I've seen and Langfuse does this.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll take a look into adding a resource type vs using request conditions

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I'd prefer keeping a request condition on the registered_model(_version) so we just have to check on that tier rather than having to check if we can update registered_model_version and then also check if we have to update alias.

But both options are viable under this RFC.

| `registered_model` | `model_version` |
| `prompt` | `prompt_version` |
| `scorer` | `scorer_version` (excluded) |
| `mcp_server` | `mcp_server_version` (excluded) |

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not include this? It seems simple to add and it makes it consistent with the other AI asset registries in MLflow.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excluded because there's no surface for future condition based access control, e.g. tags or alias, the way model_version has. But yeah trivial to include so will update RFC

Notes:
- **Grain is wildcard-only in this RFC.** Every grantable child is at `*` grain;
id-level grain (`(trace, <id>, …)`) will be added once request-level search-filter
push-down is in place (see [Search filtering](#search-filtering)).

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be best to not promise this unless you are 100% you will be doing that lol

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, will soften the wording here

this RFC lands; sub-resources marked **Yes** are what it adds. All grants are
per-workspace.

| Parent | Sub-resource | Grantable? | [Grain](#search-filtering) | Escalation use case | Addable later? |

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since all grains are wildcard, let's maybe simplify this RFC to just assume that and to drop the #search-filtering section and just keep this as a note in "Out of Scope"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense

The subsections below walk each box: the entry point + validator map, the fold and
its clauses, and how the child's parent (and workspace) are resolved.

#### Entry point and validator interface

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the future, I think this level of implementation details can be left to the PR.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh great, good to know

return get_permission(best) if best is not None else None
```

#### Proposed changes to the permission fold

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm debating if this should be opt-in because it's essentially adding double the amount of DB queries for a permission check on these APIs. If the RFC stays with max wins, you could check the parent permission first and then fallback to the more granular which makes it as efficient in most cases.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see this is addressed under "Performance". I think with #19 , this will actually be more costly.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah will prioritize max wins for the default backend.

Other backends will have to decide how to optimize the decision tree but the core will provide the parent resource type and id (in my latest changes).

listing/opening experiments gates on `(experiment, …)` READ, a different resource
type the run grant never matches. To navigate to a run in the UI a user needs
experiment READ as well, which is why the run-logging use case pairs them:
`(experiment, *, READ)` + `(run, *, EDIT)`. This matches today's behavior — child

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the best practice then to not mix experiments with traces and ML runs? I could see an admin saying they should have access to runs but not traces.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I think with an inheritance model if admin gives a user has READ access to the experiment then they have to accept that the user also has READ to traces, assessment, log_models, etc.

Otherwise they would have to not grant READ on experiment itself, which would block UI usage.

In order to support this use case we would need:

  1. Granular permissions as described above
  2. A new NONE permission that takes precedence over all others

With RFC #19 , I'll need to take a look how that could fit in

@mprahl mprahl left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left some comments but I don't think any are blocking. This will be a good feature!

@rrrkharse

Copy link
Copy Markdown
Contributor Author

Thanks, I think we might need granular permissions and a new NONE type permission to complete the experience.

Granular is a one way door decision so I'll investigate that before committing to a final design.

@B-Step62 B-Step62 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rrrkharse Looks great to me once endpoint binding comment (#32 (comment)) is addressed and NONE type is added! I think this is highly useful feature, thank you for the proposal!

Align enforcement with the merged pluggable-auth RFC (RFC 0008) by wiring
the child's parent through the AuthorizationRequirement; add the NONE deny
level and its tier-override precedence; include scorer_version and
registered_model_version/mcp_server_version; drop the redundant
search-filtering section; and simplify the fold to a registry + match key.
@rrrkharse

Copy link
Copy Markdown
Contributor Author

Added granular and none type permissions. Also addressed/made changes based on minor comments.

@B-Step62

Copy link
Copy Markdown
Contributor

Merging the RFC upon two approvals. Thank you for the hard work @rrrkharse and really excited for landing this feature!

@B-Step62
B-Step62 merged commit 5fc2369 into mlflow:main Sep 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants