Coverage for src/lexigram/auth/policies/types.py: 100%
39 statements
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-25 12:26 +0800
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-25 12:26 +0800
1"""Core types for Lexigram ABAC Policy Engine."""
3from __future__ import annotations
5from dataclasses import dataclass, field
6from enum import StrEnum
7from typing import Any
10class PolicyEffect(StrEnum):
11 ALLOW = "allow"
12 DENY = "deny"
15class DecisionOutcome(StrEnum):
16 ALLOW = "allow"
17 DENY = "deny"
18 INDETERMINATE = "indeterminate"
21@dataclass(frozen=True)
22class Condition:
23 """A condition that must be met for a policy to apply."""
25 attribute: str
26 operator: str
27 value: Any
30@dataclass(frozen=True)
31class Policy:
32 """A granular authorization policy."""
34 policy_id: str
35 name: str
36 effect: PolicyEffect
37 principals: list[str] = field(default_factory=list)
38 actions: list[str] = field(default_factory=list)
39 resources: list[str] = field(default_factory=list)
40 conditions: list[Condition] = field(default_factory=list)
41 priority: int = 0
42 description: str | None = None
45@dataclass(frozen=True)
46class AuthorizationRequest:
47 """A request for authorization evaluation."""
49 principal: str # e.g., "user:123"
50 action: str # e.g., "read"
51 resource: str # e.g., "document:456"
52 context: dict[str, Any] = field(default_factory=dict)
55@dataclass(frozen=True)
56class AuthorizationDecision:
57 """The result of an authorization evaluation."""
59 decision: DecisionOutcome
60 reason: str | None = None
61 applied_policies: list[str] = field(default_factory=list)
64__all__ = [
65 "AuthorizationDecision",
66 "AuthorizationRequest",
67 "Condition",
68 "DecisionOutcome",
69 "Policy",
70 "PolicyEffect",
71]