Protecting Salesforce with SGNL

Introduction

Protected Systems are applications, services, or infrastructure that you want to protect with SGNL. In this guide, we’ll describe how SGNL can add continuous and contextual access management to compliment the existing policies you have within Salesforce.

With this integration, Salesforce need not know about the policies, systems of record, or any of the data in SGNL - it simply needs to pass to SGNL:

  • Who/What is requesting the access (The Principal)
  • (Optional) What is attempting to be accessed (The Asset)
  • (Optional) What operation is being attempted on the asset (The Action)
  • An access token that ensures the Protected System is a legitimate caller into SGNL

Prerequisites

  • An existing Salesforce instance
  • A SGNL Client
  • A SGNL User Account with Admin privileges
  • At least 1 system of record integrated to SGNL, containing principals and (optionally) assets that will be evaluated in access evaluations
  • (Optional) 1 or more policies that you want assigned to the integration

Creating a Protected System in SGNL

  1. Log-In to your SGNL Client with an Admin Account
  2. From the left navigation pane, select Protected Systems and Add, or simply click Add from the SGNL Dashboard
  3. Select ‘Salesforce’ from the SaaS category in the list of integrations
  4. Give your integration a descriptive display name and description
  5. Specify the Default Policy to be applied to Salesforce
    • Allow: If no policies provide a decision for an access request, SGNL will respond to the access request with an Allow decision
    • Deny: If no policies provide a decision for an access request, SGNL will respond to the access request with a Deny decision
  6. Next, you’ll need to configure which identifier Salesforce is using to describe your user/principal
    • This may be an email address or Username that can be found in your IdP, or an EmployeeID in your HRIS system. This should be in the format of the Principal ID of the user that will request access to the Protected System.
    • e.g. If an Okta user will be requesting access to this Protected System, Salesforce, the principal identifier should be the Okta email address.
  7. You’ll also need to define the types of Assets that Salesforce is protecting
    • This might be customer account data, opportunities, or field-level controls on Service Cloud cases
  8. Once configured, click Continue to save your Salesforce configuration and move on to other configuration steps

Configuring Authentication

  1. Authentication ensures that only authorized systems can make requests into SGNL, as well as verifying the identity of an integration in order to effectively evaluate Policies - to access Authentication settings, open your Salesforce protected system and select the Authentication tab

    SGNL - Authentication

  2. Click Generate Token

  3. Give your token a descriptive name so that you know how it’s being used in the future and click to Generate Token

    SGNL - Generate Token

  4. On the next screen, copy the token - this will be used by Salesforce to make access requests to SGNL using the SGNL Access Service API

    Note: The value of this token is not available again after this screen, so ensure you securely store it for steps later in this guide

    SGNL - Token

Integrating Salesforce with SGNL

Salesforce is the backbone of Sales and Support for many enterprise companies. As such, in the modern enterprise Salesforce is frequently heavily customized, has unique workflows, and is tailored to support very specific parts of the organization.

SGNL provides out-of-box experiences to enrich Salesforce access control with continuous and contextual decision making during:

  • Login/Logoff events, ensuring that users have the exact amount of access they need for a given Salesforce Session
  • During object access/updates, to determine whether a specific object should be fully/partially viewable or modifiable at a point of access
  • Automated/scheduled lifecycle events on objects, to ensure that events like case closure, legal hold, or customer churn result in the appropriate level of access for members of your organization

To fully understand how SGNL can help with providing continuous access management in your Salesforce environment, we recommend getting in touch with us.

As a particularly straightforward example, you can integrate SGNL with new or existing apex triggers that you might have in your environment. In the example below, this Apex Extension fires when an end-user attempts to access the Order object for a given customer.

With SGNL, we determine whether that user should be able to take the access action at all on that customer’s data, based on policy. You can associate this Extension directly with an Order object, or customize it to suit other Objects and actions inside of your Salesforce Environment.

public class orderControllerExtension {

    private final Order[] orderRecords;
    public String message;
    
 
    public orderControllerExtension(ApexPages.StandardSetController setController) {
        this.orderRecords = (Order[])setController.getSelected();
    }

