Deploy Client on macOS Using Kandji

Deploy Client on macOS Using Kandji

This article illustrates the procedure to deploy Netskope Client on macOS devices running Big Sur or later using the Kandji MDM as the IdP. This process ensures reduced user interaction while deploying tenant certificates, system and network extensions.

Deployment Prerequisites

  • Download Netskope’s Root and Intermediate Certificates.
  • Download VPN Proxy App script from the Netskope Support Portal. This is required for macOS devices running Big Sur or later.
  • Administrator access to Kandji.
  • Administrator access to Netskope.
  • IdP setup with Netskope (for IdP-initiated enrollments).
  • IdP user integration setup with Kandji (for Kandji user-assigned enrollment).
  • Configure SAML authentication between Netskope and your IDP.

Before You Begin

Before you begin deployment, perform the following steps to upload the required certificates and configuration files in Kandji to successfully install and activate Client:

  1. Download Netskope Certificates

  2. Upload Netskope Certificates to Kandji.

  3. Upload VPN Configuration to Kandji.

  4. Add System Extension Profile.

  5. Prevent disabling Netskope background items.

  6. Allow Privacy Settings in Kandji

Download Netskope Certificates

  1. Login to Netskope WebUI with admin access and go to Settings > Manage > Certificates.

  2. Click the Signing CA tab and download both Netskope Root and Netskope Intermediate certificates.

  3. Convert the downloaded certificates to .cer format by renaming the .pem files to .cer.

Upload Netskope Certificates to Kandji

To upload the certificates to Kandji:

Important

It is mandatory to upload the Netskope Root Certificate and Netskope Intermediate Certificate.

  1. Login to Kandji and go to Library > Add New.
    img-02-kandjiAddNewCert.png
  2. Select Profiles from the dropdown menu.
  3. Click Certificate > Add and Configure
    img-03-kandjiAddNewCert-addConfigure.png
  4. Upload Netskope Root Certificate (.cer format).
    1. Enter a name for this certificate, for example: Netskope Root Certificate
    2. Select Certificate Type as PKCS#1-formatted certificate.
    3. Drag and drop the .cer certificate in the upload box.
    img-04-kandjiAddNSKProotCert.png
  5. Repeat this step to upload the Netskope Tenant Certificate. When uploading, give a name, for example: Netskope Tenant Certificate.

Upload VPN Configuration to Kandji

  1. Go to Library > Add New > Custom Profile.
  2. Click Add and Configure.
    1. Provide a name.
    2. Download the AppVPN proxy script from Netskope Support.
    3. Extract the zip file and upload the .mobileconfig file.
    img-06-kandjiAddmobileConfig.png

Add System Extension Profile

  1. Go to Library, select Profiles from the dropdown menu.
  2. Select System Extension and click Add and Configure.
    img-05-kandjiAddSystemXtn.png
  3. Specify the following for System Extension
    • Under General, select the checkbox to enable Allow Users to approve system extensions.
    • Team Identifier : 24W52P9M7W
    • Name (optional): Netskope
    • Under System Extension, select Allow all system extensions from the dropdown menu.
    img-07-kandjiAllowSysExtn.png

Prevent Disabling Netskope Startup and Background Items

  1. Go to Library > Add New  (you can also add Netskope settings to a pre-existing Login &Background item).
    Kandji_BackgroundItems_AddNew.png
  2. Select Profiles from the drop-down > Login & Background Items > Add & Configure.
    Kandji_BackgroundItems_Login_BackgroundItems.png
  3. Specify the following for Login and Background Items:
    1. Provide a name. For example, Login & Background Items.
    2. Click Add Background Item and enter details for the following:
      Kandji_BackgroundItems_AddBackgroundItem.png
      • Identifier Type: Team Identifier
      • Identifier: 24W52P9M7W
      • Comment: Netskope Client
      Kandji_BackgroundItems_Identifier.png
  4. Click Save.

