Permission

Permission — universal per-entity ACL grant. Binds (subject, entity, tier). The caller's effective tier on an entity is the max of: - global admin bypass - workspace-member default tier - direct user grant - team grants where the caller is a member - org grants where the caller is a member of the parent org - public grants (any authenticated user) Soft-delete semantics: revoke = soft-delete (`permission.revoked`), restore within retention = `permission.restored`, hard-delete past retention = `permission.purged`. Soft-deleted grants are filtered out of every effective-tier query so a revoked grant cannot grant access even momentarily — same precedent as `verifyApiKey`. Both `entityId` and `subjectId` are polymorphic. The type is encoded in the ID prefix; clients call `detectEntityType` to label them.

Definition

TypeScript
interface Permission {
  id: string;
  workspaceId: string;
  entityId: string;
  subjectId: string | null;
  tier: "viewer" | "editor" | "admin";
  createdBy: string | null;
  deletedAt: string | null;
  deletedBy: string | null;
  retentionTier: "short" | "medium" | "long" | "none" | null;
  createdAt: string;
  updatedAt: string;
}

Fields

FieldTypeNotes
idstringreadonly required
workspaceIdstringrequired — Workspace the grant is scoped to. Used for cascade delete and observability filters.
entityIdstringrequired — Polymorphic FK — the prefixed ID of the target entity. Type encoded in the prefix.
subjectIdstring | nullrequired — Subject of the grant. Null = public; otherwise a usr_… / tem_… / org_… ID.
tier"viewer" | "editor" | "admin"required — Tier this subject holds on the entity.
createdBystring | nullrequired — User who granted this permission. Null if they later left.
deletedAtstring | nullrequired — Set when the grant was revoked (soft-delete). Null while active.
deletedBystring | nullrequired — User who revoked this grant. Null while active.
retentionTier"short" | "medium" | "long" | "none" | nullrequired — Retention horizon after revocation (short ~7d, medium ~30d, long ~90d, none keeps forever). Null while active.
createdAtstringreadonly required — ISO-8601 timestamp the grant was created.
updatedAtstringreadonly required — ISO-8601 timestamp of the last tier change.