    public Boolean getHasAccess() { 
        List<Order> accounts = [SELECT Account.Name, Account.AccountNumber FROM Order where Id = :this.orderRecords[0].Id];
        this.orderRecords[0].SGNLAccessCheck__c = True;
        String accountId = '';
        String accountNumber = '';
        try {
            accountId = accounts[0].Account.Name;
            accountNumber = accounts[0].Account.AccountNumber;
        } catch (Exception e) {
            System.debug('here ' + e.getMessage());
            apexpages.addMessage(new ApexPages.message(Apexpages.Severity.INFO, e.getMessage()));
            return false;
        }
  
        String endpoint_uri = 'https://access.sgnlapis.cloud/access/v1/evaluations';
        String decision = '';
        String userId = UserInfo.getUsername();
     
         // Instantiate a new http object
          Http h = new Http();

          // Instantiate a new HTTP request Object
          HttpRequest req = new HttpRequest();

          // Set access service URL endpoint by using a managed credential
          req.setEndpoint(endpoint_uri);

          // Set HTTP request method
          req.setMethod('POST');
          
          req.setBody('{"principal": {"id":'+'"'+userId+'"},"queries": [{"assetId": "'+accountNumber+'"'+',"action": "access"}]}');
   
          String authorizationHeader = 'Bearer {{sgnlToken}}';

          req.setHeader('Authorization', authorizationHeader);
          req.setHeader('Content-Type', 'application/json;charset=UTF-8');
          
        // Send the request to the access service, and return a response.
          HttpResponse res = h.send(req);

           If (res.getStatusCode() == 200) {
                // Deserialize result JSON into Map
                Map<String, Object> result = (Map<String, Object>)JSON.deserializeUntyped(res.getBody());
                List<Object> decisions = (List<Object>) result.get('decisions');
                for (Object decision_L : decisions) {
                    Integer i = 0;
                    Map<String, Object> a2 = (Map<String, Object>)decisions[i];
                    decision = string.valueOf(a2.get('decision'));
                    System.debug('SGNL API decision value : ' + decision);
                    i++;
                }
                 if (decision == 'Allow') {
                     this.message = 'You are authorized to access ' + accountId;
                     return true;
                 } else if (decision == 'Deny') {
                     this.message = 'You are not authorized to access ' + accountId;
                     apexpages.addMessage(new ApexPages.message(Apexpages.Severity.INFO, this.message));
                     return false;
                 } else {
                     this.message = 'Error ' + result.get('result');
                     return false;
                 }
           
            } else {
                this.message = 'Res code ' + res.getStatusCode() + ' end point url ' + endpoint_uri;
                apexpages.addMessage(new ApexPages.message(Apexpages.Severity.INFO, this.message));
               return false;
           }
    }
}

Once you’ve successfully associated the Apex Extension, you’ll be able to see requests coming from Salesforce into SGNL through the SGNL Logs. It’s likely that all decisions will either be Allow or Deny, based on the Default Decision you’ve selected for the Salesforce Integration - if that’s the case, you’re ready to start assigning policies to be applied to Saleforce

Assigning Policies

  1. Once the Integration is created, you can start assigning versions of Policies to the integration - to get started, select Policies from the tabs in your newly created integration

    SGNL - Policies

  2. Select ‘Assign Policies’

  3. Select:

    • The Policies you want to apply to the integration with the check box
    • The version of the Policy you want applied

    SGNL - Select Policies

  4. Click Next once you have the Policies and Versions configured as is appropriate

  5. Select the Enforcement mode for the Policies you chose in the previous step

    • Simulated: Policy Versions that are being simulated will only log their access decision in the SGNL logs and will not impact the access decision that SGNL hands back to an integration. Simulated policies are useful for performing what-if analysis of new policy versions as well as debugging policy changes.

      Note: It’s considered best practice to start with policies in Simulated mode, to verify that policies have been created an applied as expected

    • Enforced: Policy Versions that are being enforced will impact the access decisions that SGNL hands back to an integration. Enforced Policies will determine access for an integration

    SGNL - Set Enforcement

  6. Select your desired Enforcement mode and select Assign

  7. Versions of Policies will now be Assigned to your integration

    SGNL - Policy Assignments