Skip to main content

EntityAccessControlStrategy

EntityAccessControlStrategy

@vendure/coreSourcev3.6.0Experimental

An EntityAccessControlStrategy provides three layers of access control:

  1. Gate-level (canAccess): Determines whether a request should be allowed at all, replacing the default Vendure permission evaluation logic. This runs once per request in the AuthGuard.

  2. Pre-loading (prepareAccessControl): Optional async phase that runs once per request after canAccess passes. Use this to pre-load data (e.g. seller IDs, category assignments) for use in the synchronous applyAccessControl() method.

  3. Row-level (applyAccessControl): Filters which entities a user can see by modifying query builders. This runs for every entity query.

The default implementation (DefaultEntityAccessControlStrategy) preserves the existing Vendure permission behavior and performs no row-level filtering. Custom strategies should extend the default class and override the methods they need.

Row-level interception points (only active when applyAccessControl is implemented):

All interception is handled via TransactionalConnection.getRepository(), which returns a Proxy when a strategy with applyAccessControl is configured:

  • Repository methods: find, findOne, findOneOrFail, findAndCount, count are converted to QueryBuilder operations with ACL applied before execution.
  • QueryBuilder terminal methods: createQueryBuilder() returns a Proxy-wrapped QB that applies ACL before getMany, getOne, getOneOrFail, getManyAndCount, getCount, getExists, getRawMany, getRawOne, getRawAndEntities, and stream.

This covers all standard data access paths including ListQueryBuilder.build(), findOneInChannel(), and findByIdsInChannel(), which all use getRepository(ctx, ...) internally.

Example

Ts

Example

Ts
Info

This is configured via the authOptions.entityAccessControlStrategy property of your VendureConfig.

Caution

This API is currently in developer preview and is subject to change in future releases. Feedback welcome.

Signature

canAccess

method(ctx: RequestContext, permissions: Permission[]) => Promise<boolean>

Called once per request in the AuthGuard to determine whether the request should be allowed. This replaces the default Vendure permission evaluation logic, giving full control over gate-level access.

The DefaultEntityAccessControlStrategy implements the standard Vendure permission logic. Custom strategies should extend it and call super.canAccess() to preserve the default behavior.

prepareAccessControl

method(ctx: RequestContext) => Promise<void>

Optional async phase that runs once per request in the AuthGuard, after canAccess() has passed. Use this to pre-load data needed by the synchronous applyAccessControl() method.

For example, you can look up which seller IDs or category assignments the current user has, and stash the results in a WeakMap<RequestContext> for later use in applyAccessControl().

Important: Any database queries in this method should use rawConnection.getRepository() rather than the RequestContext-aware getRepository(ctx, ...), since the latter triggers the access control Proxy and can cause infinite recursion.

applyAccessControl

method(qb: SelectQueryBuilder<T>, entityType: new (...args: any[]) => T, ctx: RequestContext) => void

Apply row-level access control constraints to the given query builder. This method is called synchronously for every entity query that goes through the Vendure data access layer.

This is optional. When not implemented, no row-level filtering is applied and no Proxy is created on getRepository() — giving zero overhead for the default case.

If your access control logic requires async lookups, perform them in prepareAccessControl() and read the cached results here.

DefaultEntityAccessControlStrategy

@vendure/coreSourcev3.6.0Experimental

The default EntityAccessControlStrategy which implements the standard Vendure permission evaluation logic. It checks the @Allow() decorator permissions against the current user's channel permissions.

Custom strategies should extend this class and override canAccess() to customize gate-level permissions, implement prepareAccessControl() for async pre-loading, and/or implement applyAccessControl() to add row-level filtering.

Example

Ts
Signature

canAccess

method(ctx: RequestContext, permissions: Permission[]) => Promise<boolean>

Implements the standard Vendure permission evaluation:

  • No permissions required (@Allow() not set) → allow
  • Permission.Public → allow
  • Otherwise, check ctx.userHasPermissions() or ctx.authorizedAsOwnerOnly
Was this chapter helpful?
Report Issue
Edited Apr 20, 2026·Edit this page