Use FMA Features for per-user licensing

  • In salesforce, access is controlled through Permission sets.
  • LMO org can assign how many feature-specific licenses are assigned using an FMA Integer parameter,
  • Currently there is no standard way to limit license specific permission set assignments

here is the approach I would take to breeze this gap

  1. Create an Integer FMA parameter and permission set combination for each feature.
  2. Assign seats for Features in LMO using FMA parameter
  3. An apex class which will check if the logged-in user
    • has permission set assigned
    • Current users permission set assignment is among the first num_SeatsPermX permission set assignment
  4. When app code needs feature it calls CurrentUser.hasAccess(new Feature('FeatureX', 'FeatureXPermissionSet')).

This will allow the LMO org to control how many users have access to a specific feature, Even if the subscriber tries to assign permission sets to users more than assigned seats any user who has been assigned permission set after the seats are filled will not have access to the feature

To improve performance we can leverage Platform Cache and store computed feature access in the cache.

Here is the sample code

public with sharing class CurrentUser {

    public static Boolean hasAccess(Feature feature) {
        Set<Id> assignedUsers = new Set<Id>();

        for(PermissionSetAssignment  permissionSetAssignment : [SELECT Id, AssigneeId 
                                                                 FROM PermissionSetAssignment 
                                                                 WHERE PermissionSetId = :feature.permissionSetId 
                                                                 ORDER By SystemModstamp 
                                                                 LIMIT :feature.seats]) {
            assignedUsers.add(permissionSetAssignment.AssigneeId);
        }

        return assignedUsers.contains(UserInfo.getUserId());
    }
}

public with sharing class Feature {
    public Id permissionSetId { get; private set; }
    public Integer seats { get; private set; }

    public Feature(String featureName, String permissionSetName) {
        permissionSetId = [SELECT Id FROM PermissionSet WHERE Name = :permissionSetName].Id;
        seats = System.FeatureManagement.checkPackageIntegerValue(featureName);
    }
}

if(!CurrentUser.hasAccess(new Feature('FeatureX', 'FeatureXPermissionSet'))) {
    throw new FeatureAccessException('You do not have access to this feature');
}