# gizdb:policy

The DAL's Policy (GIZSTACK-PLATFORM §3 item 5). Grants on records live in one table, `grants`; record ancestry lives in one closure table, `ancestry`, which the writing transaction keeps with the record. Security.decide judges an actor over the grants on a target and its ancestors, read at one snapshot. A record that has no ancestry row has no access (default deny). Only Policy Operations write `grants`; they check the granting actor with `decide` first. A group is a record of type `group`: a grant on it makes its grantee a member, and a grant to Principal.group reaches every member.

```gizlang
import * as Policy from "gizdb:policy";
```

## Types

### `Write`

```gizlang
type Write = { statements: Vec<string>; params: Vec<Value>; rows: Option<i64>; touched: Vec<Touch>; }
```

SQL statements, one text each, and the parameters $1.. they share: a statement gets the first N parameters, N being the highest one it names. When `rows` is set, the first statement must change exactly that many rows, else the transaction is a conflict. Data.write runs a Write.

- `statements`: `Vec<string>`
- `params`: `Vec<M55.Value>`
- `rows`: `_gizlang_sdk_core.Option<i64>`
- `touched`: `Vec<M60.Touch>`

### `Touch`

```gizlang
type Touch = { table: string; key: string; }
```

A row a Write changes (`key` "": any row of the table), for the live views of a store that has no change log of its own.

- `table`: `string`
- `key`: `string`

### `Condition`

```gizlang
type Condition = { sql: string; slots: Vec<Typed.Slot>; params: Vec<Value>; }
```

A SQL condition with the parameters that it numbers from `first`.

- `sql`: `string`
- `slots`: `Vec<M54.Slot>`
- `params`: `Vec<M55.Value>`

## Functions

### `schema`

```gizlang
function schema(): Vec<string>
```

The two tables, created once with the database: their Shapes' DDL.

Effects: fail, read, write, console, io.

### `place`

```gizlang
function place(node: Security.ResourceRef, parent: Option<Security.ResourceRef>): Result<Write, DbError>
```

Statements that place a new record under `parent` (none for a root). Run
them in the transaction that inserts the record. A parent that has no
ancestry row passes nothing on.

Effects: fail.

### `move`

```gizlang
function move(node: Security.ResourceRef, parent: Security.ResourceRef): Result<Write, DbError>
```

Statements that move a placed record, with everything under it, to `parent`.
A move under the record itself, or of a record that is not placed, rolls
the transaction back (ErrorKind.conflict).

Effects: fail.

### `remove`

```gizlang
function remove(node: Security.ResourceRef): Result<Write, DbError>
```

Statements that remove a record and everything under it from Policy: their
grants and their ancestry. Run them with the record's delete.

Effects: fail.

### `grant`

```gizlang
function grant(principal: Security.Principal, target: Security.ResourceRef, role: Security.Role, expires: i64, now: i64, by: Security.Principal): Result<Write, DbError>
```

A grant of `role` on `target` until `expires` (0: no end), replacing an
earlier grant to the same principal.

Effects: fail.

### `revoke`

```gizlang
function revoke(principal: Security.Principal, target: Security.ResourceRef): Result<Write, DbError>
```

The write that removes the grant of PRINCIPAL on TARGET.

Effects: fail.

### `decide`

```gizlang
function decide(source: Source, actor: Security.Principal, target: Security.ResourceRef, needed: Security.Role, now: i64): Result<Security.Decision, DbError>
```

The actor's decision on `target` for the `needed` role at `now`: the target's
ancestry and the grants of the actor, of an agent's person and of their groups
on it, in one snapshot.

Effects: fail, read, write, console, io.

### `commands`

```gizlang
function commands(w: Write): Result<Vec<Statement>, DbError>
```

The statements of `w` as the GizDB engine runs them (Connection.write, Transaction.write): parsed, the first one guarded when `rows` is set.

Effects: fail.

### `reaches`

```gizlang
function reaches(source: Source, actor: Security.Principal, needed: Security.Role, now: i64, row: string, first: i64): Result<Condition, DbError>
```

The SQL condition that a grant of at least `needed` reaches the record that the text expression `row` (a SPACE/TYPE/KEY
reference) names, on the record or on an ancestor: `decide` for many rows at once, so a query selects only what the actor may read.
An agent needs its own grant and its person's grant, under its ceiling; a group does not act. Parameters number from `first`.

Effects: fail, read, write, console, io.

## Constants

### `DEPTH`

```gizlang
const DEPTH = 32
```

The most levels a record inherits grants through (its own row is level 0).

