Skip to content

FieldPermissionMap

FieldPermissionMap<TData> = { [W in typeof WILDCARD_KEY]: boolean } & Partial<Record<FieldPermissionKey<TData>, boolean>> | Partial<Record<FieldPermissionKey<TData>, boolean>>

Defined in: packages/core/src/access/types.ts:106

A per-field decision for ONE action — what a check resolves to when it answers which fields rather than whether.

Only ever a callback’s RETURN value, never a value written on an action: a document may legitimately carry fields named withIndex, where, or filter, and in a return position there is nothing to disambiguate against.

Values are plain booleans. The map is built inside a callback that already holds { user, data, organization }, so a per-field rule is an ordinary boolean expression — activeTheme: user._id === data.ownerId — rather than a second callback layer receiving props its enclosing callback already closed over.

Two branches, and the union is the enforcement:

  • "*" present → every other field is optional; the wildcard decides them.
  • "*" absent → EVERY gateable field must be named.

So a partial map is a compile error and no field is silently permitted because it was forgotten. An EXCESS key — a misspelling, or a system key — is caught too, but not by this type: excess-property checking does not apply to an object literal returned from a contextually typed arrow, so ValidateFieldMaps catches those structurally through defineAccess’s inferred permissions literal instead.

Deliberately NOT a { mode, fields } shape: that existed to drive QUERY FILTERING through the constraint builder, which Convex cannot express per-field on an index. This map never touches a query — it is evaluated in plain JS against an already-fetched document (read path) or the incoming payload plus the stored document (write path).

TData = unknown

Document type for the subject.