Checking Permissions in Code
Overview
For logic outside a template — route or component guards, services, computed visibility — use the PermissionService from the @onecx/angular-utils library. It validates the same permissions the Conditional rendering[conditional rendering] directives use, but as an API you can call from TypeScript. It caches its results, so repeated checks stay cheap and do not re-query the source on every render.
Under the hood the PermissionService resolves the current user’s permissions through the HAS_PERMISSION_CHECKER injection token, falling back to the User Service when no custom checker is provided. You can swap in your own checker when you control how permissions are resolved.
PermissionService
The PermissionService is the recommended way to validate access in code. It reads through the HAS_PERMISSION_CHECKER token and falls back to the User Service, so it works with a custom checker or the default.
It is registered as part of the @onecx/angular-utils providers — either the full provideAngularUtils() bundle or providePermissionService() on its own. If you have not registered the angular-utils providers yet, add them once in your application:
import { providePermissionService } from '@onecx/angular-utils'
// e.g. in the application's root providers
[providePermissionService()]
hasPermission
hasPermission(permissionKey) returns an observable that emits true only when the current user holds every permission in permissionKey — a single string or a string[]. Results are cached, so checking the same permission more than once (for example across a re-render) does not re-query the source.
import { inject } from '@angular/core'
import { PermissionService } from '@onecx/angular-utils'
const permissionService = inject(PermissionService)
// Check for a single permission
const canDelete$ = permissionService.hasPermission('USER#DELETE')
// Check for multiple permissions (all must be present)
const canManage$ = permissionService.hasPermission(['USER#EDIT', 'USER#EXPORT'])
getPermissions
getPermissions() returns an observable of the current user’s full list of permission keys. It emits the list from the User Service when that service is available, or undefined when only a custom checker is provided.
import { inject } from '@angular/core'
import { PermissionService } from '@onecx/angular-utils'
const permissionService = inject(PermissionService)
// Pipe the permission list as it resolves
permissionService.getPermissions().pipe(
// map/filter the permission list for the current user
)
HAS_PERMISSION_CHECKER
The HAS_PERMISSION_CHECKER injection token lets you replace the default permission source with your own. Both the PermissionService and the Conditional rendering[conditional rendering] directives read through this token first, and only fall back to the User Service when no checker is provided.
A checker implements the HasPermissionChecker interface:
interface HasPermissionChecker {
hasPermission(permissionKey: string | string[]): Promise<boolean>
getPermissions?(): Observable<string[]>
}
Two ready-made providers are available from @onecx/angular-utils:
-
providePermissionChecker()— provides theHAS_PERMISSION_CHECKERtoken backed by the User Service. -
provideAlwaysGrantPermissionChecker()— provides a checker that always grants, which disables the permission system on the UI side. Useful for tests and local development where real permissions are not available.
To plug in your own source, provide the token directly with an implementation of the interface:
import { HAS_PERMISSION_CHECKER, HasPermissionChecker } from '@onecx/angular-utils'
class MyPermissionChecker implements HasPermissionChecker {
// Resolve the permission list from your own backend, feature flag, or test fixture
hasPermission(permissionKey: string | string[]): Promise<boolean> {
const keys = Array.isArray(permissionKey) ? permissionKey : [permissionKey]
// keys.every((key) => permissions.includes(key))
return Promise.resolve(true)
}
}
// e.g. in the application's root providers
[{ provide: HAS_PERMISSION_CHECKER, useClass: MyPermissionChecker }]
User Service
The User Service from the Angular Integration Interface is the default backing source for both the PermissionService and the permission checker. Use it directly when you need the raw permission list or a promise-based check without the caching layer.
hasPermission
hasPermission(permissionKey) resolves to true only when the current user holds every permission in permissionKey — a single string or a string[] — and to true when nothing is passed.
const userService = inject(UserService)
// Check for a single permission
const canDelete = await userService.hasPermission('USER#DELETE')
// Check for multiple permissions (all must be present)
const canManage = await userService.hasPermission(['USER#EDIT', 'USER#EXPORT'])
getPermissions
getPermissions() returns the current user’s full list of permissions as an observable, for the context of the application.
const userService = inject(UserService)
// Pipe the permission list as it resolves
userService.getPermissions().pipe(
// map/filter the permission list for the current user
)
Related
-
Permissions Handling[Permissions Handling] — the feature overview, how permissions reach an application, and the
<RESOURCE>#<ACTION>convention. -
Conditional rendering[Conditional rendering] — the
*ocxIfPermission/*ocxIfNotPermissiondirectives for permission-based UI inside templates. -
User Service — the full
@onecx/angular-integration-interfacereference. -
Checking permissions in code (React)[Checking permissions in code (React)] — the
usePermissionhook /PermissionProviderequivalent for React applications.