mirror of
https://github.com/meta-llama/llama-stack.git
synced 2025-12-27 21:21:59 +00:00
feat: allow access attributes for resources to be configured
This allows a set of rules to be defined for determining the access attributes to apply to a particular resource. It also checks that the attributes determined for a new resource to be registered are matched by attributes associated with the request context. Signed-off-by: Gordon Sim <gsim@redhat.com>
This commit is contained in:
parent
0cc0731189
commit
490e77bffa
10 changed files with 402 additions and 19 deletions
54
llama_stack/distribution/resource_attributes.py
Normal file
54
llama_stack/distribution/resource_attributes.py
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This source code is licensed under the terms described in the LICENSE file in
|
||||
# the root directory of this source tree.
|
||||
|
||||
from llama_stack.distribution.access_control import check_access
|
||||
from llama_stack.distribution.datatypes import AccessAttributes, AccessAttributesRule, ResourceWithACL
|
||||
|
||||
|
||||
def match_access_attributes_rule(
|
||||
rule: AccessAttributesRule, resource_type: str, resource_id: str, provider_id: str
|
||||
) -> bool:
|
||||
if rule.resource_type and rule.resource_type.value != resource_type:
|
||||
return False
|
||||
if rule.resource_id and rule.resource_id != resource_id:
|
||||
return False
|
||||
if rule.provider_id and rule.provider_id != provider_id:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
class ResourceAccessAttributes:
|
||||
def __init__(self, rules: list[AccessAttributesRule]) -> None:
|
||||
self.rules = rules
|
||||
self.access_check_enabled = False
|
||||
|
||||
def enable_access_checks(self):
|
||||
self.access_check_enabled = True
|
||||
|
||||
def get(self, resource_type: str, resource_id: str, provider_id: str) -> AccessAttributes | None:
|
||||
for rule in self.rules:
|
||||
if match_access_attributes_rule(rule, resource_type, resource_id, provider_id):
|
||||
return rule.attributes
|
||||
return None
|
||||
|
||||
def apply(self, resource: ResourceWithACL, user_attributes: dict[str, list[str]] | None) -> bool:
|
||||
"""Sets the resource access attributes based on the specified rules.
|
||||
|
||||
Returns True if a matching rule was found for this resource.
|
||||
|
||||
If access checks have been enable, also checks whether the user attributes allow the
|
||||
resource to be created.
|
||||
"""
|
||||
|
||||
resource_attributes = self.get(resource.type, resource.identifier, resource.provider_id)
|
||||
if resource_attributes:
|
||||
if self.access_check_enabled and not check_access(
|
||||
resource.identifier, resource_attributes, user_attributes
|
||||
):
|
||||
raise ValueError(f"Access denied: {resource.type} '{resource.identifier}'")
|
||||
resource.access_attributes = resource_attributes
|
||||
return True
|
||||
return False
|
||||
Loading…
Add table
Add a link
Reference in a new issue