---
title: "Permission"
description: "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."
section: "Reference"
group: "Types"
order: 172
---

## Definition

```ts
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

| Field           | Type                                              | Notes                                                                                                                               |
| --------------- | ------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| `id`            | `string`                                          | `readonly` `required`                                                                                                               |
| `workspaceId`   | `string`                                          | `required` — Workspace the grant is scoped to. Used for cascade delete and observability filters.                                   |
| `entityId`      | `string`                                          | `required` — Polymorphic FK — the prefixed ID of the target entity. Type encoded in the prefix.                                     |
| `subjectId`     | `string \| null`                                  | `required` — Subject of the grant. Null = public; otherwise a `usr_…` / `tem_…` / `org_…` ID.                                       |
| `tier`          | `"viewer" \| "editor" \| "admin"`                 | `required` — Tier this subject holds on the entity.                                                                                 |
| `createdBy`     | `string \| null`                                  | `required` — User who granted this permission. Null if they later left.                                                             |
| `deletedAt`     | `string \| null`                                  | `required` — Set when the grant was revoked (soft-delete). Null while active.                                                       |
| `deletedBy`     | `string \| null`                                  | `required` — User who revoked this grant. Null while active.                                                                        |
| `retentionTier` | `"short" \| "medium" \| "long" \| "none" \| null` | `required` — Retention horizon after revocation (`short` ~7d, `medium` ~30d, `long` ~90d, `none` keeps forever). Null while active. |
| `createdAt`     | `string`                                          | `readonly` `required` — ISO-8601 timestamp the grant was created.                                                                   |
| `updatedAt`     | `string`                                          | `readonly` `required` — ISO-8601 timestamp of the last tier change.                                                                 |
