angee.graphql.access
REBAC read gating for GraphQL schema surfaces and change payloads.
actor_can_read
def actor_can_read(resource: ObjectRef) -> boolReturn whether the current actor holds read on resource.
The GraphQL-layer read gate for surfaces that anchor visibility on a single REBAC object rather than a per-model resource (e.g. the platform console's platform/explorer anchor, the operator daemon's operator/connection anchor). Callers pass their own anchor as resource so each surface keeps its anchor explicit; an actorless request (no authenticated subject) reads as not allowed.
is_gated_read_axis
def is_gated_read_axis(model: type[models.Model], axis: str) -> boolWhether a (possibly relation-leaf) group-by axis reads a field-gated column.
A dotted axis (party__display_name) is never a field on model, so it would slip past a same-model check; walk its forward to-one relations to the leaf model and gate-check the leaf there — a gated read reached through a relation leaks owner-only values into bucket keys exactly as a direct one does.
ChangeReadGate
class ChangeReadGate()Filter and redact change payloads for one model and actor.
__init__
def __init__(model: type[models.Model], actor: SubjectRef) -> NoneResolve model authorization facts for actor once.
filter
def filter(payload: Mapping[str, Any] | ChangePayload) -> ChangeEvent | NoneReturn a readable change event, or None when hidden.
ActorSelfChangeReadGate
class ActorSelfChangeReadGate(ChangeReadGate)Expose changes only when the changed resource is the subscribing actor.
Self-service schema surfaces use this gate when ordinary row-read permission is intentionally broader than the private event stream. The actor/resource identity is still derived by REBAC; no session or model-specific identifier is reimplemented here.
filter
def filter(payload: Mapping[str, Any] | ChangePayload) -> ChangeEvent | NoneReturn only this actor's own resource change event.