Skip to content

Backend Core Entitlements

Related documentation: Data ownership · Backend Core Addons · Backend Admin API

Core is the source of truth for company commercial entitlements: base package, add-ons, and restriction packages (negative org overrides). Auth still owns membership permission grants; Core can deny specific permission keys for everyone in a company when an active restriction applies.

GET /internal/companies/{companyId}/entitlements

Section titled “GET /internal/companies/{companyId}/entitlements”

Returns the resolved entitlement snapshot for a company, including:

FieldMeaning
enabledModulesUnion of base package + active add-on modules
restrictionsActive company restriction package assignments (summary)
deniedPermissionKeysUnion of Auth permission keys blocked by active restrictions

deniedPermissionKeys is computed from restriction_package_permissions for every active row in company_restrictions. Persona apps (Promoters BFF/FE) must treat a key in this list as denied for all members, including OWNER, ADMIN, and TENANT_SUPERADMIN, even when Auth granted the key.

Positive access still requires Auth membership grants. Restrictions only subtract capability at the org level.

Restriction packages are catalog rows — not add-ons. They do not grant modules; they list permission keys to deny when attached to a company.

Tables (migration 00024_restriction_packages.sql):

  • restriction_packageskey, name, description, is_active
  • restriction_package_permissions(restriction_package_id, permission_key) (Auth keys as plain text; no FK to Auth)
  • company_restrictions — company assignment with status, window fields; UNIQUE(company_id, restriction_package_id)

Seed: agencies_contact — “Agencies & artist contacts” — denies promoter.booking.agencies.view. Not auto-attached to any company; operators attach manually from Admin → company Subscriptions.

Mirror add-on catalog shape:

  • GET/POST /internal/catalog/restriction-packages
  • GET/PATCH/DELETE /internal/catalog/restriction-packages/{id}

Create/update bodies accept permissionKeys: string[] (Auth catalog keys).

  • POST /internal/companies/{companyId}/restrictions

Body:

{
"restrictionKey": "agencies_contact",
"status": "active",
"startsAt": "2026-08-12T00:00:00Z",
"endsAt": null,
"source": "platform_admin",
"externalReference": "support_ticket_123"
}

Detach by posting status: "inactive" (same pattern as add-ons). Successful upsert bumps entitlementVersion.

Company subscription items[] may include kind: "restriction" rows (alongside package and addon). Each restriction item uses the catalog package UUID as id, exposes permissionKeys on the item, and appears in Admin company Subscriptions UI.

When promoter.booking.agencies.viewdeniedPermissionKeys:

  • Hide Booking → Agencies nav (owner bypass does not apply)
  • Block /booking/agencies/** and artist Team tab in the Promoters FE
  • BFF returns 403 on agencies network routes, artist team, and legacy artist contacts when the key is denied — after normal Auth permission checks

Hydration path: Promoters GET /users/initaccess.deniedPermissionKeys from Core company context → FE global state deniedPermissionKeys.