Remote / foldkit-remote-drizzle
Which rows a principal may see
authorize decides which fields a principal may read. Which rows exist
for them is the binding's visible: a condition over the table's columns, or
undefined for every row.
ts
const Db = bind(Blog, {
Post: {
table: posts,
// A visitor sees what is published; an author sees every row.
visible: principal => (isAuthor(principal) ? undefined : isNotNull(posts.publishedAt)),
},
})A rule may also answer with an Effect of the condition, for one that must
ask something first (a guard's server-side body), and it is given its own
binding as a second argument, (principal, self), so a rule written before
bind can name the table's columns through self.columns. foldkit-guard
builds its rules that way.
It is on the binding, not on a source, because a table is read four ways and a rule on one would leave three open. Every one applies it:
| The table is read | What a hidden row is |
|---|---|
| by id | not returned, so the client knows it as NotFound |
| as the children of a relation | not listed, not counted by a derived count, and not a gap in a page |
as the target of a one ref | the ref reads null, so it does not say the row exists |
| through a query | not in any page; an id cursor on a hidden row does not resolve |
- A required
onewhose target can be hidden will readnullfor a principal who may not see it, which its schema refuses. Make such a relation{ optional: true }, or make the owner'svisibledepend on the target's. - A relation's own
policiesstill apply, beside the target'svisible. entity(name, table, { visible })takes the same rule.