Allow Privacy Settings in Kandji

  1. Go to Library > Add New  (you can also add Netskope settings to a pre-existing Privacy library item).

  2. Select Profiles from the drop-down > Privacy > Add & Configure

  3. Under APP ACCESS, create the following:

    Privacy setting #1

    • Identifier Type: Bundle ID

    • Identifier: com.netskope.client.Netskope-Client

    • Code Requirement:

      anchor apple generic and identifier "com.netskope.client.Netskope-Client" and (certificate leaf[field.1.2.840.113635.100.6.1.9] /* exists */ or certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */ and certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */ and certificate leaf[subject.OU] = "24W52P9M7W")
    • App or Service: Allow Accessibility and SystemPolicyAllFiles.

    Privacy setting #2

    • Identifier Type: Bundle ID

    • Identifier: com.netskope.epdlp.client

    • Code Requirement:

      anchor apple generic and identifier "com.netskope.epdlp.client" and (certificate leaf[field.1.2.840.113635.100.6.1.9] /* exists */ or certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */ and certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */ and certificate leaf[subject.OU] = "24W52P9M7W")
    • App or Service: Allow SystemPolicyAllFiles

    To learn more: Enabling Endpoint DLP on the Netskope Client for macOS.

    Privacy setting #3

    • Identifier Type: Bundle ID

    • Identifier: com.netskope.client.Netskope-Client.NetskopeClientMacAppProxy

    • Code Requirement:

      anchor apple generic and identifier "com.netskope.client.Netskope-Client.NetskopeClientMacAppProxy" and (certificate leaf[field.1.2.840.113635.100.6.1.9] /* exists */ or certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */ and certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */ and certificate leaf[subject.OU] = "24W52P9M7W")
    • App or Service: Allow SystemPolicyAllFiles

Deployment Procedure

After you complete adding the required certificates and files, you are ready to start with the deployment scripts using the pre-built scripts using the instructions provided in this section.

Kandji supports the following types of deployment methods:

  • IdP deployment in Single-User Mode.
  • IdP deployment in Multi-User Mode.
  • Deployment by the user assigned in Kandji.

Netskope provides documentation for three deployment methods. Choose the best method for your organization and follow the instructions in that section. If neither of these deployment methods are applicable to your organization, contact Netskope for additional assistance.

Option 1: Using IdP

  • Supports single and multi-user device enrollments.
  • Requires existing setup of the SAML Forward Proxy in your Netskope tenant to enable client enrollment.
  • Supports multi-factor authentication(MFA).

Option 2: Using Kandji Assigned User

  • Installs Netskope Client silently without end-user interaction.
  • Supports single-user mode enrollments.
  • The admin need to source Kandji users from IdP. To learn more, view Kandji documentation.
  • Assign each device to the users planned for enrollment.
  • Supports automated user assignment via IdP authentication during zero-touch deployments.

Add Deployment Scripts in Kandji

After you complete the steps to upload the required certificates and files, you can start adding the deployment scripts in Kandji. You can use the Netskope pre-built deployment scripts.

Deployment scripts are a combination of audit and remediation scripts that are required to deploy Netskope Client to the end user devices.

  • The audit script checks if Netskope Client is installed on the end-user devices.
  • The remediation script installs the clients on end-user devices that do not have the client installed.

