Weekly Planner
Domain model

Permissions

Instant permission rules for boards, events, shares, members, and more.

Permissions

Source: instant.perms.ts.

Summary

EntityViewCreateUpdate / delete
boardsowner, member, or enabled share secretauth + owner is selfowner only
eventssame as board viewowner, editor, or edit secretsame
settingsownerownerowner
sharesboard owner, or token lookup via shareTokenboard ownerboard owner
membersboard owner or selfboard ownerowner; self can delete
boardPrefsselfauth + selfself
todosownerauth + self + rate limitowner
apiTokensowner (hash field hidden)never (server-only)delete: owner; update: never

Bindings (boards)

Typical bindings: isOwner, isMember, isEditor, hasShareSecret.

Share secrets

  • Field rules hide secret / editSecret from everyone except the board owner.
  • Public metadata lookup can find a share by ruleParams.shareToken without exposing secrets. passwordSalt is readable on that lookup so guests can derive the secret client-side.
  • Event writes for share editors must pass ruleParams.secret matching shares.editSecret.

Rate limits ($rateLimits)

Event and todo writes pass through Instant rate limits — token buckets evaluated inside the permission rules:

  • eventWrites: 120/minute burst + 2000/day sustained. Signed-in writers are keyed by auth.id; share-link guests by their ruleParams.secret (each share link gets its own bucket).
  • todoWrites: 300/hour keyed by auth.id.

rateLimit.limit() is the last term in each && chain: CEL short-circuits, so a write that fails ownership checks never consumes a token. Because the REST API impersonates the token owner, these buckets bound API abuse too. Capacities are sized far above interactive use — they exist to stop runaway scripts, not humans.

API tokens

apiTokens rows can be listed and revoked by their owner in the client (the account page uses a live query), but create/update are false: secrets are minted only by /api/tokens through the admin SDK, and the hash field rule hides the stored digest from every client read.

Why /api/invite exists

Clients cannot safely look up arbitrary Instant users by email. Invites verify the caller’s refresh token with the admin SDK, confirm board ownership, resolve the target user, then create/update member + editor links using the same policy helpers as the client (member-policy.js).

On this page