Skip to content

Conversation

@derekhiggins
Copy link
Contributor

Changed UserInOwnersList.matches() to return False instead of True when a resource's owner attributes are None. This prevents unintended access when resource when owner attributes arn't present.

For example, checking "user in owners teams" now returns False if the resource has no teams attribute, rather than defaulting to True.

Changed UserIsOwner.matches() to return True when a resource has no owner attribute set. This allows access to resources that don't use the owner attribute.

Updated default_policy to use multiple separate "user in owners" AccessRules instead of a single rule with multiple when clauses. With the new fail-closed behavior, only one rule needs to match. Added a "user is owner" rule to handle resources without attribute-based access.

Closes: #4272

@meta-cla meta-cla bot added the CLA Signed This label is managed by the Meta Open Source bot. label Dec 2, 2025
@derekhiggins
Copy link
Contributor Author

@grs would you mind double checking if my thinking is correct here

Copy link
Contributor

@grs grs left a comment

Choose a reason for hiding this comment

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

Makes sense to me.


def matches(self, resource: ProtectedResource, user: User) -> bool:
required = self.owners_values(resource)
if not required:
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe change the name of the required variable, as it now doesn't indicate whether a check is required or not?

Copy link
Contributor

@ashwinb ashwinb left a comment

Choose a reason for hiding this comment

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

Comment from @grs as well as failing tests

class UserIsOwner:
def matches(self, resource: ProtectedResource, user: User) -> bool:
return resource.owner.principal == user.principal if resource.owner else False
return resource.owner.principal == user.principal if resource.owner else True
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm questioning the wisdom of this, As is above
UserIsOwner passes if User is the owner OR the resource has no owner (public)

I wonder if we should have a new rule(UserIsNull)
UserIsOwner: passes if User is the owner
UserIsNull:the resource has no owner (public)

Copy link
Contributor

Choose a reason for hiding this comment

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

Actually, I agree with you, sorry I missed that! I think it would be unexpected for a rule enabled only if the user is the owner to apply when there is no owner.

I think UserIsNull should be OwnerIsNull though, or perhaps even better ResourceIsUnowned.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ack, I'll go with ResourceIsUnowned so ,

CI though up changes I need to make to the prebuild SQL query in _build_default_policy_where_clause (for the default policy), I'm currently going through that, I'll update this once I'm happy with what I have.

@derekhiggins
Copy link
Contributor Author

Comment from @grs as well as failing tests

The tests are failing because of differences in how ProtectedResource/SqlRecord sets owners on public resources vs ResourceWithOwner

So that its clear whats I'm proposing to fix this specific issue I've propose a seperate PR #4284

Once its fixed, I'll have to rebase this PR (with some changes in AuthorizedSqlStore)

Changed UserInOwnersList.matches() to return False instead of True when
a resource's owner attributes are None. This prevents unintended access
when resource when owner attributes aren't present.

For example, checking "user in owners teams" now returns False if the
resource has no teams attribute, rather than defaulting to True.

Added "ResourceIsUnowned" to allow access to unowned resources.

Updated default_policy to use multiple separate "user in owners"
AccessRules instead of a single rule with multiple when clauses. With
the new fail-closed behavior, only one rule needs to match. Added a
"user is owner" rule to handle resources. Also added ResourceIsUnowned
to allow access to unowned resources.

Updated the SQL generated by _build_default_policy_where_clause to
reflect the above changes.

Closes: llamastack#4272

Signed-off-by: Derek Higgins <[email protected]>
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.

Access control allows access to resources belonging to teamless users

3 participants