.ch
Governed by Swiss law · Zürich
The Allée des Nations, Geneva
Access control

Not a layer on top. The engine itself.

Everything is a node. A grant is a sentence about a node and everything under it. One arbiter decides every operation, every time — reads, writes, discovery, grants, erasure — with no cache, no roles and no session state.

Allée des Nations · Palais des Nations · Geneva · 1936

A grant is a sentence.

Grantee may perform ops on this tenant's data, scoped at this node — the node and its entire subtree.” That is the whole model. Vault → category → credential; patient → study → series → slice; company → region → office → user. One tree, one parent_id, one rule.

vault · dossier root — the tenant
├─ Financial ← grant: accountant, r
│  ├─ Bank · UBS
│  ├─ Bank · PostFinance
│  └─ Tax · 2025 return
├─ Personal · not reachable: get, list, search all deny
└─ Work · not reachable
granted nodecovered by inheritance
rread — get, history, list, search, children, objects
wwrite — put, revise, reparent, put_object; implies read
ddelete — tombstone, shred
mmanage — grant and revoke, within scope, within your own ops

One arbiter, every operation.

check_access runs on every put, get, list, search, children, grant, revoke and shred. No cache, no roles, no session state — the decision is always live against the current grants.

Discovery is a read.

List, search and children are scoped by exactly the same rule as opening a record. What you cannot open, you cannot see exists. No counting another tenant's rows, no reading across the boundary, no enumerating a subtree you were not granted. (Within your own tenant a uniqueness constraint can still tell a writer that a value exists on a branch they cannot read — one bit, and only one; see Guarantees.)

A grant is an entry.

Who holds what, at which permission, under which relationship, granted by whom — inside the ciphertext, bound to its row, checksummed, audited. The authorization graph never touches the file in plaintext, so a key-less writer has nothing to forge. Revoking a grant tombstones it, effective immediately.

Revocation cascades.

Revoking a grant tombstones it and, transitively, every grant its grantee issued at or below that node. Tombstoning or shredding a principal retires every grant they hold or ever issued. Delegation trees fall with their root; nothing lingers.

Delegation is bounded.

Only manage covering a node can grant on it, and only ops the granter holds there. A radiology administrator with rm can hand out r inside Radiology — never w, never outside. No self-escalation, no ambient authority.

Owner and System are computed, never stored.

The caller authenticates the accessor; the store enforces. Accessor is a closed enum, and nothing that parses a request can construct System.

Denied is a fact, too.

Every refused read, write, grant or shred is an audit event. Repeats within a window coalesce, so a probing actor is one line with a count, not a flood that hides the signal.

Many tenants, one file.

Two tenants in one store cannot get, list, search, unique-probe or reparent across each other. Isolation is by access, not by copies — and replication ships every tenant's sealed rows under one operator-plane cursor.

Give the accountant Financial.

One grant on one node; the whole subtree follows, including everything filed under it tomorrow. Revoked in one call, audited on both ends.

Give a specialist one study, not the patient.

Grant on the study node: every series and slice under it opens; the rest of the dossier does not exist for them — not in search, not in lists, not in counts.

Why it matters

Least privilege by construction.

Auditors get an authorization model that is a data structure, not a policy document: every effective permission is a sealed row you can list, every change is a chained event, and the rule that decides is one function. HIPAA's minimum necessary, SOC 2's logical access, ISO 27001 A.5 — answered by the shape of the store.