The audit scripts are the same for each deployment method. You can start by creating the Kandji Library item and adding the audit script.

  1. Go to Library > Add New.

    Kandji_DeploymentScript_AddNew.png

  2. Select Custom Script and click Add &Configure.

    Kandji_DeploymentScript_Add_Confgure.png

  3. Create custom script with the following parameters:

    • Name: Enter any name. For example, Netskope Client Install.

    • Execution Frequency : Set this to value that suits your environment. Netskope recommends setting this value to Daily or 15 minutes.

  4. Enter the following script in the Audit Script text box:

    #!/bin/bash
    #script for installing NSAgent on OSX machines
    #will check to see if Netskope is Installed
    function Test_NSClient(){
    xz=$(/usr/bin/mdfind kMDItemFSName == Netskope Client.app -onlyin /Library/Application\ Support/)
     if [ -e "$xz" ]; then
         echo "$xz found netskope client is installed"
     exit 0
     else
         echo "client does not exist"
     exit 1
     fi
    }
    Test_NSClient
    #end script

    Kandji_DeploymentScript_Auditscript.png

  5. Click +Add Remediation script and add the following script:

    The remediation script varies according to your choice of the enrollment method.
    • Remediation Script for IdP enrollment

      • Replace the values marked XXXXX with your tenant domain name and YYYYY with the tenant name.

        • spDomain= <tenant-domain> Example: skope.com.

        • spTenant = <tenant-name> Example: If your tenant URL is example.skope.com, then enter only example.

        • If you prefer normal installation with single-user mode no other changes are needed.

        • If you prefer to install in multi-user mode, change “perusermode=0” to  “perusermode=1”

      • If Secure Enrollment is enabled, replace the authentication and encryption enrollment tokens with the tokens generated on the tenant webUI:

        • enrollencryptiontoken=<encryption token>

        • enrollauthtoken=<authentication token>

        If secure enrollment is not enabled, the following values are displayed in the script:

        • enrollencryptiontoken=0

        • enrollauthtoken=0

      #!/bin/bash
      #Script for installing Netskope Client on OSX machines
      #function will install Netskope Client
      
      function Ins_NSClient(){
      ag="NSClient.pkg"
      spDomain="XXXXX"
      spTenant="YYYYY"
      perusermode=0 # put 0 for normal installation, put 1 for per user config
      echo "Downloading NsAgent..."
      curl -o /tmp/$ag  https://download.goskope.com/dlr/mac/get
      echo "will now add config file..."
      mkdir -p "/Library/Application Support/Netskope/STAgent"
      NSIDPCONFIG_FILE_PATH="/Library/Application Support/Netskope/STAgent/nsidpconfig.json"
      echo "{ \"serviceProvider\": { \"domain\": \"$spDomain\", \"tenant\": \"$spTenant\" } }" > "${NSIDPCONFIG_FILE_PATH}"
      if [ $perusermode -eq 1 ]
      then
      NSUSERCONFIG_JSON_FILE="/Library/Application Support/Netskope/STAgent/nsuserconfig.json"
      echo "{\"nsUserConfig\":{\"enablePerUserConfig\": \"true\", \"configLocation\": \"~/Library/Application Support/Netskope/STAgent\", \"token\": \"\", \"host\": \"\",\"autoupdate\": \"true\"$fail_close_option}}" > "${NSUSERCONFIG_JSON_FILE}"
      fi
      echo "Installing Agent..."
      installer -dumplog -pkg /tmp/$ag -target / && rm /tmp/$ag
      }
      # Function to create JSON file with provided tokens
      Create_Json() {
          # Create directory if it doesn't exist
          mkdir -p $TEMP_BRANDING_DIR
          # Delete previous enroll.conf if it exists
          if [[ -f "$TEMP_ENROLLMENT_TOKEN_FILE" ]]; then
              rm "$TEMP_ENROLLMENT_TOKEN_FILE"
          fi 
          local a=$1 #auth token
          local b=$2 #encryption token
          # Check if parameters are 32 characters hexadecimal
          if ! [[ "$a" =~ ^[a-fA-F0-9]{32}$ ]] && [[ "$a" != "0" ]]; then
              echo "Invalid auth token: must be 32 hexadecimal characters"
              return 1
          fi
          if ! [[ "$b" =~ ^[a-fA-F0-9]{32}$ ]] && [[ "$b" != "0" ]]; then
              echo "Invalid encryption token: must be 32 hexadecimal characters"
              return 1
          fi
          # Start the JSON structure
          echo "{" > $TEMP_ENROLLMENT_TOKEN_FILE
          #if both token is present
          if [[ "$a" != "0" && "$b" != "0" ]]; then
              echo "\"enrollauthtoken\": \"$a\"," >> $TEMP_ENROLLMENT_TOKEN_FILE
              echo "\"enrollencryptiontoken\": \"$b\"" >> $TEMP_ENROLLMENT_TOKEN_FILE
          # only encryption token present
          elif [[ "$a" == "0" && "$b" != "0" ]]; then
              echo "\"enrollencryptiontoken\": \"$b\"" >> $TEMP_ENROLLMENT_TOKEN_FILE
          #only authtoken present
          elif [[ "$b" == "0" && "$a" != "0" ]]; then
                echo "\"enrollauthtoken\": \"$a\"" >> $TEMP_ENROLLMENT_TOKEN_FILE
          else
               echo "Unsupported use case"
          fi
          # End the JSON structure
          echo "}" >> $TEMP_ENROLLMENT_TOKEN_FILE
          chmod 700 "$TEMP_ENROLLMENT_TOKEN_FILE"
          echo "enroll.conf created with provided tokens."
      }
      
      # Main script execution
      
      #update these tokens to valid tokens
      enrollencryptiontoken=0
      enrollauthtoken=0
      TEMP_BRANDING_DIR="/tmp/nsbranding"
      TEMP_ENROLLMENT_TOKEN_FILE="$TEMP_BRANDING_DIR/enroll.conf"
      
      # Check if atleast one of the token is present, then create enroll.conf
      if [[ "$enrollencryptiontoken" != "0" || "$enrollauthtoken" != "0" ]]; then
          echo "Using secure enrollment"
          Create_Json "$enrollauthtoken" "$enrollencryptiontoken"
      else
          echo "Not using secure enrollment"
          # Delete previous enroll.conf if it exists
          if [[ -f "$TEMP_ENROLLMENT_TOKEN_FILE" ]]; then
              rm "$TEMP_ENROLLMENT_TOKEN_FILE"
          fi
      fi
      Ins_NSClient
      #end script
    • Remediation script for Kandji assigned user

      • If Secure Enrollment is enabled, replace the authentication and encryption enrollment tokens with the tokens generated on the tenant webUI:

        • enrollencryptiontoken=<encryption token>

        • enrollauthtoken=<authentication token>

        If secure enrollment is not enabled, the following values are displayed in the script:

        • enrollencryptiontoken=0

        • enrollauthtoken=0

      • Replace the values marked XXXXX with your tenantUrl and YYYYY with your Organization ID.

        • tenantUrl= addon-<tenant url>Example: If your tenant URL is example.skope.com, then it would be addon-example.skope.com

        • orgKey = <Organization ID> This is found in your Netskope tenant at this location: Settings > Security Cloud Platform > MDM Distribution > Deployment Resources for iOS > Create VPN Configuration > Organization ID: YYYYY

        #!/bin/bash
        #Script for installing Netskope Client on OSX machines by the Kandji assigned user
        #function will install Netskope Client
        
        
        function Ins_NSClient(){
        ag="NSClient.pkg"
        tenantUrl="addon-XXXXX"                                                                                                                                                                                                                              
        emailAddress="$(/usr/libexec/PlistBuddy -c 'print :EMAIL' /Library/Managed\ Preferences/io.kandji.globalvariables.plist)"
        orgKey="YYYYY"
        echo "will now add config file..."
        mkdir -p "/tmp/nsbranding"
        NSINSTPARAM_JSON_FILE="/tmp/nsbranding/nsinstparams.json"
        echo "{\"TenantHostName\":\"$tenantUrl\", \"Email\":\"$emailAddress\", \"OrgKey\":\"$orgKey\"}" > "${NSINSTPARAM_JSON_FILE}"
        echo "Downloading NsAgent..."
        curl -o /tmp/$ag  https://download.goskope.com/dlr/mac/get
        echo "Installing Agent..."
        installer -dumplog -pkg /tmp/$ag -target / && rm /tmp/$ag
        echo "Cleaning up..."
        }
        
        
        # Function to create JSON file with provided tokens
        Create_Json() {
            # Create directory if it doesn't exist
            mkdir -p $TEMP_BRANDING_DIR
            # Delete previous enroll.conf if it exists
            if [[ -f "$TEMP_ENROLLMENT_TOKEN_FILE" ]]; then
                rm "$TEMP_ENROLLMENT_TOKEN_FILE"
            fi  
            local a=$1 #auth token
            local b=$2 #encryption token
            # Check if parameters are 32 characters hexadecimal
            if ! [[ "$a" =~ ^[a-fA-F0-9]{32}$ ]] && [[ "$a" != "0" ]]; then
                echo "Invalid auth token: must be 32 hexadecimal characters"
                return 1
            fi  
            if ! [[ "$b" =~ ^[a-fA-F0-9]{32}$ ]] && [[ "$b" != "0" ]]; then
                echo "Invalid encryption token: must be 32 hexadecimal characters"
                return 1
            fi  
            # Start the JSON structure
            echo "{" > $TEMP_ENROLLMENT_TOKEN_FILE
            #if both token is present
            if [[ "$a" != "0" && "$b" != "0" ]]; then
                echo "\"enrollauthtoken\": \"$a\"," >> $TEMP_ENROLLMENT_TOKEN_FILE
                echo "\"enrollencryptiontoken\": \"$b\"" >> $TEMP_ENROLLMENT_TOKEN_FILE
            # only encryption token present
            elif [[ "$a" == "0" && "$b" != "0" ]]; then
                echo "\"enrollencryptiontoken\": \"$b\"" >> $TEMP_ENROLLMENT_TOKEN_FILE
            #only authtoken present
            elif [[ "$b" == "0" && "$a" != "0" ]]; then
                  echo "\"enrollauthtoken\": \"$a\"" >> $TEMP_ENROLLMENT_TOKEN_FILE
            else
                 echo "Unsupported use case"
            fi  
            # End the JSON structure
            echo "}" >> $TEMP_ENROLLMENT_TOKEN_FILE
            chmod 700 "$TEMP_ENROLLMENT_TOKEN_FILE"
            echo "enroll.conf created with provided tokens."
        }
        # Main script execution
        
        #update these tokens to valid tokens
        enrollencryptiontoken=0
        enrollauthtoken=0
        TEMP_BRANDING_DIR="/tmp/nsbranding"
        TEMP_ENROLLMENT_TOKEN_FILE="$TEMP_BRANDING_DIR/enroll.conf"
        
        # Check if atleast one of the token is present, then create enroll.conf
        if [[ "$enrollencryptiontoken" != "0" || "$enrollauthtoken" != "0" ]]; then
            echo "Using secure enrollment"
            Create_Json "$enrollauthtoken" "$enrollencryptiontoken"
        else
            echo "Not using secure enrollment"
            # Delete previous enroll.conf if it exists
            if [[ -f "$TEMP_ENROLLMENT_TOKEN_FILE" ]]; then
                rm "$TEMP_ENROLLMENT_TOKEN_FILE"
            fi
        fi
        Ins_NSClient
        #end script
  6. Click Save.

