External credential storage configuration

Configure your instance to obtain credentials from a remote repository.

These procedures assume that you already have an external repository configured with the credentials you want to protect. The credential identifier configured in the ServiceNow instance must be mapped to the actual credential in the repository through the JAR file.

To configure External Credential Storage, complete these tasks in order.

Create a JAR file to resolve credentials

Create a JAR file to resolve credential identifiers sent from the MID Server into actual credentials from the repository.

About this task

Make sure to include all the credential elements that the instance expects, such as the private key.

To create a JAR file to resolve credentials:

Procedure

  1. Use this sample Java file as a template:
    package com.snc.discovery;
     
    import java.util.*;
    import java.io.*;
     
    /**
     * Basic implementation of a CredentialResolver that uses a properties file.
     */
    
    public class CredentialResolver {
     
        private static String ENV_VAR = "CREDENTIAL_RESOLVER_FILE";
        private static String DEFAULT_PROP_FILE_PATH = "C:\\dummycredentials.properties";
     
        // These are the permissible names of arguments passed INTO the resolve()
        // method.
     
        // the string identifier as configured on the ServiceNow instance...
        public static final String ARG_ID = "id";
     
        // a dotted-form string IPv4 address (like "10.22.231.12") of the target
        // system...
        public static final String ARG_IP = "ip";
     
        // the string type (ssh, snmp, etc.) of credential as configured on the
        // instance...
        public static final String ARG_TYPE = "type";
     
        // the string MID server making the request, as configured on the
        // instance...
        public static final String ARG_MID = "mid";
     
        // These are the permissible names of values returned FROM the resolve()
        // method.
     
        // the string user name for the credential, if needed...
        public static final String VAL_USER = "user";
     
        // the string password for the credential, if needed...
        public static final String VAL_PSWD = "pswd";
     
        // the string pass phrase for the credential if needed:
        public static final String VAL_PASSPHRASE = "passphrase";
     
        // the string private key for the credential, if needed...
        public static final String VAL_PKEY = "pkey";
     
        // the string authentication protocol for the credential, if needed...
        public static final String VAL_AUTHPROTO = "authprotocol";
     
        // the string authentication key for the credential, if needed...
        public static final String VAL_AUTHKEY = "authkey";
     
        // the string privacy protocol for the credential, if needed...
        public static final String VAL_PRIVPROTO = "privprotocol";
     
        // the string privacy key for the credential, if needed...
        public static final String VAL_PRIVKEY = "privkey";
     
     
        private Properties fProps;
     
        public CredentialResolver() {
        }
     
        private void loadProps() {
            if(fProps == null)
                fProps = new Properties();
     
            try {
                String propFilePath = System.getenv(ENV_VAR);
                if(propFilePath == null) {
                    System.err.println("Environment var "+ENV_VAR+" not found. Using default file: "+DEFAULT_PROP_FILE_PATH);
                    propFilePath = DEFAULT_PROP_FILE_PATH;
                }
     
                File propFile = new File(propFilePath);
                if(!propFile.exists() || !propFile.canRead()) {
                    System.err.println("Can't open "+propFile.getAbsolutePath());
                }
                else {
                    InputStream propsIn = new FileInputStream(propFile);
                    fProps.load(propsIn);
                }
                //fProps.load(CredentialResolver.class.getClassLoader().getResourceAsStream("dummycredentials.properties"));
            } catch (IOException e) {
                System.err.println("Problem loading credentials file:");
                e.printStackTrace();
            }
        }
     
        /**
         * Resolve a credential.
         */
        public Map resolve(Map args) {
            loadProps();
            String id = (String) args.get(ARG_ID);
            String type = (String) args.get(ARG_TYPE);
            String keyPrefix = id+"."+type+".";
     
            if(id.equalsIgnoreCase("misbehave"))
                throw new RuntimeException("I've been a baaaaaaaaad CredentialResolver!");
     
            // the resolved credential is returned in a HashMap...
            Map result = new HashMap();
            result.put(VAL_USER, fProps.get(keyPrefix + VAL_USER));
            result.put(VAL_PSWD, fProps.get(keyPrefix + VAL_PSWD));
            result.put(VAL_PKEY, fProps.get(keyPrefix + VAL_PKEY));
            result.put(VAL_PASSPHRASE, fProps.get(keyPrefix + VAL_PASSPHRASE));
            result.put(VAL_AUTHPROTO, fProps.get(keyPrefix + VAL_AUTHPROTO));
            result.put(VAL_AUTHKEY, fProps.get(keyPrefix + VAL_AUTHKEY));
            result.put(VAL_PRIVPROTO, fProps.get(keyPrefix + VAL_PRIVPROTO));
            result.put(VAL_PRIVKEY, fProps.get(keyPrefix + VAL_PRIVKEY));
     
            System.err.println("Resolving credential id/type["+id+"/"+type+"] -> "+result.get(VAL_USER)+"/"+result.get(VAL_PSWD)+"/"+result.get(VAL_PASSPHRASE)+"/"+result.get(VAL_PKEY)+"/"+result.get(VAL_AUTHPROTO)+"/"+result.get(VAL_AUTHKEY)+"/"+result.get(VAL_PRIVPROTO)+"/"+result.get(VAL_PRIVKEY));
     
            return result;
        }
     
     
        /**
         * Return the API version supported by this class.
         */
        public String getVersion() {
            return "1.0";
        }
     
        public static void main(String[] args) {
            CredentialResolver obj = new CredentialResolver();
            obj.loadProps();
     
            System.err.println("I spy the following credentials: ");
            for(Object key: obj.fProps.keySet()) {
                System.err.println(key+": "+obj.fProps.get(key));
            }
     
        }
    }
  2. Create a properties file to store the external credentials for the script. Use the sample below to add the necessary credentials.
    #dummycredentials.properties
    #set the environment variable CREDENTIAL_RESOLVER_FILE to the fully qualified path to this file (including file name)
    #If the environment variable isn't set, it defaults to C:/Mid Servers/Credentials/dummycredentials.properties
    #CREDENTIAL_ID.TYPE.user=
    #CREDENTIAL_ID.TYPE.pswd=
    #CREDENTIAL_ID.TYPE.pkey=
    #CREDENTIAL_ID.TYPE.passphrase=
    #CREDENTIAL_ID.snmpv3.authprotocol=
    #CREDENTIAL_ID.snmpv3.authkey=
    #CREDENTIAL_ID.snmpv3.privprotocol=
    #CREDENTIAL_ID.snmpv3.privkey=
    
    #CREDENTIAL_ID is the value in the "Credential ID" field on the instance.
    #TYPE is one of 
    #ssh_password
    #ssh_private_key
    #snmp
    #snmpv3
    #vmware
    #windows
    #mssql
    #cim
    
    PublicSnmp.snmp.pswd=public
    TestingSnmp.snmp.pswd=Muffins
    
    ExampleDomain.windows.user=EXAMPLEDOMAIN\\administrator
    ExampleDomain.windows.pswd=Password1
    
    ExampleLinux.ssh_password.user=root
    ExampleLinux.ssh_password.pswd=Rootpass123
    
    #For VMWare on 10.0.103.14
    ExampleVMWare.vmware.user=administrator
    ExampleVMWare.vmware.pswd=vmpass123##$#@
    
    #### Examples ######
    # No Authorization with no Privileges
    User1.snmpv3.user=user1 
    
    # Md5 Authorization with no Privileges
    User2.snmpv3.user=user2
    User2.snmpv3.authprotocol=md5
    User2.snmpv3.authkey=1234567890abcdef
    
    # Sha Authorization with no Privileges
    User3.snmpv3.user=user3
    User3.snmpv3.authprotocol=sha
    User3.snmpv3.authkey=1234567890abcdef
    
    # Authorization with Privileges
    User4.snmpv3.user=user4
    User4.snmpv3.authprotocol=md5
    User4.snmpv3.authkey=1234567890abcdef
    User4.snmpv3.privprotocol=aes_128
    User4.snmpv3.privkey=1234567890abcdef

