Encrypting credential passwords

Introduction

Pineapple uses (by default) a file based credential provider to manage the defined set of credentials. Credentials are an integral part of the Pineapple environment configuration and serves to separate the security configuration from the model of the target IT environment that Pineapple operates on. Pineapple uses credentials for authentication when a session is established to a resource.

The resources are accessed using different protocols, each with their own authentication mechanism. The lowest common denominator is usage of user name and password for authentication. Pineapple currently only supports password based authentication.

The file based credential provider is backed by the configuration file named credentials.xml. All passwords in the configuration file are encrypted to avoid storing them in clear text.

Encryption of credential passwords

The credential configuration file credentials.xml is read by the credential provider when Pineapple is initialized. When the file is read then Pineapple inspects whether a password is defined in clear text. A password is considered unencrypted if:

  • The password is stored without the prefix encrypted:
  • The password is stored with the prefix encrypted: and decryption of the password fails.

If a password is determined to be in clear text then the password is encrypted and the configuration file is saved to encrypt the password in the file. The prefix encrypted: will be added to the password in the file to signal that the password have been encrypted.

The purpose for supporting processing of unencrypted password in the configuration file is to support manual editing of the configuration file.

Passwords are stored encrypted in memory

All passwords are stored encrypted in memory. A password is only when the password is passed on to a specific API used to establish a session to some resource.

Symmetric encryption

The file based credential provider uses symmetric encryption to support the use cases:

  • Encrypt a password in the configuration file.
  • Decrypt a password in memory when a session to a resource is established. And the password is used for authentication.

The master password

The used library for encryption (Jasypt) uses a master password to encrypt and decrypt passwords.

When Pineapple starts, the master password is read from the file location defined by the value of the system property pineapple.credentialprovider.password.file. This is an optional system property. If this property isn't defined then it will be resolved to ${pineapple.home.dir}/conf/credentialprovider.password.

Creation of a default master password

If no password file exists at the location resolved by the system property pineapple.credentialprovider.password.file then Pineapple will create a file at the location containing a random generated master password. The random generated password will then be used to encrypt all defined passwords.

The master password isn't included in a configuration refresh

When the Pineapple is instructed to perform a configuration refresh then the master password isn't re-read and all passwords re-encrypted. A configuration refresh can either be performed through the GUI or through the REST API (using the operation: Refresh Environment Configuration).

The master password is excluded because:

  • The master password is intended to be a stable configuration which isn't modified.
  • To be able to include the master password in the configuration refresh then Pineapple should be able to migrate all encrypted passwords from one master password to a new one if the master password had changed in the password file. This functionality isn't supported.

Setting the master password

Two scenarios exists for setting the master password:

  • Pineapple has been started previously. A master password file exist and all passwords are already encrypted.
  • Pineapple hasn't been started previously. A master password file doesn't exist and all passwords are in clear text in the credentials.xml file.

Setting the master password when the master password file exist and all passwords are already encrypted

