Securely Storing Parameters in Red Hat Satellite

The Problem

When we integrate Red Hat Satellite with Ansible Tower we generally want to keep Red Hat Satellite as our single source of inventory data. How do we store sensitive data, such as passwords, in Red Hat Satellite, and ensure that it is available in the dynamic inventory for consumption in playbooks without exposing the data?

Red Hat Satellite does not support encrypted parameter values, only ‘hidden’ ones. These are less than useful as when accessed via an API script they are redacted. Ansible Tower does support encrypted variables, using Ansible Vault’s encrypt_string feature, however this only works with variables that are statically declared in files and not with dynamic content.

An Example

Consider an Ansible playbook that is used for configuring the Red Hat High-Availability Add-on. Most of the fencing agents used by the STONITH fencing mechanism require a password used to access the fencing device. If we want to store this within Satellite we have a problem – in order for it to be consumed by the playbook that actually configures the cluster, it would need to be in plain text.

A Solution

The solution is to store an encrypted copy of the secret parameter in Satellite, and then decrypt it in the playbook, using a Custom Credential to store the encryption passphrase.

Creating the Custom Credential Type

First, I create a new custom credential type, called Foreman Parameter Encryption as show below:

The input configuration is as follows:

fields:
  - secret: true
    type: string
    id: passphrase
    label: Passphrase
required:
  - passphrase

and the output configuration is:

extra_vars:
  foreman_key: '{{ passphrase }}'

This creates a new credential type in which I can store passphrases. Any passphrase stored will me exposed at runtime into the playbook as a variable called foreman_key.

Creating the Encryption Passphrase

I then decide on an encryption passphrase which I will use to encrypt and decrypt my sensitive data and store it in a credential of type Foreman Parameter Encryption:

Encrypting Data

On the commandline, I then encrypt my sensitive data:

$ echo -n "my super secret stuff" | openssl enc -e -aes-256-cbc -a -salt

entering the passphrase when prompted.

I can then store this encrypted string as a Foreman parameter as shown below:

Accessing Secret Parameters from within a Playbook

At this point I know that I can securely store sensitive data in Satellite, and expose it, still in encrypted form, via the dynamic inventory to Ansible Tower. The last step is to decrypt it within a playbook for use.

I first need to add the credential containing the encryption passphrase that I saved earlier to the Job Template. This will expose the passphrase within the playbook as the variable foreman_key. I can then decrypt foreman parameters with the following task:

- name: Decrypt my super secret stuff
  shell: echo {{ foreman_params.my_secret_stuff }} | openssl enc -pass pass:{{ foreman_key }} -d -aes-256-cbc -a
  register: decrypted_secret_stuff
  no_log: true

Note the use of no_log: true to ensure that decrypted variables are not reflected to the log – this should be specified in any task that consumed the decrypted_secret_stuff variable.

Spread the love

Leave a Reply

Your email address will not be published. Required fields are marked *