Licensing & Feature Gates

The Licensing & Tiers page covers what the two tiers include. This page is the admin mechanics: activating a license and how the gate enforces it.

Activating a license

A Pinion license is a signed JWT the package validates locally — there’s no runtime callout to a license server.

  • PinionLicense__c stores the activation: Tier__c, LicensedTo__c, the Jwt__c (the activation token), ExpiresAt__c, LastValidatedAt__c, and InstallStampedAt__c. You activate a key on the License page in the Pinion Admin app.
  • LicenseConfig__mdt holds the validation config: the expected issuer and key id, the public key (PEM) the JWT is verified against, the channel mode (D2C / AppExchange (LMA) / Both), the trial length (TrialDays__c), and the expiry-warning window (WarnDays__c).
  • LicenseTierOrdering__mdt ranks the tiers so the gate can compare “is the org’s tier ≥ the feature’s minimum.” The authoritative order is compiled into the package; these rows are optional overrides.

How the gate enforces

FeatureGateGuard (over FeatureGateService) is the single choke point every gated feature calls. There are two gate shapes, both defined as FeatureTierMap__mdt records:

  • Capability gates — the feature is Pinion+ only (MinTier__c = PinionPlus). requireOrUpgrade(featureKey) allows it on Plus and blocks it on base. Examples: Config Promotion, Multi-Instance Bundles, MCP, Advanced Approvals, Pricing Waterfall, RevOps Dashboard, Mass Renewal, Line-Item Audit, the advanced MDQ dimensions/cadences.

  • Limit gates — the feature is available on base up to a cap, and unlimited on Plus. enforceLimitOrUpgrade(featureKey, currentCount) blocks the action that would exceed the cap. The base caps are:

    FeatureBase cap
    Active approval rules3
    Product / pricing rules10
    Configuration attributes per product2
    MDQ time dimensions per product1

When a gate blocks, it surfaces a friendly “Upgrade to Pinion+” message — as an AuraHandledException in the LWC/Aura path, or an HTTP 403 in the REST path — rather than a raw error.