ScopeGuard at the URL level, and explicit scope filters in each service method at the query level. This page shows both patterns.
ScopeGuard (URL level)
TheScopeGuard runs after PermissionsGuard and before the controller handler. It reads @RequireScope(...) metadata from the route.
Configuration
Scope resolution logic
Service-layer scoping (query level)
Every service method that reads data applies explicit scope filters. This is not automated; it is a convention enforced through code review.Store-scoped queries
Client-scoped queries
Scope propagation through relations
When querying across relations, scope must be maintained. A store-scoped order query follows the chainOrder → Employee → Store → clientId. The service resolves this chain so cross-client data cannot leak through joined queries.
Client narrowing
Client-scoped endpoints accept an optionalclientId query parameter, resolved by resolveRequestedClientId in backend/src/auth/user-scope.ts. The parameter can only narrow a query:
- Admin: filters to the requested client
- HR: honoured only when inside the assigned client; otherwise ignored (role scope is authoritative)
- Store Manager: ignored entirely; store scope is the only filter