Skip to main content
This section demonstrates how to validate the integration of Ansible Vault with the Futurex PKCS#11 library. A sample text file is encrypted using Ansible Vault, with the vault password stored in a separate file. That password file is then encrypted using the CryptoHub. During decryption, the password is recovered via the CryptoHub and passed to Ansible Vault to decrypt the original file. The example highlights security of keys stored on a CryptoHub and automated secrets handling in Ansible playbooks.

Create a key pair on the CryptoHub

Perform the following two tasks to create a key pair:

Set Futurex environment variables

Perform the following steps by using the pkcs11-tool available from the OpenSC ( github.com/OpenSC/OpenSC) suite to generate keys. On both DEB-based and RPM-based distributions, the package is calledopensc. In a terminal, run the following commands to set the requiredFXPKCS11 environment variables:
Shell
export FXPKCS11_MODULE=/path/to/libfxpkcs11.so;

export FXPKCS11_CFG=/path/to/fxpkcs11.cfg;
Be sure to modify the file path to match the location of libfxpkcs11.so and fxpkcs11.cfg on your system.

Create a key pair

In a terminal, run the following command to create a new ECC key pair on the CryptoHub by using pkcs11-tool:
Shell
sudo pkcs11-tool --module $FXPKCS11_MODULE --login --keypairgen --key-type rsa:2048 --label "ansible_rsa_privatekey" --id "123456" --usage-decrypt
When prompted for the user PIN, enter the password of the identity configured in the fxpkcs11.cfg file.
If successful, the command output lists the keys that pkcs11-tool created on the CryptoHub.

Ansible Vault playbooks

In Ansible, playbooks perform automated tasks. You can reference the Futurex PKCS#11 library when performing these tasks inside the playbook file to perform various functions, including encrypting and decrypting files.

Prerequisites

You must create a file for the Vault Password(such as vault_password_file.txt) and place it in the same directory with the other test files. This is the password that Ansible Vault uses to encrypt and decrypt the sample test file. Due to the importance of a password file, this file will be encrypted with a public key that is stored on CryptoHub.
In this example, we use a vaultpasswordfile.txt because Ansible Vault typically requires the password to be supplied through a file or an executable script. This approach is essential for non-interactive automation and enables integration with HSM-based encryption workflows.
The testing examples provided are for demonstration purposes only and are not intended for use in production environments. Be sure to apply proper security practices, such as secure password handling, encrypted communications, and HSM configurations, when deploying to production.

Inventory file

An inventory file in Ansible defines the hosts that Ansible will manage. It can list IP addresses, hostnames, and groupings of machines, allowing you to organize and target them in playbooks. The file can be written in INI or YAML format. Example (INI format):
Ini
[local]
localhost ansible_connection=local
In the example above, local is targeted for local execution, common in test setups.

Example Directory Layout

test\_ansible/
  \|--- encrypt.yml
  \|--- decrypt.yml
  \|--- inventory
  \|--- test.txt 
  \|--- vault\_password\_file.txt

Encrypt example

You must copy and paste the contents of this example into a file with the .yml extension and modify it as needed (such as encrypt.yml) The following example file performs the following actions:
  1. Encrypts test.txt using Ansible Vault with the provided password file. Note:test.txt can be a text file containing sample data.
  2. Uses CryptoHub's public key, which was generated earlier, to encrypt vault_password_file.txt, storing the result in vault_password_file.txt.enc.
  3. Deletes the original, unencrypted vault_password_file.txt to protect sensitive data.
  4. Displays a success message if all tasks are completed successfully.
YAML
---
- hosts: localhost
  vars:
    pkcs11_key_label: "ansible_rsa_privatekey" ## This is the key label that was generated in the earlier step
    test_file: "/home/futurex/test_ansible/test.txt" ## This is the test file with sample data
    password_file: "/home/futurex/test_ansible/vault_password_file.txt" ## This is the file that contains an ansible password of your choosing password
    encrypted_password_file: "/home/futurex/test_ansible/vault_password_file.txt.enc" ## This is the created file where the encryptted passsword will be placed 
  tasks:
    - name: Encrypt test data with Ansible-Vault
      command: >
        ansible-vault encrypt {{ test_file }} --vault-password-file {{ password_file }}

    - name: Encrypt Vault Password File with HSM public key
      command: >
        openssl pkeyutl \
        -provider pkcs11 \
        -inkey 'pkcs11:object={{ pkcs11_key_label }};type=public' \
        -pubin -encrypt \
        -in {{ password_file }} \
        -out {{ encrypted_password_file }}

    - name: Remove plaintext vault password file
      file:
        path: "{{ password_file }}"
        state: absent

    - name: Confirm encryption success
      stat:
        path: "{{ encrypted_password_file }}"
      register: encrypted_result

    - name: Display success message
      debug:
        msg: "Vault password file encrypted with HSM key."
      when: encrypted_result.stat.exists
After you modify the playbook file according to your environment, use the following shell command to run the playbook:
Shell
ansible-playbook -u <your username> -i inventory encrypt.yml
After running the command, opening the test.txt file will reveal that it is now encrypted by Ansible Vault, displaying content similar to:
None
$ANSIBLE_VAULT;1.1;AES256
66393331626331366132616133666639656630353133613933336666663234316361373532353635
3138306138633134613765643466666639343463666437310a633238323135386565633238663634
64613837373931373762613562656137313137393266643336613061326132396231363132636162
3234343930663332370a323461626133333537646664373835383932356163343864346330656435
3663

Decrypt example

You must copy and paste the contents of this example into a file with the .yml extension and modify it as needed (such as decrypt.yml) The following example performs the following actions
  1. Uses the CryptoHub**‘s private key** to decrypt vault_password_file.txt.enc, restoring the original password into a temporary file.
  2. Decrypts test.txt using Ansible Vault with the restored password file.
  3. Deletes the temporary, decrypted password file after use to maintain security.
  4. Displays a success message if all tasks are completed successfully.
YAML
---
- hosts: localhost
  vars:
    pkcs11_key_label: "ansible_rsa_privatekey" ## This is the key label that was generated in the earlier step
    test_file: "/home/futurex/test_ansible/test.txt" ## This is the test file with sample data
    password_file: "/home/futurex/test_ansible/vault_password_file.txt" ## This is the file that contains an ansible password of your choosing password
    encrypted_password_file: "/home/futurex/test_ansible/vault_password_file.txt.enc" ## This is the created file where the encryptted passsword will be placed
  tasks:
    - name: Decrypt Vault Password File with HSM private key
      command: >
        openssl pkeyutl \
          -provider pkcs11 \
          -inkey 'pkcs11:object={{ pkcs11_key_label }};type=private' \
          -decrypt \
          -in {{ encrypted_password_file }} \
          -out {{ password_file }}

    - name: Decrypt the test file using Ansible-Vault
      command: >
        ansible-vault decrypt {{ test_file }} --vault-password-file {{ password_file }}

    - name: Remove decrypted vault password file
      file:
        path: "{{ password_file }}"
        state: absent

    - name: Confirm decryption success
      stat:
        path: "{{ test_file }}"
      register: decrypted_result

    - name: Display decryption success message
      debug:
        msg: "File decrypted successfully using Vault + HSM."
      when: decrypted_result.stat.exists
After you modify the playbook file according to your environment, use the following shell command to run the playbook:
Shell
ansible-playbook -u <your username> -i inventory decrypt.yml