Class: PermissionService
Defined in: server/access/permission-service.ts:12
Authoring surface for the optional RbacPermissions registry mirror. The
authoritative catalog is in code (definePermissions()); this service
persists it for admin-UI listing and can sync the in-code catalog into the
table.
Extends
Constructors
Constructor
new PermissionService(deps: AccessFeatureDeps): PermissionService;Defined in: server/access/base-access-service.ts:36
Parameters
| Parameter | Type |
|---|---|
deps | AccessFeatureDeps |
Returns
PermissionService
Inherited from
Properties
deps
protected readonly deps: AccessFeatureDeps;Defined in: server/access/base-access-service.ts:34
Inherited from
Accessors
actorId
Get Signature
get protected actorId(): string | null;Defined in: server/access/base-access-service.ts:40
Returns
string | null
Inherited from
Methods
coarsePermissionsForActor()
protected coarsePermissionsForActor(
actor: {
id: string;
type: SubjectType;
},
scope: GrantScope,
now?: Date
): Promise<CoarseActorAuthority>;Defined in: server/access/base-access-service.ts:117
H3: derive an actor's UNCONDITIONALLY-held authority for a target scope —
the delegable set for both GrantService.create's CreateGrantGuard and
RoleService.createVersion's CreateVersionGuard. Only grants the actor
holds with NO selector and NO condition contribute, mirroring
hasCoarsePermission: a narrowly-held permission must not be re-delegable
(as a grant) or re-addable (to a role) unconstrained. Effective-date
validity is honored. Shared here (not duplicated per service) so the two
escalation guards can never drift on what "coarsely held" means.
Derived over scopeChain(scope), so a platform admin can delegate inside
an organization without mode: "system" (which would skip every
escalation guard). The chain is derived here, never accepted as a
parameter — see scopeChain.
scopeKeys reports PROVENANCE: which scopes actually backed the actor.
That is what GrantService's self-org cap reads instead of a
caller-asserted actorOrganizationId, making it server-derived and
unspoofable.
Parameters
| Parameter | Type |
|---|---|
actor | { id: string; type: SubjectType; } |
actor.id | string |
actor.type | SubjectType |
scope | GrantScope |
now | Date |
Returns
Promise<CoarseActorAuthority>
Inherited from
BaseAccessService.coarsePermissionsForActor
create()
create(input: {
action: string;
delegable?: boolean;
description?: string | null;
id?: string;
organizationId?: string | null;
}): Promise<{
action: string;
createdAt: Date;
createdBy: string | null;
delegable: boolean;
deletedAt: Date | null;
deletedBy: string | null;
description: string | null;
id: string;
organizationId: string | null;
updatedAt: Date;
updatedBy: string | null;
}>;Defined in: server/access/permission-service.ts:13
Parameters
| Parameter | Type |
|---|---|
input | { action: string; delegable?: boolean; description?: string | null; id?: string; organizationId?: string | null; } |
input.action | string |
input.delegable? | boolean |
input.description? | string | null |
input.id? | string |
input.organizationId? | string | null |
Returns
Promise<{
action: string;
createdAt: Date;
createdBy: string | null;
delegable: boolean;
deletedAt: Date | null;
deletedBy: string | null;
description: string | null;
id: string;
organizationId: string | null;
updatedAt: Date;
updatedBy: string | null;
}>
listForScope()
listForScope(organizationId: string | null): Promise<{
action: string;
createdAt: Date;
createdBy: string | null;
delegable: boolean;
deletedAt: Date | null;
deletedBy: string | null;
description: string | null;
id: string;
organizationId: string | null;
updatedAt: Date;
updatedBy: string | null;
}[]>;Defined in: server/access/permission-service.ts:24
List catalog rows visible in a scope (org's own + global).
Parameters
| Parameter | Type |
|---|---|
organizationId | string | null |
Returns
Promise<{
action: string;
createdAt: Date;
createdBy: string | null;
delegable: boolean;
deletedAt: Date | null;
deletedBy: string | null;
description: string | null;
id: string;
organizationId: string | null;
updatedAt: Date;
updatedBy: string | null;
}[]>
loadActiveGrants()
protected loadActiveGrants(
repos: AccessRepositories,
subject: Subject,
scopes: GrantScope[]
): Promise<{
conditionLogic: JsonValue;
createdAt: Date;
createdBy: string | null;
deletedAt: Date | null;
deletedBy: string | null;
effectiveEnd: Date | null;
effectiveStart: Date | null;
grantFingerprint: string;
id: string;
organizationId: string | null;
roleId: string;
scopeKey: string;
scopeType: RbacScopeType;
selector: JsonValue;
subjectId: string;
subjectType: RbacSubjectType;
updatedAt: Date;
updatedBy: string | null;
}[]>;Defined in: server/access/base-access-service.ts:70
Security-critical lookup: load a subject's active grants across a set of scopes, expanding org-group membership for non-group subjects. The single source of truth for "which grants apply to this subject right now" — every caller (snapshot compilation, coarse-permission derivation) funnels here so the scopeKey derivation and group-expansion rule can never drift between call sites.
Queried one scope at a time rather than with a single scopeKey IN (…):
group expansion is a PER-SCOPE rule, not a property of the subject. It runs
only for an organization-scoped lookup AND a non-group subject — a
group subject's grants are read directly (it has no "groups" of its own to
expand), and platform scope has no org-group notion, so a group's
platform-scoped grant must NOT reach its members through an org-scoped
chain. Flattening the chain into one query with a unioned groupIds would
silently widen exactly that.
Must be called inside a repos.transaction(...) so the membership reads
and the grant reads share one transaction.
Parameters
| Parameter | Type |
|---|---|
repos | AccessRepositories |
subject | Subject |
scopes | GrantScope[] |
Returns
Promise<{
conditionLogic: JsonValue;
createdAt: Date;
createdBy: string | null;
deletedAt: Date | null;
deletedBy: string | null;
effectiveEnd: Date | null;
effectiveStart: Date | null;
grantFingerprint: string;
id: string;
organizationId: string | null;
roleId: string;
scopeKey: string;
scopeType: RbacScopeType;
selector: JsonValue;
subjectId: string;
subjectType: RbacSubjectType;
updatedAt: Date;
updatedBy: string | null;
}[]>
Inherited from
BaseAccessService.loadActiveGrants
syncCatalog()
syncCatalog(organizationId?: string | null): Promise<number>;Defined in: server/access/permission-service.ts:35
Sync the in-code permission catalog (from definePermissions, wired as
deps.catalog) into the RbacPermissions table for the given scope.
Idempotent: inserts only missing actions. Returns the count inserted.
Parameters
| Parameter | Type | Default value |
|---|---|---|
organizationId | string | null | null |
Returns
Promise<number>
transaction()
protected transaction<T>(fn: (deps: AccessFeatureDeps) => Promise<T>): Promise<T>;Defined in: server/access/base-access-service.ts:44
Type Parameters
| Type Parameter |
|---|
T |
Parameters
| Parameter | Type |
|---|---|
fn | (deps: AccessFeatureDeps) => Promise<T> |
Returns
Promise<T>