Guard / foldkit-guard
Checking a server at startup
A Source written by hand over a guarded Entity serves every row, and nothing
at request time can tell. GuardServer.validate looks before any request:
ts
GuardServer.validate(Policy, { entities: [Todo], domain: Data, server: backend.server })It throws, naming each:
- for an Entity of
entitieswhose Source lacks the ruleGuardDrizzle.visibleorGuardServer.memorybuilt for it, or theGuardServer.filterbuilt for it; - for a query listing such an Entity without the rule, and a query the server serves that the domain does not declare, whose Entity no one can name;
- for a query whose body filters or orders by a member with a Read rule. A
row comes back without that member, but the query still answers for it: a
cost < $maxhalved twenty times reads the cost the row hid. This holds whoever asks, since one body serves every principal. Where some readers must filter by it, give the value an Entity of its own with a row Read rule: a row a reader may not see is not in their list at all; - for a declared write of such an Entity that does not land through the
GuardServer.writerbuilt for it; - for a live Source of its own over such an Entity, whose stream nothing can check: serve its changes through a live hub;
- for an Entity carrying another set's guards;
- for a field its Source declares
shared(sent to every live subscriber as written) when a Read rule could tell readers apart: the rows',always, the field's own, or, for a relation, its target rows', a target not amongentitiesincluded.
A rule built from another Policy, for another Entity, or for this one before
its guards were attached does not count. Every guarded Entity's Source needs both its rule and its
filter, even one with no member rules yet, so a rule attached later is
applied rather than served past. GuardServer.memory gives both; over
Drizzle, each Source takes its filter, and each binding its visible.
A handler (RemoteServer.mutation) writes what its code writes, which no
check at startup can read.