AccessQueryPolicy

The read predicate of each governed aggregate as a QueryPolicy: what a caller may read of it, compiled to a filter (AccessFilters) and appended at admission step 2, right after the scope. An aggregate it does not govern is left to the default rule (ScopeQueryPolicy).

  • Who it reads for. A caller as it is (QueryCaller.caller): its subject, scope and claims are what the predicate compares. Trusted in-process code (no caller) and a service reading as itself are read by no access policy: a service is trusted, bounded by the models wow.callers.<service>.reads lets it read. The tenant still bounds them.

  • Snapshots. Each declared attribute is compared on access.<name>, AccessAttribute.OWNER and AccessAttribute.SPACE on the snapshot's owner and space, and a snapshot whose access attributes are not recorded (access absent) is never read.

  • State reads. The same filter, evaluated on the state's latest record (me.ahoo.wow.query.QueryGateway.admitRecord): its history, a version or a trace, is read by its current attributes.

  • Events. The same predicate on what each stream records of its aggregate's current attributes, access, the owner and the space among them (access.owner, access.space): a stream is stamped again whenever its aggregate's attributes change, so the events of an aggregate show while it shows, whichever commit wrote them. A stream not yet stamped (access null) is never read. An events query need not name its aggregates.

  • Datasets. A dataset whose scope binds a governed aggregate (QueryDataset.scope) reads the rows whose aggregate the predicate lets the caller read by that aggregate's current attributes, whatever a row recorded when it was written: the whole predicate is one restriction (DatasetAccess), which the dataset's storage compiles as one semi-join of the dataset's id column on the aggregates' current access records (on ClickHouse, the Sink's _state). A row whose aggregate the storage holds no attributes of is never read. A predicate that grants every aggregate restricts nothing and reads no access record; on a storage that does not declare StorageSupport.datasetAccess any other predicate reads none of the rows, logged once. A dataset bound to no governed aggregate is left to the default rule.

An attribute the aggregate does not have (AccessPolicies.declares) matches nothing, and is logged once: the policy fails closed. Between a change of an aggregate's attributes and the stamp of its earlier streams, an events query reads those streams by the attributes they were stamped with; its state reads are never behind.

Constructors

Link copied to clipboard
constructor(access: AccessPolicies)

Properties

Link copied to clipboard
open override val order: Int

Right after the scope, before the application's policies.

Functions

Link copied to clipboard
open suspend override fun evaluate(caller: QueryCaller, context: QueryContext<*>): FilterExpression