Skip to main content

permissions.py

Source: src/sunholo/tools/permissions.py

Functions

permitted_tools(current_user: 'Optional[Dict[str, str]]', requested_tools: 'List[str]', permission_rules: 'List[Dict[str, Any]] | None' = None, default_permissions: 'Dict[str, Any] | None' = None, tool_configs: 'Optional[Dict[str, Any]]' = None, vac_name: 'str' = '', use_cache: 'bool' = True) -> 'Tuple[List[str], Dict[str, Any]]'

Validate and filter tools based on user permissions.

Performs security-critical permission validation:

  1. Checks user email against permission rules
  2. Filters requested tools to allowed set
  3. Merges user-provided configs with defaults
  4. Handles wildcard ("*") config values

Args: current_user: Dict with "email" key, or None for anonymous. requested_tools: List of tool IDs the user wants to use. permission_rules: List of permission rule dicts, each with:

  • "email" or "domain": Pattern to match
  • "tools": List of allowed tool IDs
  • "toolConfigs": Dict of tool-specific configs default_permissions: Default permissions dict with:
  • "tools": Default allowed tools
  • "toolConfigs": Default tool configs tool_configs: User-provided tool configs (overrides defaults where wildcard "*" values are present). vac_name: VAC name for cache key generation. use_cache: Whether to use permission cache.

Returns: Tuple of (filtered_tools, merged_configs).

  • filtered_tools: Only tools the user is allowed to use
  • merged_configs: Tool configs with user values applied to wildcards

batch_permitted_tools(requests: 'List[Tuple[Optional[Dict[str, str]], List[str], Optional[Dict], str]]', permission_rules: 'List[Dict[str, Any]] | None' = None, default_permissions: 'Dict[str, Any] | None' = None) -> 'List[Tuple[List[str], Dict[str, Any]]]'

Process multiple permission requests efficiently.

Groups requests to minimize redundant config loading.

Args: requests: List of (current_user, requested_tools, tool_configs, vac_name). permission_rules: Shared permission rules. default_permissions: Shared default permissions.

Returns: List of (filtered_tools, merged_configs) results.

check_tag_permissions(user_email: 'Optional[str]', tags: 'List[str]', tag_permissions: 'Dict[str, Dict[str, Any]]', owner_email: 'str' = '') -> 'bool'

Check if a user has permission to access resources with given tags.

Access types:

  • "public": Anyone can access
  • "private": Only owner
  • "domain": Same domain as owner
  • "domains": User's domain in allowed list
  • "specific": User's email in allowed list
  • "group": User in allowed groups

Args: user_email: User's email (None for anonymous). tags: Tags on the resource. tag_permissions: Permission rules per tag. owner_email: Resource owner's email.

Returns: True if user has access to at least one tag.

create_permission_cache_key(user_email: 'str', tools: 'List[str]', config: 'Dict[str, Any] | None' = None, vac_name: 'str' = '') -> 'str'

Create a stable cache key from permission request parameters.

Args: user_email: User email. tools: Requested tools list. config: Tool configs dict. vac_name: VAC name.

Returns: MD5 hash string.

extract_domain(email: 'str') -> 'Optional[str]'

Extract domain from an email address.

Args: email: Email address string.

Returns: Lowercase domain, or None if invalid.

filter_tools_by_tags(user_email: 'Optional[str]', requested_tools: 'List[str]', tool_tags: 'Dict[str, List[str]]', tag_permissions: 'Dict[str, Dict[str, Any]]', owner_email: 'str' = '') -> 'List[str]'

Filter tools based on tag-level permissions.

Args: user_email: User's email. requested_tools: Tools the user wants to use. tool_tags: Mapping of tool_id -> list of tags. tag_permissions: Permission rules per tag. owner_email: Owner email for private/domain checks.

Returns: Filtered list of tools the user can access.

Classes

PermissionCache

Time-based cache for permission results.

Prevents redundant permission computation for repeated requests within the TTL window.

Args: max_size: Maximum cache entries. ttl_seconds: Time-to-live for cache entries in seconds.

  • init(self, max_size: 'int' = 500, ttl_seconds: 'int' = 300)

    • Initialize self. See help(type(self)) for accurate signature.
  • _cleanup_expired(self) -> 'None'

    • No docstring available.
  • _is_expired(self, key: 'str') -> 'bool'

    • No docstring available.
  • clear(self) -> 'None'

    • Clear all cached values.
  • get(self, key: 'str') -> 'Any'

    • Get cached value, or None if expired/missing.
  • set(self, key: 'str', value: 'Any') -> 'None'

    • Set a cached value with current timestamp.
Sunholo Multivac

Get in touch to see if we can help with your GenAI project.

Contact us

Other Links

Sunholo Multivac - GenAIOps

Copyright ©

Holosun ApS 2026