Skip to content

Conversation

@derekhiggins
Copy link
Contributor

Closes security gaps where RBAC checks could be bypassed:

o Inference router: Added RBAC enforcement in the fallback
path to ensure access control is applied consistently.

o Model listing: Dynamic models fetched via provider_data were returned
without RBAC checks. Added filtering to ensure users only see models
they have permission to access.

Both fixes create temporary ModelWithOwner objects for RBAC validation, maintaining security through consistent access control enforcement.

Closes: #4269

@meta-cla meta-cla bot added the CLA Signed This label is managed by the Meta Open Source bot. label Dec 2, 2025
@derekhiggins derekhiggins changed the title Fix RBAC bypass vulnerabilities in model access fix: RBAC bypass vulnerabilities in model access Dec 2, 2025
Copy link
Collaborator

@cdoern cdoern left a comment

Choose a reason for hiding this comment

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

lgtm, one or two nits.

Comment on lines 118 to 124
temp_model = ModelWithOwner(
identifier=model_id,
provider_id=provider_id,
provider_resource_id=provider_resource_id,
model_type=expected_model_type,
type="model",
metadata={}, # Empty metadata for temporary object
)
Copy link
Collaborator

Choose a reason for hiding this comment

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

With no owner and empty metadata, does that have an impact on our RBAC policies? Will this cause checks to pass that should otherwise fail? Or checks to fail that should otherwise pass?

Copy link
Collaborator

Choose a reason for hiding this comment

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

I think this is the temporary ModelWithOwner objects for RBAC validation, meaning is_action_allowed(self.routing_table.policy, "read", temp_model, user): below fails if the user does not have access to the model? so for temp_model the owner doesn't matter, its just for comparison, I think?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes, its a tmp model for policy check, with no owner (by design)

if auth hasn't been enabled then user==None and is_action_allowed will pass, the default doesn't change all models are still available

if auth is enabled then the default policy allows access