Follow these steps:

  1. Kill Pineapple. Kill Pineapple if it is running.
  2. Determine the location of master password file.
    1. If Pineapple is configured to start with the system property pineapple.credentialprovider.password.file defined then the location defined by the system property will be used as the location of the master password file.
    2. Otherwise, the location of the master password file is: ${pineapple.home.dir}/conf/credentialprovider.password.
  3. Set the new master password. Open the master password file and modify the password by adding a secure random string, e.g something which is approximately than 36 characters long and consist of upper and lower case characters and numbers. Example: /path/to/pinapple/.pineapple/conf/credentialprovider.password:
    7af93081-e89d-4005-8e23-5c8070d8d773
    
  4. Reset the passwords. Open credentials.xml and replace all encrypted passwords with password in clear text:
    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <configuration xmlns="http://pineapple.dev.java.net/ns/environment_1_0">
      <environments>
        <environment description="Environment to support execution of modules on a local Linux host with...." id="linux-default">
          <credentials>
            <credential password="WebLogic99" user="weblogic" id="weblogic-edit-jmx"/>
          </credentials>
      </environment>
        <environment description="Environment to support the Pineapple test infrastructure." id="linux-pineapple-test-infrastructure">
          <credentials>
            <credential password="vagrant" user="vagrant" id="ssh-node1"/>
            <credential password="vagrant" user="vagrant" id="ssh-node2"/>
          </credentials>
        </environment>
        
        ... 
        
    </configuration>
    
  5. Start Pineapple. Start Pineapple to have all password encrypted again:
    1. The new master password file will be read from the defined location.
    2. All unencrypted passwords in credentials.xml will be read and then encrypted with the master password. The passwords are written back to the configuration with the prefix encrypted: appended:
      <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
      <configuration xmlns="http://pineapple.dev.java.net/ns/environment_1_0">
        <environments>
          <environment description="Environment to support execution of modules on a local Linux host with...." id="linux-default">
            <credentials>
              <credential password="encrypted:cucfJyRm0QR6EaNH7A6GRg==" user="weblogic" id="weblogic-edit-jmx"/>
            </credentials>
        </environment>
          <environment description="Environment to support the Pineapple test infrastructure." id="linux-pineapple-test-infrastructure">
            <credentials>
              <credential password="encrypted:VX1mne9VBLY=" user="vagrant" id="ssh-node1"/>
              <credential password="encrypted:VX1mne9VBLY=" user="vagrant" id="ssh-node2"/>
            </credentials>
          </environment>
          
          ... 
          
      </configuration>
      

Setting the master password when the master password file doesn't exist and all passwords are in clear text

Follow these steps:

  1. Determine the location of master password file.
    1. If Pineapple is configured to start with the system property pineapple.credentialprovider.password.file defined then the location defined by the system property will be used as the location of the master password file.
    2. Otherwise, the location of the master password file is: ${pineapple.home.dir}/conf/credentialprovider.password.
  2. Set the new master password. Create a text file at the location and add a secure random string, e.g something which is approximately than 36 characters long and consist of upper and lower case characters and numbers. Example: /path/to/pinapple/.pineapple/conf/credentialprovider.password:
    g5f7j89l-e3fr-5678-r6h8-5c8070d8d773
    
  3. Start Pineapple. Start Pineapple to encrypt all passwords:
    1. The new master password file will be read from the defined location.
    2. All unencrypted passwords in credentials.xml will by read.
    3. All passwords will be encrypted with the master password and written back to the configuration with the prefix encrypted: appended:
      <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
      <configuration xmlns="http://pineapple.dev.java.net/ns/environment_1_0">
        <environments>
          <environment description="Environment to support execution of modules on a local Linux host with...." id="linux-default">
            <credentials>
              <credential password="encrypted:cucfJyRm0QR6EaNH7A6GRg==" user="weblogic" id="weblogic-edit-jmx"/>
            </credentials>
        </environment>
          <environment description="Environment to support the Pineapple test infrastructure." id="linux-pineapple-test-infrastructure">
            <credentials>
              <credential password="encrypted:VX1mne9VBLY=" user="vagrant" id="ssh-node1"/>
              <credential password="encrypted:VX1mne9VBLY=" user="vagrant" id="ssh-node2"/>
            </credentials>
          </environment>
          
          ... 
          
      </configuration>
      

Protect the master password file

The master password must be protected since it can be used to decrypt all passwords. To protect the password, set the location of the master password file to a location which can be protected using OS level measures by limiting access to the file.

The master password versus the default configuration

When Pineapple is started with no existing configuration then it will create a default configuration which contains:

  • Runtime directories used by Pineapple (e.g. .pineapple and sub directories).
  • Example modules (e.g. located in .pineapple/modules).
  • Configuration files (e.g. resources.xml and credentials.xml located in .pineapple/conf).

Pineapple's behavior regarding encryption of the passwords defined in credentials.xml which is created as part of the default configuration depends on whether the master password file exist.

Initialization of the default configuration when the master password file doesn't exist

If no password file exist at the resolved location and then Pineapple will generate a default master password. The passwords defined in the default configuration will be encrypted using the default master password.

Initialization of the default configuration when the master password file exist

If the password file exist then Pineapple will read the master password. The passwords defined in the default configuration will be encrypted using the read master password.