Import a JAR file to resolve credentials

Import a JAR file created to resolve credential identifiers sent from the MID Server into actual credentials from the repository.

About this task

After you create the JAR file, import it into the instance, where it becomes accessible to the MID Server.

Procedure

  1. After creating the JAR and properties files, copy the properties file to the MID Server.
  2. Navigate to MID Server > JAR Files.
  3. Click New.
  4. Complete the following fields:
    FieldDescription
    Name A unique and descriptive name for identifying the file in the instance.
    Version A version number for the file, if one is available.
    Source Location of the JAR file for reference purposes. Source information is not used by the system.
    Description Short description of the JAR file and its purpose in the instance.
  5. Click the paper clip icon in the banner and attach the JAR file to the record.
    Figure 1. Attaching a JAR file
  6. Click Submit.
  7. Restart the MID Server service.
    The platform makes the JAR file available to any MID Server configured to communicate with the instance.

Configure the credential identifier

Configure the credential identifier in the instance.

Before you begin

Role required: admin
Verify the following items:

Procedure

  1. Navigate to Discovery > Credentials or Orchestration > Credentials.
  2. Click New.
  3. Select a credential type.
  4. Select the External credential store check box.
    The User name and Password fields disappear, and the Credential ID field appears.
  5. Complete the Credentials form using the fields from the table.
  6. Click Submit.
    Field Description
    Name Enter a unique and descriptive name for this credential.
    Active Enable or disable these credentials for use.
    Credential ID Enter the unique key configured for external credentials in the JAR file uploaded to the MID Server for an external credential system. This is the ID passed to the Java class in the parameter map:
    public static final String ARG_ID   = "id";
    The MID Server uses this identifier to resolve the actual credentials on the repository.
    Note: This field is only visible when the External credential store check box is selected.
    Tag Allow workflow creators to assign individual credentials to any activity in an Orchestration workflow or assign different credentials to each occurrence of the same activity type in an Orchestration workflow.
    External credential store Select this check box to use an external credential storage system. When you select this option the User name and Password fields are replaced with the Credential ID field. External credential storage is only available when the External Credential Storage plugin in activated.
    Note: Currently, the only supported external storage system is CyberArk.
    Applies to Select whether to apply these credentials to All MID servers in your network, or to one or more Specific MID servers. Specify the MID Servers that should use these credentials in the MID servers field.
    MID servers Select one or more MID Servers from the list of available MID Servers. The credentials configured in this record are available to the MID Servers in this list. This field is available only when you select Specific MID servers from the Applies to field.
    Order Enter the order (sequence) in which the platform tries this credential as it attempts to log onto devices. The smaller the number, the higher in the list this credential appears. Establish credential order when using large numbers of credentials or when security locks out users after three failed login attempts. If all the credentials have the same order number (or none), Discovery or Orchestration tries the credentials in a random order.

Configure the credential identifier for AWS

Configure your instance to obtain credentials from a remote repository.

Before you begin

Role required: cloud_admin

Verify that the External Credential Storage plugin and Amazon Web Services plugin have been activated and the MID server has been installed.

About this task

These procedures assume that you already have an external repository configured with the credentials you want to protect. The credential identifier configured in the ServiceNow instance must be mapped to the actual credential in the repository through the JAR file.

Procedure

  1. Navigate to Amazon AWS Cloud > Configuration > Accounts.
  2. Select the appropriate account.
  3. In the AWS Credentials related list, click New and fill in the form, as appropriate.
    Table 1. AWS Credentials
    Field Description
    Name A unique and descriptive name for this credential. For example, Amazon Web Services.
    Active Check box to enable or disable the credential.
    AWS Account Master AWS account to which this credential belongs.
    External credential store Select this check box to use an external credential storage system. When you select this checkbox, the Access Key ID and the Secret Access Key fields disappear and are replaced by Credential ID and MID servers.
    Credential ID Enter the Name as stored in CyberArk.
    MID servers Select one or more MID Servers.
  4. Click Submit.