if auth is enabled and using a custom policy its upto the user to make sure they allow access to the model with their policy either by name/resource_id or by using other claims in the token (this is the only behaviour that should be changing in this PR, previously a custom policy wasn't restricting anything.

@bbrowning
Copy link
Collaborator

Does this change the default visibility of models in our starter distro and similar setups that don't use a customized RBAC policy? Are all models visible to every user when authentication is disabled? The changes look reasonable as far as enforcement, but it wasn't immediately obvious whether this is also adding additional restrictions in our default case.

@derekhiggins
Copy link
Contributor Author

Does this change the default visibility of models in our starter distro and similar setups that don't use a customized RBAC policy? Are all models visible to every user when authentication is disabled? The changes look reasonable as far as enforcement, but it wasn't immediately obvious whether this is also adding additional restrictions in our default case.

Yup, if not using Authentication nothing should change, the first check in is_action_allowed returns True if auth isn't enabled (user == None)

Closes security gaps where RBAC checks could be bypassed:

o Inference router: Added RBAC enforcement in the fallback
  path to ensure access control is applied consistently.

o Model listing: Dynamic models fetched via provider_data were returned
  without RBAC checks. Added filtering to ensure users only see models
  they have permission to access.

Both fixes create temporary ModelWithOwner objects for RBAC validation,
maintaining security through consistent access control enforcement.

Closes: llamastack#4269

Signed-off-by: Derek Higgins <derekh@redhat.com>
Copy link
Collaborator

@bbrowning bbrowning left a comment

Choose a reason for hiding this comment

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

This looks reasonable and my questions have been addressed. Thanks!

@cdoern cdoern merged commit 8940be2 into llamastack:main Dec 3, 2025
34 checks passed
@cdoern
Copy link
Collaborator

cdoern commented Dec 3, 2025

@Mergifyio backport release-0.3.x

@mergify
Copy link

mergify bot commented Dec 3, 2025

backport release-0.3.x

✅ Backports have been created

mergify bot pushed a commit that referenced this pull request Dec 3, 2025
Closes security gaps where RBAC checks could be bypassed:

o Inference router: Added RBAC enforcement in the fallback
  path to ensure access control is applied consistently.

o Model listing: Dynamic models fetched via provider_data were returned
  without RBAC checks. Added filtering to ensure users only see models
  they have permission to access.

Both fixes create temporary ModelWithOwner objects for RBAC validation,
maintaining security through consistent access control enforcement.

Closes: #4269

Signed-off-by: Derek Higgins <derekh@redhat.com>
(cherry picked from commit 8940be2)

# Conflicts:
#	llama_stack/core/routers/inference.py
#	llama_stack/core/routing_tables/models.py
#	tests/unit/server/test_access_control.py
cdoern pushed a commit that referenced this pull request Dec 3, 2025
Closes security gaps where RBAC checks could be bypassed:

o Inference router: Added RBAC enforcement in the fallback
  path to ensure access control is applied consistently.

o Model listing: Dynamic models fetched via provider_data were returned
  without RBAC checks. Added filtering to ensure users only see models
  they have permission to access.

Both fixes create temporary ModelWithOwner objects for RBAC validation,
maintaining security through consistent access control enforcement.

Closes: #4269

Signed-off-by: Derek Higgins <derekh@redhat.com>
(cherry picked from commit 8940be2)
Signed-off-by: Charlie Doern <cdoern@redhat.com>
cdoern pushed a commit that referenced this pull request Dec 3, 2025
Closes security gaps where RBAC checks could be bypassed:

o Inference router: Added RBAC enforcement in the fallback
  path to ensure access control is applied consistently.

o Model listing: Dynamic models fetched via provider_data were returned
  without RBAC checks. Added filtering to ensure users only see models
  they have permission to access.

Both fixes create temporary ModelWithOwner objects for RBAC validation,
maintaining security through consistent access control enforcement.

Closes: #4269

Signed-off-by: Derek Higgins <derekh@redhat.com>
(cherry picked from commit 8940be2)
Signed-off-by: Charlie Doern <cdoern@redhat.com>
cdoern pushed a commit that referenced this pull request Dec 3, 2025
Closes security gaps where RBAC checks could be bypassed:

o Inference router: Added RBAC enforcement in the fallback
  path to ensure access control is applied consistently.

o Model listing: Dynamic models fetched via provider_data were returned
  without RBAC checks. Added filtering to ensure users only see models
  they have permission to access.

Both fixes create temporary ModelWithOwner objects for RBAC validation,
maintaining security through consistent access control enforcement.

Closes: #4269

Signed-off-by: Derek Higgins <derekh@redhat.com>
(cherry picked from commit 8940be2)
Signed-off-by: Charlie Doern <cdoern@redhat.com>
raise ModelNotFoundError(model_id)

# Create a temporary model object for RBAC check
temp_model = ModelWithOwner(
Copy link
Contributor

Choose a reason for hiding this comment

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

this reads awkward, maybe we need to think about the RBAC API a bit so this "temp model" creation is not necessary

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yup, creating that seemed a little excessive but I couldn't see any way around it

cdoern pushed a commit that referenced this pull request Dec 3, 2025
Closes security gaps where RBAC checks could be bypassed:

o Inference router: Added RBAC enforcement in the fallback
  path to ensure access control is applied consistently.

o Model listing: Dynamic models fetched via provider_data were returned
  without RBAC checks. Added filtering to ensure users only see models
  they have permission to access.

Both fixes create temporary ModelWithOwner objects for RBAC validation,
maintaining security through consistent access control enforcement.

Closes: #4269

Signed-off-by: Derek Higgins <derekh@redhat.com>
(cherry picked from commit 8940be2)
Signed-off-by: Charlie Doern <cdoern@redhat.com>
cdoern pushed a commit that referenced this pull request Dec 3, 2025
)

Closes security gaps where RBAC checks could be bypassed:

o Inference router: Added RBAC enforcement in the fallback
  path to ensure access control is applied consistently.

o Model listing: Dynamic models fetched via provider_data were returned
  without RBAC checks. Added filtering to ensure users only see models
  they have permission to access.

Both fixes create temporary ModelWithOwner objects for RBAC validation,
maintaining security through consistent access control enforcement.

Closes: #4269
<hr>This is an automatic backport of pull request #4270 done by
[Mergify](https://mergify.com).

Signed-off-by: Derek Higgins <derekh@redhat.com>
Signed-off-by: Charlie Doern <cdoern@redhat.com>
Co-authored-by: Derek Higgins <derekh@redhat.com>
r-bit-rry pushed a commit to r-bit-rry/llama-stack that referenced this pull request Dec 3, 2025
Closes security gaps where RBAC checks could be bypassed:

o Inference router: Added RBAC enforcement in the fallback
  path to ensure access control is applied consistently.

o Model listing: Dynamic models fetched via provider_data were returned
  without RBAC checks. Added filtering to ensure users only see models
  they have permission to access.

Both fixes create temporary ModelWithOwner objects for RBAC validation,
maintaining security through consistent access control enforcement.

Closes: llamastack#4269

Signed-off-by: Derek Higgins <derekh@redhat.com>
r-bit-rry pushed a commit to r-bit-rry/llama-stack that referenced this pull request Dec 4, 2025
Closes security gaps where RBAC checks could be bypassed:

o Inference router: Added RBAC enforcement in the fallback
  path to ensure access control is applied consistently.

o Model listing: Dynamic models fetched via provider_data were returned
  without RBAC checks. Added filtering to ensure users only see models
  they have permission to access.

Both fixes create temporary ModelWithOwner objects for RBAC validation,
maintaining security through consistent access control enforcement.

Closes: llamastack#4269

Signed-off-by: Derek Higgins <derekh@redhat.com>

logger.debug(f"Fetched {len(models)} models from provider {provider_id} using provider_data")
# Convert to ModelWithOwner for RBAC check
temp_model = ModelWithOwner(
Copy link
Collaborator

Choose a reason for hiding this comment

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

@derekhiggins we ask providers to return Model, but we always need ModelWithOwner. can we move the ResourceWithOwner up a level in the class hierarcy?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We'd have to look into how difficult it would be but wouldn't be a bad idea, I'd like to add a few simple RBAC policies into the integration auth tests next. Then would be more comfortable with refactors like this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Meta Open Source bot.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ABAC/RBAC Bypass in Model Access

5 participants