Add Custom Profile for Kandji Global Variables

Primarily, you need to deploy a .plist file to the local devices to run the remediation script. The script uses the .plist file during installation to identify the the user of any device.

Note

Download Kandji-Global-Variables.mobileconfig file from the Support portal.

To add a custom profile:

  1. Go to Library > Add New.
    Kandji_CustomProfile_AddNew.png
  2. Select Profiles from the drop-down > Custom Profile.
  3. Click Add & Configure.
  4. Enter a name for the profile. For example, Kandji Global Variables.
  5. Upload the downloaded Kandji-Global-Variables.mobileconfig file.
    Kandji_CustomProfile_KandjiGlobalVariables.png
  6. Click Save.

Apply New Kandji Library items to your BlueprintKandji

Netskope recommends creating a test blueprint to ensure Netskope Client deploys as expected.

  1. Navigate to your Blueprint.
  2. Uncheck the box next to Show enabled only.
    Kandji_Blueprint_Showenabledonly.png
  3. Toggle to enable the following items:
    • Netskope Root Certificate(Profiles / Certificates)
    • Netskope Tenant Certificate(Profiles / Certificates)
    • Netskope-AppProxyVPN (Custom Profile)
    • Netskope System Extension(System Extension)
    • Login & Background Item(Login & Background Items)
    • Install Netskope Client(Custom Scripts)
    • Kandji Global Variables(Custom Profile) ***** only needed if enrolling by Kandji assigned Users
  4. Click Save.
Share this Doc

Deploy Client on macOS Using Kandji

Or copy link

In this topic ...