Warrants
A warrant (std.warrant) is proof that an account's key signed something
every peer refuses and no honest app would sign. Your app uses warrants to
show the members of a space that someone broke the rules, so whoever may
remove members can decide what to do.
Nodes write warrants for you, and every member's node checks the proof itself before it shows an account as flagged. Nothing happens to the account automatically. A peer that has never heard of warrants syncs and judges everything the same. It just shows no flags.
Showing who is flagged
spaces.access(id).flagged lists every account this node has checked proof
against:
const { flagged } = await node.spaces.access(space.id);
// [{ account, key, kind, by, offence }]Each entry is one warrant:
| Field | |
|---|---|
account | The account accused |
key | The key that signed it: one device or app of theirs |
kind | What it broke: chain, standing or access |
by | The account that brought the proof |
offence | The id of the offending version |
Several members may bring proof against one account, so an account can appear more than once.
Show the flag to the space's members. One granted /member/remove may remove
the person with spaces.removeMember(id, did).
Show it to the account itself too. A flag against your own account usually
means one of your keys is being used somewhere it shouldn't be. Revoking that
key with spaces.revoke takes back what it signed.
When a warrant counts
A warrant flags someone only when it:
- is a first version, standing as a record;
- is in
std.warrant, and not against its own writer; - has evidence that is exactly what its ids name, envelope and body;
- proves its kind's check.
Anything else flags nobody. That covers false, malformed and unknown kinds, and it earns the writer nothing either. Each warrant is judged once, whether it holds or not, so a false one costs a node one check.
The record
std.warrant at a fresh key of its writer's
{ kind, evidence: [<version>, <version>?] } retain: trueevidence[0] is the offending version. Its signer's root is the accused
account.
The record's key is the writer's own, so nobody can write its first version
but the writer, the accused least of all. Only that first version counts as
proof. Whoever the space's grants allow may write a later version or delete
it, as for any record, but neither takes the proof back. The writer sets
retain, so the first version is kept whole.
One offence counts once per writer, however many records say it.
Kinds
kind | evidence | Proves |
|---|---|---|
chain | [v, p], both without bodies | p.id = v.prev, and v doesn't follow p |
standing | [v], without its body; not an access collection | In v's own view: its root was no member, the rules said final, or a first version's root had no grant to write it |
access | [v], whole; an access collection | In its own view, v's event is refused by its author's power |
For standing, policies on the body are left out of the grant check.
A version's own view is the access changes its seen names, and
everything they saw, replayed alone. That's what its writer's node had when
it signed. Nothing outside it can change the verdict, so an honest writer
never fails it.
See spec 02 §4 and spec 03 §4.5 for the checks themselves.
How a node writes one
When your node refuses a version that proves one of the kinds above, it writes a warrant of its own. It skips this if one of its own warrants against that account already stands. So one account's misconduct costs each member one warrant at a time.
The node looks through the cheap global view first, and replays the own view only for what that finds broken. A flag can be missed, but is never false. A race, like a write that crossed a removal it hadn't seen, is withdrawn rather than refused, so it earns no warrant.
When a warrant goes away
Like any record, a warrant is withdrawn when its writer is removed by a change whose cutoff doesn't cover it, or revokes the key that signed it (#166).
More kinds are planned after v1, in #148.
The inbox
An inbox is an address you hand out on purpose, so that someone you share no space with can ask to become your contact. They knock, you accept, and you both end up in a private space for two.
Records
Signed JSON that syncs. Write a record and everyone in the space has it; query it and your screen stays live.