Some checks are pending
Bidi Control Character Guard / bidi-control-guard (push) Waiting to run
Circular Dependency Check / Check for new circular dependencies (push) Waiting to run
Citus Migration Smoke / Combined migrations on single-node Citus (push) Waiting to run
E2E Fresh Install Tests / fresh-install-e2e (push) Waiting to run
ext-v2 guardrails / Run ext-v2 guard and ESLint (push) Waiting to run
Integration Tests / Check for relevant changes (push) Waiting to run
Integration Tests / ${{ (github.event_name == 'schedule' || github.event.inputs.suite == 'full') && 'Full integration suite' || 'Tier-1 integration subset' }} (push) Blocked by required conditions
Mobile checks / Mobile lint + typecheck (push) Waiting to run
Mobile checks / Mobile unit tests (push) Waiting to run
Mobile checks / Mobile dependency audit (report) (push) Waiting to run
Mobile checks / Mobile reproducibility checks (push) Waiting to run
Secrets guard (env backups) / Ensure no tracked env backup files (push) Waiting to run
Temporal Readiness / fast-readiness (push) Waiting to run
Temporal Readiness / docker-parity (push) Waiting to run
TypeScript Type Check / Nx affected typecheck (push) Waiting to run
Unit Tests / Skipped-test budget (push) Waiting to run
Unit Tests / Nx affected unit tests (push) Waiting to run
Unit Tests / Server unit coverage (informational) (push) Waiting to run
Validate Tenant Management Schema / Check for relevant changes (push) Waiting to run
Validate Tenant Management Schema / Validate Tenant Management Schema (push) Blocked by required conditions
EE Workflows Build Guard / ee-workflows-build-guard (push) Waiting to run
Excluded: .git, node_modules, secrets/, compose.env, assemblyscript tgz Source: /opt/alga-psa on psa.joliet.tech
40 KiB
40 KiB
Scratchpad — Advanced Authorization Kernel and Premium ABAC Bundles
- Plan slug:
premium-abac-authorization-kernel - Created:
2026-04-21
What This Is
Keep a lightweight, continuously-updated log of discoveries and decisions made while implementing this plan.
Prefer short bullets. Append new entries as you learn things, and also update earlier notes when a decision changes or an open question is resolved.
Decisions
- (2026-04-21) The product direction is a comprehensive authorization-kernel overhaul rather than a small ABAC bolt-on.
- (2026-04-21) The design should follow the ALGA plan approach with
PRD.md,features.json,tests.json, andSCRATCHPAD.mdunderee/docs/plans/. - (2026-04-21) The old policy DSL should be treated as abandoned scaffolding and not evolved into the main runtime direction.
- (2026-04-21) Configurable ABAC should use admin-configurable templates, not arbitrary expressions.
- (2026-04-21) The most important first-class relationship concepts are owns / manages / assigned / same client / client portfolio / selected boards.
- (2026-04-21) Configured premium ABAC is narrowing-only; it must never widen access beyond RBAC + built-in kernel behavior.
- (2026-04-21) The shared authorization runtime should exist in CE and EE so existing ABAC-like product rules can be normalized without forking security behavior by edition.
- (2026-04-21) The EE-only seam is the configurable control plane: bundle CRUD, assignments, publishing, simulation, and governance UX.
- (2026-04-21) Configurable premium ABAC management is officially gated at the existing Premium tenant tier by default.
- (2026-04-21) The packaging model should mirror existing EE plugin/provider seams: one stable interface, CE builtin implementation, EE configurable implementation.
- (2026-04-21) Bundle assignments should support roles, teams, users, and API keys.
- (2026-04-21) Bundle assignments should use one generic assignment table keyed by
target_type + target_id. - (2026-04-21) Bundle changes should use a draft → publish model rather than editing active policy in place.
- (2026-04-21) The primary admin artifact should be a bundle, not a raw policy row.
- (2026-04-21) The first configurable resource families are tickets, documents, time, billing, projects, and assets, with API-key scoping treated as cross-cutting.
- (2026-04-21) The EE simulator should support both real principals/records and synthetic scenarios.
- (2026-04-21) The migration must explicitly document and validate current behavior parity before and after cutover.
Discoveries / Constraints
- (2026-04-21) Core RBAC is currently centered in
server/src/lib/auth/rbac.tsandpackages/db/src/models/user.tsvia role/permission lookup plus MSP/client portal gating. - (2026-04-21) There are multiple copies of RBAC and policy-engine code (
server,packages/auth,packages/tags,ee/server), which reinforces the need for a single shared runtime contract. - (2026-04-21) The codebase already contains important production ABAC-like behavior that should become built-in kernel rules rather than optional premium overlays.
- (2026-04-21)
packages/tickets/src/lib/clientPortalVisibility.tsis the clearest existing shared scope-filter example and is a strong model for list/query narrowing. - (2026-04-21)
packages/scheduling/src/actions/timeEntryDelegationAuth.tsalready expresses a high-value managed-hierarchy relationship model (self,manager,tenant-wide). - (2026-04-21)
server/src/app/api/documents/view/[fileId]/route.tscontains a large amount of inline relationship/visibility logic that should be kernelized carefully and fail-closed. - (2026-04-21)
packages/client-portal/src/actions/client-portal-actions/visibilityGroupActions.tsdemonstrates same-client and client-admin relationship guards that belong in the shared kernel, not only in premium configuration. - (2026-04-21) API-key-backed controllers such as
server/src/lib/api/controllers/ApiBaseController.tsandApiTicketController.tsare mostly RBAC-only today and are a likely parity gap compared with UI/server-action flows. - (2026-04-21) There is a legacy
policiestable and policy UI scaffolding, but runtime evaluation does not appear to rely on it as the authoritative production path. - (2026-04-21) The dev seed
server/seeds/dev/49_policies.cjsreferences stale concepts likedepartment, confirming drift in the old DSL path. - (2026-04-21) Existing EE gating patterns already exist in the repo:
- edition detection via
server/src/lib/features.ts - tier gating via
server/src/lib/tier-gating/assertTierAccess.tsandServerTierGate.tsx - feature-tier mapping in
packages/types/src/constants/tierFeatures.ts - Teams-style availability logic in
packages/integrations/src/lib/teamsAvailability.ts
- edition detection via
- (2026-04-21) The product already uses stable CE/EE entrypoint aliasing (for example
packages/product-auth-ee/{oss,ee}/entry*), which is the preferred packaging pattern for the configurable authorization seam.
Commands / Runbooks
- (2026-04-21) Search for RBAC/ABAC-related code and existing inline rules:
rg -n --hidden --glob '!node_modules' --glob '!dist' "\bABAC\b|attribute[- ]based|access policy|policy engine|scope filter|row[- ]level|hasPermission\(|role_permissions|permissions|is_client_admin|portal_visibility_group_id|isInReportsToChain|approval_status|is_client_visible" packages server ee - (2026-04-21) Find policy-engine and legacy DSL scaffolding:
rg -n --hidden --glob '!node_modules' --glob '!dist' "class PolicyEngine|evaluateAccess\(|parsePolicy|policyActions|policies\b" packages server ee - (2026-04-21) Inspect current Teams-style edition/tier gating references:
rg -n --hidden --glob '!node_modules' --glob '!dist' "tier-gating|TIER_FEATURES|Teams integration|teamsAvailability|isEnterprise" packages server ee - (2026-04-21) Scaffold an ALGA plan folder:
python3 /Users/roberisaacs/.agents/skills/alga-plan/scripts/scaffold_plan.py "Advanced Authorization Kernel and Premium ABAC Bundles" --slug premium-abac-authorization-kernel
Links / References
packages/auth/src/lib/getSession.tspackages/auth/src/lib/getCurrentUser.tspackages/auth/src/lib/withAuth.tsserver/src/lib/auth/rbac.tspackages/db/src/models/user.tspackages/tickets/src/lib/clientPortalVisibility.tspackages/scheduling/src/actions/timeEntryDelegationAuth.tsserver/src/app/api/documents/view/[fileId]/route.tspackages/client-portal/src/actions/client-portal-actions/visibilityGroupActions.tsserver/src/lib/api/controllers/ApiBaseController.tsserver/src/lib/api/controllers/ApiTicketController.tspackages/auth/src/actions/policyActions.tspackages/product-auth-ee/oss/entry.tsxpackages/product-auth-ee/ee/entry.tsserver/src/lib/features.tsserver/src/lib/tier-gating/assertTierAccess.tsserver/src/lib/tier-gating/ServerTierGate.tsxpackages/types/src/constants/tierFeatures.tspackages/integrations/src/lib/teamsAvailability.tsee/docs/plans/2026-04-21-premium-abac-authorization-kernel/CURRENT_AUTHORIZATION_BASELINE.mdcontext.mdresearch.md
Open Questions
- Which exact project and asset surfaces are in the first migration wave under the shared kernel versus the second wave?
- Which billing fields participate in v1 redaction, and which wait for a later phase?
- Which API surfaces are in the first parity wave once the shared kernel exists?
Progress Log
- (2026-04-21) Completed
F001: validated and retainedCURRENT_AUTHORIZATION_BASELINE.mdas the parity contract for tickets/documents/time/projects/assets/billing/client-portal/API-key behaviors. - (2026-04-21) Completed
F002by introducing a shared kernel contract atserver/src/lib/authorization/kernel/contracts.tswith common entry points for single-resource authorization, scope resolution, mutation authorization, field redactions, and explainability. - (2026-04-21) Completed
F003with CE builtin providerBuiltinAuthorizationKernelProvider(server/src/lib/authorization/kernel/providers/builtinProvider.ts) that evaluates only builtin product rules. - (2026-04-21) Completed
F004by introducing bundle overlay provider plumbing (BundleAuthorizationKernelProvider) plus EE kernel factory (ee/server/src/lib/authorization/kernel.ts) and CE stub seam (packages/ee/src/lib/authorization/kernel.ts). - (2026-04-21) Completed
F005with edition-aware runtime loading (server/src/lib/authorization/kernel/enterpriseEntry.ts+index.ts) so callers use one kernel interface withoutisEnterprise()branching. - (2026-04-21) Completed
F006: kernel engine now hard-gates on RBAC first (server/src/lib/authorization/kernel/engine.ts) before builtin/bundle narrowing logic. - (2026-04-21) Completed
F007via shared relationship template evaluators inserver/src/lib/authorization/kernel/relationships.tsforown,assigned,managed,same_client,client_portfolio,same_team, andselected_boards. - (2026-04-21) Completed
F008with explicit intersection composition inserver/src/lib/authorization/kernel/scope.ts(intersectAuthorizationScopes). - (2026-04-21) Completed
F009by adding shared mutation-guard evaluation through builtin provider hooks andauthorizeMutationin the kernel engine. - (2026-04-21) Completed
F010by adding shared redaction hook support throughresolveFieldRedactionsand provider-level field redaction resolvers. - (2026-04-21) Completed
F011by emitting structured stage-aware reasons (rbac,builtin,bundle,mutation,redaction) in every decision path. - (2026-04-21) Completed
F012with request-local memoization support (RequestLocalAuthorizationCache) and RBAC memoization in the kernel engine. - (2026-04-21) Validation runbook for this checkpoint:
cd server && npx vitest run src/test/unit/authorization/kernel.engine.test.ts src/test/unit/authorization/kernel.relationships.test.tscd .. && npx tsc --pretty false --noEmit -p server/tsconfig.json
- (2026-04-21) Completed
F013: added regression boundary testserver/src/test/unit/authorization/kernel.legacyDirection.test.tsto enforce that the new kernel path does not import legacy policy DSL runtime modules; this codifies the cutover direction before resource-family migrations. - (2026-04-21) Completed
F014-F017with migrationserver/migrations/20260421190000_create_authorization_bundle_control_plane.cjsintroducingauthorization_bundles,authorization_bundle_revisions,authorization_bundle_rules, and genericauthorization_bundle_assignments. - (2026-04-21) Completed
F018with tenant-scoped assignment target validation increateBundleAssignment(...)(server/src/lib/authorization/bundles/service.ts) for role/team/user/api_key targets. - (2026-04-21) Completed
F019-F021by modeling lifecycle states (active/archived,draft/published/archived,active/disabled) plus transactional publish, bundle archive, and assignment enable/disable service operations. - (2026-04-21) Completed
F022andF023with bundle-resolution logic that aggregates active role/team/user/api_key assignments, resolves published revision rules, and applies them through kernel intersection semantics. - (2026-04-21) Completed
F024andF025via typed catalog enforcement inserver/src/lib/authorization/bundles/catalog.tsand expanded relationship template support (own_or_assigned,own_or_managed,selected_clients). - (2026-04-21) Completed
F026by adding support hooks fornot_self_approver,client_visible_only, andhide_sensitive_fieldsconstraint behavior in bundle evaluation. - (2026-04-21) Completed
F027by shipping starter bundle definitions inserver/src/lib/authorization/bundles/starterBundles.tsfor assigned-client technician, project delivery team, time manager, restricted asset operator, and finance reviewer scenarios. - (2026-04-21) Completed
T001andT002:T001: baseline artifact validated and maintained.T002: migration contract test added atserver/src/test/unit/migrations/authorizationBundleControlPlaneMigration.test.tsto assert control-plane schema shape and narrowing-only constraints.
- (2026-04-21) Additional validation runbook for this checkpoint:
cd server && npx vitest run src/test/unit/authorization/kernel.engine.test.ts src/test/unit/authorization/kernel.relationships.test.ts src/test/unit/authorization/kernel.legacyDirection.test.ts src/test/unit/authorization/bundle.catalog.test.ts src/test/unit/authorization/bundle.provider.test.ts src/test/unit/authorization/starterBundles.test.ts src/test/unit/migrations/authorizationBundleControlPlaneMigration.test.tscd .. && npx tsc --pretty false --noEmit -p server/tsconfig.json
- (2026-04-21) Completed
F028by replacing EEPolicyManagementwith a tier-gated Authorization Bundle Library surface:- UI:
ee/server/src/components/settings/policy/PolicyManagement.tsx - Actions:
ee/server/src/lib/actions/auth/authorizationBundleActions.ts - Service additions for list/create/clone:
server/src/lib/authorization/bundles/service.ts - Tier feature gate:
TIER_FEATURES.ADVANCED_AUTHORIZATION_BUNDLESinpackages/types/src/constants/tierFeatures.ts
- UI:
- (2026-04-21)
F028implementation details:- Browse/search active+archived bundles from
authorization_bundles. - Clone bundle into new draft-backed custom bundle while copying source revision rules.
- Archive active bundles.
- Seed starter bundles into tenant scope via one action.
- Tier enforcement is server-side (
assertTierAccess) and client-side (useTierFeature) with Premium minimum tier.
- Browse/search active+archived bundles from
- (2026-04-21) Completed
T003with DB-backed integration coverage inserver/src/test/integration/authorization/bundleRevisionPublishing.integration.test.tsvalidating:- publish moves previous published revision to archived
- target draft revision becomes published
- stable bundle identity and assignment rows are preserved
- (2026-04-21) Validation runbook for
F028+T003checkpoint:cd packages/types && npx vitest run src/constants/tierFeatures.test.ts --coverage.enabled=falsemkdir -p server/coverage/.tmp && cd server && npx vitest run --coverage.enabled=false src/test/integration/authorization/bundleRevisionPublishing.integration.test.tscd .. && npx tsc --pretty false --noEmit -p server/tsconfig.json
- (2026-04-21) Completed
F029by extending EE policy settings to include a draft-oriented Bundle Editor in resource sections (Tickets, Documents, Time, Projects, Assets, Billing), replacing raw policy text editing:- UI editor surface:
ee/server/src/components/settings/policy/PolicyManagement.tsx - Draft editor actions:
getAuthorizationBundleDraftEditorAction,upsertAuthorizationBundleDraftRuleAction,deleteAuthorizationBundleDraftRuleActioninee/server/src/lib/actions/auth/authorizationBundleActions.ts - Draft helpers in service layer:
ensureDraftBundleRevision,listBundleRulesForRevision,deleteBundleRuleinserver/src/lib/authorization/bundles/service.ts
- UI editor surface:
- (2026-04-21)
F029rationale: enforce draft-first authoring semantics by materializing/rehydrating a draft revision from the currently published revision when no draft exists, then editing only draft rules grouped by resource family. - (2026-04-21) Completed
F030by adding human-readable summaries for both bundle-level and rule-level understanding:- Rule summaries in editor rows (
Narrow <resource> <action> to ...) generated inee/server/src/components/settings/policy/PolicyManagement.tsx. - Effective bundle summaries in library rows (status + assignment impact text).
- Draft-vs-published revision summary generated server-side in
getAuthorizationBundleDraftEditorAction(ee/server/src/lib/actions/auth/authorizationBundleActions.ts) and rendered in the editor header.
- Rule summaries in editor rows (
- (2026-04-21) Completed
F031by adding an Assignment Manager panel to the EE bundle surface:- New action
listAuthorizationBundleAssignmentsActionresolves assignment targets across role/team/user/api_key with friendly labels. - UI now has per-bundle
Assignmentstoggle showing grouped assignment cards and status. - Files:
ee/server/src/lib/actions/auth/authorizationBundleActions.ts,ee/server/src/components/settings/policy/PolicyManagement.tsx.
- New action
- (2026-04-21) Completed
F032by adding an EE Access Simulator for real principals + existing records:- Principal lookup action:
listAuthorizationSimulationPrincipalsAction. - Record lookup action by resource family:
listAuthorizationSimulationRecordsAction. - Simulation execution:
runAuthorizationBundleSimulationActioncompares draft vs published revision decisions with explainability codes. - UI: simulator panel in
ee/server/src/components/settings/policy/PolicyManagement.tsx.
- Principal lookup action:
- (2026-04-21) Completed
F033by extending the simulator with synthetic scenarios:- Added synthetic record input (
ownerUserId,clientId,boardId,isClientVisible) when no real record is suitable. - Simulation action now supports
syntheticRecordpayloads and runs the same draft-vs-published decision flow.
- Added synthetic record input (
- (2026-04-21) Completed
F034by tightening unavailable/upgrade states for non-entitled contexts:- EE tier-gate surface already blocks with
useTierFeature(TIER_FEATURES.ADVANCED_AUTHORIZATION_BUNDLES). - CE placeholder copy updated (
packages/ee/src/components/settings/policy/PolicyManagement.tsx) to show Premium upgrade path while clarifying builtin authorization remains active.
- EE tier-gate surface already blocks with
- (2026-04-21) Completed
F035by adding explicit server-side permission/tier gates to bundle management actions:- CRUD + editor + simulator + assignment + publish actions all enforce
assertTierAccess(TIER_FEATURES.ADVANCED_AUTHORIZATION_BUNDLES)plus RBAC permission checks (system_settings:read|write). - Added write-gated actions for publish and assignment status changes in
ee/server/src/lib/actions/auth/authorizationBundleActions.ts.
- CRUD + editor + simulator + assignment + publish actions all enforce
- (2026-04-21) Completed
F036by exposing an audit-trail read model from persisted bundle metadata:- Added
getAuthorizationBundleAuditTrailActionreturning chronological lifecycle events for bundle creation/archive, draft creation, publish events, and assignment changes. - Uses existing metadata columns (
created_by,updated_by,published_by, timestamps, assignment status) as authoritative audit source.
- Added
- (2026-04-21) Completed
F037for selected server-action paths by moving ticket list/detail authorization to shared kernel checks after RBAC:packages/tickets/src/actions/ticketActions.tsnow resolves authorization subject context and calls kernelauthorizeResourceforgetTicketsForListandgetTicketById.- List path applies kernel decision filtering to ticket rows; single-ticket path denies when kernel disallows.
- Current cut keeps builtin-kernel path for these endpoints; premium ticket bundle overlays are tracked separately in
F039.
- (2026-04-21) Validation for
F037path-level cutover:cd packages/tickets && npx vitest run src/actions/ticketActions.ticketOrigin.test.ts src/actions/ticketActions.moveToBoard.test.ts --coverage.enabled=false
- (2026-04-21) Completed
F038by kernelizing selected-board narrowing for client-portal style ticket access in selected ticket action paths:- Added client visibility-group board resolution via
getClientContactVisibilityContext(...). - For client principals, ticket list/detail now pass
selectedBoardIdsinto kernel evaluation withselected_boardsrelationship template and fail-closed behavior when visibility context is missing/invalid. - Added client-scope guard (
clientId) alongside board narrowing for list/detail parity.
- Added client visibility-group board resolution via
- (2026-04-21) Completed
F039by enabling premium bundle overlays on selected ticket list/detail paths:- Ticket actions now instantiate kernel with a bundle provider that resolves active published bundle rules for the current principal (
resolveBundleNarrowingRulesForEvaluation). - Bundle template semantics are now enforced in bundle provider (
bundle_template_denied) by evaluating each matching rule’s relationship template against record context. - This enables ticket narrowing from bundle templates like assignment/client/team/selected-board in the migrated ticket paths.
- Ticket actions now instantiate kernel with a bundle provider that resolves active published bundle rules for the current principal (
- (2026-04-21) Completed
F040by migrating selected document server-action list/detail/download paths to the shared kernel:- Added shared document auth helpers in
packages/documents/src/actions/documentActions.tsfor principal resolution, relationship-context normalization fromdocument_associations, and per-record kernel evaluation. - Migrated
getDocument,getAllDocuments,getDocumentsByEntity,getDocumentsByFolder, anddownloadDocumentto runauthorizeResourcethrough the kernel after RBAC. - Preserved client-user semantics by enforcing
own OR same_clientrelationship checks plus fail-closedis_client_visibleguard on non-owned records.
- Added shared document auth helpers in
- (2026-04-21) Completed
F041by enabling premium document bundle overlays on migrated document paths:- Document actions now instantiate a bundle provider backed by
resolveBundleNarrowingRulesForEvaluation(...). - Document record context passed to kernel now includes
clientId,teamIds, andis_client_visible, enabling client/portfolio-style narrowing andclient_visible_onlyenforcement where configured.
- Document actions now instantiate a bundle provider backed by
- (2026-04-21) Completed
F042by wiring document field-redaction hooks into migrated document surfaces:- Migrated list/detail document actions now apply kernel-provided
redactedFieldsto returned document payloads without mutating allow/deny behavior. - Redaction plumbing is centralized via
authorizeAndRedactDocuments(...).
- Migrated list/detail document actions now apply kernel-provided
- (2026-04-21) Validation runbook for
F040-F042checkpoint:cd packages/documents && npx tsc --pretty false --noEmit -p tsconfig.jsoncd .. && npx tsc --pretty false --noEmit -p server/tsconfig.jsoncd server && npx vitest run src/test/unit/authorization/kernel.engine.test.ts src/test/unit/authorization/bundle.provider.test.ts --coverage.enabled=false
- (2026-04-21) Completed
F043by kernelizing selected time/timesheet delegation checks through shared relationship semantics:packages/scheduling/src/actions/timeEntryDelegationAuth.tsnow resolves managed scope (teamsmanager + optional reports-to chain) and evaluates non-self delegation with kernelmanagedrelationship templates viaauthorizeResource.- Preserved delegation hierarchy:
selfshort-circuit,timesheet:approveprerequisite,timesheet:read_alltenant-wide override, then manager/reports-to managed scope. fetchTimeSheetsForApprovalnow uses the same managed-subject resolver to scope approval list visibility consistently with delegation rules.
- (2026-04-21) Validation runbook for
F043checkpoint:cd packages/scheduling && npx tsc --pretty false --noEmit -p tsconfig.jsoncd .. && npx tsc --pretty false --noEmit -p server/tsconfig.jsoncd packages/scheduling && npx vitest run tests/timeEntryCrud.changeRequests.test.ts tests/timeSheetClient.reopen.test.tsx --coverage.enabled=false(known pre-existing failure inT012mock chain:db(...).leftJoin is not a function)
- (2026-04-21) Completed
F044by enabling premium time narrowing overlays in delegation evaluation:assertCanActOnBehalfnow composes built-in delegation and premium bundle narrowing by addingBundleAuthorizationKernelProviderwithresolveBundleNarrowingRulesForEvaluation(...).- For
timesheet:read_allprincipals, builtin delegation now allows broad scope, while bundle templates can narrow that scope (for example to managed-only/self-only behavior) without widening baseline RBAC/delegation. - Result scope classification remains explicit (
managerwhen subject is in managed set, otherwisetenant-wideonly when read-all plus kernel allow).
- (2026-04-21) Validation runbook for
F044checkpoint:cd packages/scheduling && npx tsc --pretty false --noEmit -p tsconfig.jsoncd .. && npx tsc --pretty false --noEmit -p server/tsconfig.json
- (2026-04-21) Completed
F045by kernelizing not-self-approver checks in selected time approval flows:- Added
assertCanApproveSubject(...)inpackages/scheduling/src/actions/timeEntryDelegationAuth.ts, which composes delegation checks with kernelauthorizeMutationforapprovemutations. - Added a built-in mutation guard (
timesheet_not_self_approver_denied) and bundle-aware mutation overlay evaluation (not_self_approverconstraint) so approval gating is centralized in kernel semantics. - Wired approval paths to the new guard:
packages/scheduling/src/actions/timeSheetActions.ts(approveTimeSheet,bulkApproveTimeSheets)packages/scheduling/src/actions/timeEntryCrudActions.ts(updateTimeEntryApprovalStatuswhen transitioning toAPPROVED)
- Added
- (2026-04-21) Validation runbook for
F045checkpoint:cd packages/scheduling && npx tsc --pretty false --noEmit -p tsconfig.jsoncd .. && npx tsc --pretty false --noEmit -p server/tsconfig.json
- (2026-04-21) Completed
F046by migrating selected project comment authorization semantics to kernel evaluation:packages/projects/src/actions/projectTaskCommentActions.tsnow enforces non-internal comment edit/delete access via kernelownrelationship evaluation on the comment owner record.- Preserved prior behavior exactly for internal users (retain full edit/delete capability), while non-internal users must satisfy
ownsemantics through the shared kernel path. - This captures the targeted v1 own-comment/internal-user seam under shared authorization contracts.
- (2026-04-21) Validation runbook for
F046checkpoint:cd packages/projects && npx tsc --pretty false --noEmit -p tsconfig.jsoncd .. && npx tsc --pretty false --noEmit -p server/tsconfig.jsoncd packages/projects && npx vitest run src/actions/projectPhaseStatusActions.contract.test.ts src/actions/projectPhaseStatusCopyRemove.contract.test.ts --coverage.enabled=false(known pre-existing contract drift inprojectTaskStatusActions.tsexpectation: missing literalasync function getScopedProjectStatusMappings()
- (2026-04-21) Completed
F047by enabling premium bundle narrowing on selected project list/detail surfaces:packages/projects/src/actions/projectActions.tsnow evaluatesgetProjectsandgetProjectthrough kernelauthorizeResourcewithBundleAuthorizationKernelProvider.- Added project record normalization for bundle template matching (
assigned_to,client_id, optionalassigned_team_id) and per-request subject context resolution (roles/teams/managed users/client). - Result: published bundle templates for assignment/client/team scope now narrow project visibility on these migrated read paths.
- (2026-04-21) Validation runbook for
F047checkpoint:cd packages/projects && npx tsc --pretty false --noEmit -p tsconfig.jsoncd .. && npx tsc --pretty false --noEmit -p server/tsconfig.json
- (2026-04-21) Completed
F048on selected asset read paths by migrating authorization to kernel evaluation:packages/assets/src/actions/assetActions.tsnow evaluates asset access via kernel ingetAsset,getAssetDetailBundle, andlistAssets.- Added shared asset authorization subject resolution and asset record normalization from
assets+asset_associations(client/team/assignment hooks).
- (2026-04-21) Completed
F049by enabling premium bundle narrowing on migrated asset paths:- Asset kernel calls now include
BundleAuthorizationKernelProviderwithresolveBundleNarrowingRulesForEvaluation(...), allowing published client/team/assignment bundle templates to narrow asset visibility on selected surfaces.
- Asset kernel calls now include
- (2026-04-21) Validation runbook for
F048-F049checkpoint:cd packages/assets && npx tsc --pretty false --noEmit -p tsconfig.jsoncd .. && npx tsc --pretty false --noEmit -p server/tsconfig.jsoncd packages/assets && npx vitest run tests --coverage.enabled=false(no matching tests discovered in this package)
- (2026-04-21) Completed
F050by migrating selected billing (quote) visibility/mutation paths onto kernel checks:packages/billing/src/actions/quoteActions.tsnow authorizesgetQuoteandlistQuotesthrough kernelauthorizeResource(resourcebilling:read) after RBAC.approveQuotenow uses kernelauthorizeMutationfor approval guards before state transition.
- (2026-04-21) Completed
F051by enabling premium billing bundle narrowing on migrated quote paths:- Billing quote read/approve kernel calls now include
BundleAuthorizationKernelProviderwithresolveBundleNarrowingRulesForEvaluation(...), enabling client-portfolio style narrowing and bundle mutation constraints.
- Billing quote read/approve kernel calls now include
- (2026-04-21) Completed
F052by adding billing field-redaction hook application on selected quote surfaces:getQuoteandlistQuotesnow apply kernelredactedFieldsto returned quote payloads without changing base allow/deny semantics.
- (2026-04-21) Validation runbook for
F050-F052checkpoint:cd packages/billing && npx tsc --pretty false --noEmit -p tsconfig.jsoncd .. && npx tsc --pretty false --noEmit -p server/tsconfig.jsoncd packages/billing && npx vitest run tests/contractReportActions.revenue.assignmentFact.test.ts tests/contractReportActions.expiration.wiring.test.ts --coverage.enabled=false
- (2026-04-21) Completed
F053andF054for selected API-key-backed v1 parity read surfaces by moving API authorization to shared kernel decisions:- Added API helper
server/src/lib/api/controllers/authorizationKernel.tsfor subject normalization and kernel delegation. - Added
apiKeyIdto API request context (ApiContext,ApiBaseController.authenticate) so API-key bundle assignments are intersected in authorization subject evaluation. - Kernelized selected read paths in:
server/src/lib/api/controllers/ApiTicketController.ts(list,getById)server/src/lib/api/controllers/ApiProjectController.ts(list,getById)server/src/lib/api/controllers/ApiQuoteController.ts(list,getById)
- These controllers now apply shared-kernel allow/deny checks per record, instead of RBAC-only pass-through.
- Added API helper
- (2026-04-21) Completed
F055by ensuring migrated API/server-action authorization uses shared kernel loading (getAuthorizationKernel) so CE remains on builtin-kernel runtime while EE overlays remain edition-gated. - (2026-04-21) Completed
F056by adding DB-backed narrowing regression coverage for assignment guards and intersection composition to catch silent broadening on migrated paths. - (2026-04-21) Completed
T004,T005,T006, andT012with DB-backed integration coverage inserver/src/test/integration/authorization/bundleAssignmentResolution.integration.test.ts:- assignment target validation rejects invalid role/team/user/api_key references
- role+team+user bundle attachments compose as narrowing intersections
- api-key bundle restrictions intersect with impersonated user bundles
- role assignment to published bundle immediately narrows ticket read decisions
- (2026-04-21) Completed
T008andT009using existing kernel guard/intersection unit tests (server/src/test/unit/authorization/kernel.engine.test.ts) and reinforced by new integration assertions. - (2026-04-21) Completed
T030via existing legacy-direction guard (server/src/test/unit/authorization/kernel.legacyDirection.test.ts). - (2026-04-21) Added API helper unit coverage in
server/src/test/unit/api/authorizationKernel.test.tsfor subject shaping and shared-kernel delegation. - (2026-04-21) Validation runbook for
F053-F056+ tests checkpoint:npx tsc --pretty false --noEmit -p server/tsconfig.jsoncd server && npx vitest run --coverage.enabled=false src/test/unit/api/authorizationKernel.test.ts src/test/integration/authorization/bundleAssignmentResolution.integration.test.ts
- (2026-04-21) Completed
T007with shared-contract mode tests inserver/src/test/unit/authorization/kernel.contract.modes.test.ts:- validates that CE mode (builtin only) and EE-overlay mode (builtin + bundle provider) both expose and execute shared kernel entry points (
authorizeResource,resolveScope,authorizeMutation,explainDecision).
- validates that CE mode (builtin only) and EE-overlay mode (builtin + bundle provider) both expose and execute shared kernel entry points (
- (2026-04-21) Additional validation runbook:
cd server && npx vitest run --coverage.enabled=false src/test/unit/authorization/kernel.contract.modes.test.ts src/test/unit/api/authorizationKernel.test.ts
- (2026-04-21) Completed
T029by extendingserver/src/test/unit/authorization/kernel.engine.test.tswith explicit reason-chain assertions that include RBAC gate (rbac_allowed), builtin relationship path (relationship_rules_allowed), and bundle narrowing (bundle_narrowing_applied). - (2026-04-21) Note on current integration runner state: repeated full integration reruns encountered transient DB pool exhaustion (
KnexTimeoutErrorduring test DB recreation). Unit-level checkpoints continue to run reliably; heavy integration reruns should be resumed after DB pool reset. - (2026-04-21) Completed
T010with simulator action unit coverage inserver/src/test/unit/authorization/bundleSimulatorAction.test.ts:- validates real principal + persisted-record simulation paths (
listAuthorizationSimulationPrincipalsAction,listAuthorizationSimulationRecordsAction,runAuthorizationBundleSimulationAction) - validates synthetic scenario simulation path (no persisted record lookup) against the same draft-vs-published decision flow
- asserts explainability reason chains are emitted for both revisions (for example
rbac:rbac_allowed,bundle:bundle_narrowing_applied,bundle:bundle_template_denied)
- validates real principal + persisted-record simulation paths (
- (2026-04-21) Fixed simulator action wiring in
ee/server/src/lib/actions/auth/authorizationBundleActions.tsby restoring in-action record resolution and removing an orphaned trailing record block that had drifted outside any action scope. - (2026-04-21) Validation runbook for
T010checkpoint:cd server && npx vitest run --coverage.enabled=false src/test/unit/authorization/bundleSimulatorAction.test.tscd .. && npx tsc --pretty false --noEmit -p server/tsconfig.json
- (2026-04-21) Completed
T011with tier/edition guard coverage across EE actions and CE fallback surfaces:server/src/test/unit/authorization/bundleSimulatorAction.test.tsnow asserts non-entitled tier gating blocks EE bundle-management actions before service calls.server/src/test/unit/authorization/kernel.ceFallback.test.tsverifies CE fallback behavior: when enterprise kernel factory is unavailable,getAuthorizationKernel()still runs builtin authorization decisions.server/src/test/unit/authorization/cePolicyManagement.placeholder.test.tsenforces CE placeholder UI copy includes Premium upgrade guidance while explicitly stating builtin authorization remains active.
- (2026-04-21) Validation runbook for
T011checkpoint:cd server && npx vitest run --coverage.enabled=false src/test/unit/authorization/bundleSimulatorAction.test.ts src/test/unit/authorization/kernel.ceFallback.test.ts src/test/unit/authorization/cePolicyManagement.placeholder.test.tscd .. && npx tsc --pretty false --noEmit -p server/tsconfig.json
- (2026-04-21) Completed
T013with ticket authorization narrowing regression coverage inpackages/tickets/src/actions/ticketActions.authorizationNarrowing.test.ts:- validates migrated
getTicketsForList+getTicketByIdpreserve baseline client board-narrowing behavior via selected board visibility. - validates selected-client + selected-board bundle restrictions are enforced on list/detail paths in the migrated ticket authorization flow.
- validates migrated
- (2026-04-21) Validation runbook for
T013checkpoint:cd packages/tickets && npx vitest run src/actions/ticketActions.authorizationNarrowing.test.ts --coverage.enabled=false
- (2026-04-21) Completed
T014by extendingpackages/tickets/src/actions/ticketActions.authorizationNarrowing.test.tswith API/UI parity coverage:- compares migrated UI list scope (
getTicketsForList) with API helper scope (authorizeApiResourceRead) under the same tenant/user/bundle-rule context. - asserts the same effective allowed ticket IDs for both paths in the selected v1 ticket parity scenario.
- compares migrated UI list scope (
- (2026-04-21) Completed
T015andT016with document authorization contract coverage inpackages/documents/tests/documentActions.authorization.contract.test.ts:T015: verifies migrated document paths preserve client baseline own/same-client/client-visible semantics while including selected-client bundle narrowing hooks.T016: verifies document redaction wiring appliesredactedFieldson allowed records without changing allow/deny filtering.
- (2026-04-21) Completed
T017,T018, andT019with runtime delegation/approval coverage inpackages/scheduling/tests/timeEntryDelegationAuth.authorization.test.ts:T017: validates self, manager, reports-to, and tenant-wide delegation semantics remain intact.T018: validates premium bundle overlays narrow delegation (for example self-only on read-all users) and do not broaden non-managed access.T019: validates not-self-approver guard remains enforced in kernelized approval flow.
- (2026-04-21) Completed
T020with project authorization contract coverage inpackages/projects/src/actions/projectAuthorization.contract.test.ts:- preserves own-comment/internal-user behavior in
projectTaskCommentActions.tsand bundle-aware kernel narrowing on project list/detail inprojectActions.ts.
- preserves own-comment/internal-user behavior in
- (2026-04-21) Completed
T021with asset authorization contract coverage inpackages/assets/src/actions/assetAuthorization.contract.test.ts:- verifies selected migrated asset surfaces (
getAsset,getAssetDetailBundle,listAssets) remain on shared kernel evaluation with bundle narrowing overlays.
- verifies selected migrated asset surfaces (
- (2026-04-21) Completed
T022andT023with billing quote authorization contract coverage inpackages/billing/tests/quoteAuthorization.contract.test.ts:T022: verifies selected quote read/approve paths stay on kernel read/mutation checks with bundle narrowing and self-approver guard.T023: verifies quote field redaction wiring on allowed records for both detail and list flows.
- (2026-04-21) Completed
T024,T025, andT027with EE bundle-management contract coverage inserver/src/test/unit/authorization/bundleManagement.contract.test.ts:T024: verifies draft-first editor/publish/assignment flow wiring and explicit revision publishing seam.T025: verifies resource-section and human-readable summary wiring in both UI and server payloads.T027: verifies audit trail event model includes bundle/revision/assignment lifecycle metadata and chronological sorting.
- (2026-04-21) Completed
T026with runtime action guard coverage inserver/src/test/unit/authorization/bundleManagementPermissions.test.ts:- verifies create/edit/publish/assignment/simulator actions fail closed when
system_settingspermission is missing and no mutating service call executes.
- verifies create/edit/publish/assignment/simulator actions fail closed when
- (2026-04-21) Completed
T028with CE migration contract coverage inserver/src/test/unit/authorization/kernel.ceMigratedFlows.contract.test.ts:- verifies selected migrated ticket/document/time/project/asset/billing paths continue to wire through shared builtin kernel entry points.
- (2026-04-21) Validation runbook for
T015-T028checkpoint:cd packages/documents && npx vitest run tests/documentActions.authorization.contract.test.ts --coverage.enabled=falsecd packages/scheduling && npx vitest run tests/timeEntryDelegationAuth.authorization.test.ts --coverage.enabled=falsecd packages/projects && npx vitest run src/actions/projectAuthorization.contract.test.ts --coverage.enabled=falsecd packages/assets && npx vitest run src/actions/assetAuthorization.contract.test.ts --coverage.enabled=falsecd packages/billing && npx vitest run tests/quoteAuthorization.contract.test.ts --coverage.enabled=falsecd server && npx vitest run src/test/unit/authorization/bundleManagement.contract.test.ts src/test/unit/authorization/kernel.ceMigratedFlows.contract.test.ts src/test/unit/authorization/bundleManagementPermissions.test.ts --coverage.enabled=false