Source code for oci_policy_analysis.application.core.models.models_iam

"""IAM entity and search models (groups, users, dynamic groups, compartments)."""

from typing import Annotated, Literal, NotRequired, TypedDict


[docs] class Compartment(TypedDict, total=False): """ Model representing an OCI compartment (identity and metadata). Captures id, name, parent, description, path, lifecycle, and tags where available. Adds optional analysis/derived fields for policy statement counts. Optional/derived fields (set after loading and analysis): - statement_count_direct: Number of policy statements directly in this compartment. - statement_count_cumulative: Cumulative policy statements (this + all ancestors in path). """ id: Annotated[str, 'Compartment OCID'] name: Annotated[str, 'Display name of the compartment'] parent_id: Annotated[str, 'Parent compartment OCID'] hierarchy_path: Annotated[str, 'Full compartment hierarchy path, e.g., "ROOT/HR/Payroll"'] description: NotRequired[Annotated[str, 'Description of the compartment']] lifecycle_state: NotRequired[Annotated[str, 'Lifecycle state (e.g., ACTIVE, DELETED)']] tags: NotRequired[ Annotated[dict[str, str], 'Optional. All freeform and defined tags associated with the compartment.'] ] statement_count_direct: NotRequired[ Annotated[int, 'Number of policy statements directly in this compartment (analysis-derived, optional)'] ] statement_count_cumulative: NotRequired[ Annotated[int, 'Cumulative number of policy statements including all ancestors (analysis-derived, optional)'] ]
[docs] class Group(TypedDict): """OCI IAM group.""" domain_name: NotRequired[Annotated[str, 'Identity domain; defaults to Default.']] group_name: Annotated[str, 'Group name.'] group_id: NotRequired[Annotated[str, 'Group ID.']] group_ocid: NotRequired[Annotated[str, 'Group OCID.']] description: NotRequired[Annotated[str, 'Group description.']]
[docs] class User(TypedDict): """OCI IAM user.""" domain_name: NotRequired[Annotated[str, 'Identity domain; defaults to Default.']] user_name: Annotated[str, 'User name.'] user_ocid: NotRequired[Annotated[str, 'User OCID.']] display_name: NotRequired[Annotated[str, 'Display name.']] email: NotRequired[Annotated[str, 'Primary email.']] user_id: NotRequired[Annotated[str, 'User ID.']] groups: NotRequired[Annotated[list[str], 'Group OCIDs.']]
[docs] class ConditionAtom(TypedDict, total=False): """Parsed condition atom for display/evidence.""" id: Annotated[str, 'Atom id within the clause.'] left: Annotated[str, 'Left side expression.'] operator: Annotated[str, 'Operator.'] right: Annotated[str, 'Right side expression.'] normalized_left: Annotated[str, 'Case-normalized left side.'] value_type: Annotated[str, 'Right side value kind.'] evidence_kind: Annotated[str, 'Evidence category.'] subexpression: Annotated[str, 'Raw atom text.']
[docs] class ConditionStructure(TypedDict, total=False): """Parsed rule/where structure for display.""" raw_text: Annotated[str, 'Raw clause text.'] parse_status: Annotated[Literal['parsed', 'partial', 'unsupported', 'absent'], 'Parse status.'] structure: Annotated[str, 'Compact tree summary.'] atoms: Annotated[list[ConditionAtom], 'Flat condition atoms.'] residual_text: Annotated[str, 'Unparsed or residual text.'] warnings: Annotated[list[str], 'Parse warnings.']
[docs] class DynamicGroup(TypedDict): """OCI dynamic group.""" domain_name: NotRequired[Annotated[str, 'Identity domain; defaults to Default.']] domain_ocid: NotRequired[Annotated[str, 'Domain OCID.']] dynamic_group_name: Annotated[str, 'Dynamic group name.'] dynamic_group_ocid: NotRequired[Annotated[str, 'Dynamic group OCID.']] dynamic_group_id: NotRequired[Annotated[str, 'Dynamic group ID.']] matching_rule: NotRequired[Annotated[str, 'Dynamic group matching rule.']] matching_rule_parsed_structure: NotRequired[Annotated[str, 'Parsed matching-rule summary.']] matching_rule_elements: NotRequired[Annotated[str, 'Parsed matching-rule atoms for display.']] matching_rule_structure: NotRequired[Annotated[ConditionStructure, 'Parsed matching-rule structure.']] description: NotRequired[Annotated[str | None, 'Dynamic group description.']] in_use: NotRequired[Annotated[bool, 'True when referenced by policy.']] creation_time: NotRequired[Annotated[str, 'Creation time.']] created_by_ocid: NotRequired[Annotated[str, 'Creator OCID.']] created_by_name: NotRequired[Annotated[str, 'Creator name.']]
[docs] class GroupSearch(TypedDict, total=False): """Group search filters.""" domain_name: Annotated[ list[str], 'Domain names to match.', ] group_name: Annotated[list[str], 'Group names or substrings.'] group_ocid: Annotated[list[str], 'Group OCIDs or substrings.']
[docs] class UserSearch(TypedDict, total=False): """User search filters.""" domain_name: Annotated[ list[str], 'Domain names to match.', ] search: Annotated[ list[str], 'User names/display names or substrings.', ] user_ocid: Annotated[str, 'User OCIDs or substrings.']
[docs] class DynamicGroupSearch(TypedDict, total=False): """Dynamic group search filters.""" domain_name: NotRequired[ Annotated[ list[str], 'Domain names to match.', ] ] dynamic_group_name: NotRequired[Annotated[list[str], 'Dynamic group names or substrings.']] matching_rule: NotRequired[ Annotated[ list[str], 'Matching rule substrings.', ] ] dynamic_group_ocid: Annotated[str, 'Dynamic group OCIDs or substrings.'] in_use: NotRequired[ Annotated[ bool, 'Filter by policy reference status.', ] ]