All articles

Managing Secrets in Ansible using passbolt

7 min. read

Jean-Christophe Vassort

Jean-Christophe Vassort

7 April, 2022

Ansible is an open source IT automation engine sponsored by Red Hat to enable devops, developers and system administrators to automate the management of servers and workstation. It can be used for server provisioning, configuration management, application deployment, service orchestration, and many other IT processes.

In this article we assume that you are a little bit familiar with Ansible. If you are new to this, you can have first a look at this article to get an introduction.

One common task that one faces when using Ansible is the need to manage secrets like, for example, the passwords or keys used to connect two services together. The most used solutions for this problem are Ansible Vault or Ansible lookup plugins. Another approach would be to use Passbolt.

We will look at these three options in this article, to give you some perspective on the different approaches, as well as outline some of the advantages of using passbolt for this use case.

Managing secrets in Ansible

Using Ansible Vault

Ansible Vault provides a dedicated Ansible command-line tool to encrypt secrets which are stored in your Ansible inventory, protected by a passphrase and versioned with an SCM like git. Let’s first see how to use Ansible vault, so that we can compare it with the passbolt solution. In the below example, we will encrypt the string “password”:

$ ansible-vault encrypt
New Vault password: ****
Confirm New Vault password: ****
Reading plaintext input from stdin
password
Encryption successful

Ansible Vault returns the encrypted content:​​

$ANSIBLE_VAULT;1.1;AES256
353030646433386461373032366165…1646330333236663632656338373231636631

It is this encrypted content you will store in your git repository.

Vault decryption is simple and easy:

$ ansible-vault decrypt
Vault password: ****
Reading ciphertext input from stdin
$ANSIBLE_VAULT;1.1;AES256
353030646433386461373032366165…1646330333236663632656338373231636631
Decryption successful
password

Using Ansible lookup plugins

Another way to manage secrets is to extend Ansible capabilities with a lookup plugin. You can use lookup plugins to access data from 3rd party sources such as Hashicorp Vault, AWS Secret Manager, etc.

Lookup plugins are an Ansible-specific extension to the Jinja2 templating language. As an example, this ansible task will create an Amazon RDS instance, with password looked up from AWS Secret Manager:

- name: Create RDS instance with aws_secret lookup for password param  rds:
    command: create
    instance_name: app-db
    db_engine: MySQL
    size: 10
    instance_type: db.m1.small
    username: dbadmin
    password: "{{ lookup('amazon.aws.aws_secret', 'DbSecret') }}"

The database password is retrieved with the lookup() function who invokes the aws_secret plugin from amazon.aws ansible collection.

Managing Ansible secrets using passbolt

What are the benefits of using passbolt?

Using passbolt for managing Ansible secrets introduces some functional benefits. You will be able to rotate secrets directly within passbolt without having to update your ansible inventory (and add new commits in your git repository…). Additionally passbolt audit logs will provide you with a clear audit trail on when these secrets were accessed.

Moreover you will also benefit from having a centralized repository for all your team’s secrets, not just the Ansible ones.

Security considerations

Switching to passbolt from Ansible vault is not without changes in your risk landscape. For example in terms of availability, if you adopt passbolt, your infrastructure will now be relying more on the passbolt service. In short, you will need have a disaster recovery plan to make sure your passbolt service is resilient.

With passbolt, the most critical components are your private key and passphrase who will unlock the access to your passwords. There is multiple ways to protect them. In this example we will see how you can use the ansible plugin to delegate the cryptographic operations to gnupg via gpg-agent. Alternatively you can also store the private key and passphrase on an external tool and use Ansible lookup plugin feature to fetch them.

Finally, a good practice is to always use a dedicated passbolt user account, that will server as a technical account with read-only access, to make sure to limit access to the resource you need for a given process. As a general advise, you should never use an account with write accesses if you don’t need it.

Don’t hesitate to read our blog post about passbolt and Gitlab CI/CD, you will surely find some additional useful security tips.

Passbolt ansible lookup plugin usage

The passbolt ansible lookup plugin gives you the possibility to retrieve credentials from any passbolt instance. Let’s see how.

Setup

Additional ansible content is usually distributed as “Collections”, a distribution format for Ansible content that can include playbooks, roles, modules, and plugins.

Official collections are listed on https://docs.ansible.com/ansible/latest/collections/. The collections submitted by the community are available here: https://galaxy.ansible.com.

You will find the passbolt lookup plugin used in this example in this collection: https://galaxy.ansible.com/anatomicjc/passbolt

You can install it with this command:

$ ansible-galaxy collection install anatomicjc.passbolt

As ansible is written in python language, you will need the py-passbolt library to use it. You can install it in this way:

$ python -m pip install py-passbolt

We have created a git repository with an ansible playbook example that covers all current cases about how to use the passbolt lookup plugin.

Authentication

Passbolt uses GpgAuth for Authentication, which is a challenge based authentication similar to SSH. In this example the authentication is done through environment variables available only in the ansible-playbook scope. We use gnupg to perform the cryptographic operations needed for the authentication. We list two options without gpg-agent (by calling PGPy library, an OpenPGP python implementation) or with the gpg-agent (generally the recommended way).

Without gpg-agent, you need to provide your OpenPGP private key and associated passphrase:

environment:
  PASSBOLT_BASE_URL: "https://passbolt.domain"
  PASSBOLT_PRIVATE_KEY: "{{ private_key_vault }}"
  PASSBOLT_PASSPHRASE: "{{ passphrase_vault }}"

In our demo repository, sensitive variables such as the OpenPGP private key and its passphrase are encrypted with ansible-vault. You will find vaulted variables here.

If you prefer using a gpg-agent, you won’t need to put your private key and passphrase in Ansible vault, here is the relevant configuration:

environment:
  PASSBOLT_BASE_URL: "https://passbolt.domain"
  PASSBOLT_GPG_LIBRARY: "gnupg"
  PASSBOLT_FINGERPRINT: "1321159AE7BEE9EF9C4BBC7ECBAD2FB0C22FE70C"

With this configuration, the cryptographic work is delegated to gpg-agent and your private key and passphrase won’t be stored in your git repository. You will need to setup the keyring and inject the passphrase yourself via command line. It allows you to get better passphrases and private key security by leveraging gnupg keyring and pinentry functionalities directly.

How to use passbolt lookup plugin

We will use below a passbolt variable for convenience. The full plugin name to be used is ‘anatomicjc.passbolt.passbolt’ .
You can have a look at our ansible playbook example.

Now that we got authentication out of the way, let’s see how we can get access to some secrets. By default, passbolt lookup plugin will let you search on the resource name. If you want to search, for example, for an “OVH” resource you will write:

lookup(passbolt, 'OVH')

It will be fine if you have only one OVH resource in your passbolt resource list. If you have multiple entries with different usernames, you can use additional filters to refine your search:

lookup(passbolt, 'OVH', username='[email protected]')
lookup(passbolt, 'OVH', username='[email protected]', uri='https://api.ovh.com')

The passbolt lookup plugin will always return the first match.

For each passbolt resource, you have an unique uuid. So to further avoid confusion you can also search per uuid instead of resource name with the per_uuid filter:

lookup(passbolt, 'a294b8d6–5dae-4db6–9e49-f790781cec30', per_uuid='true')

Now let’s assume you want to use the ansible aws s3 module, you can define aws variables like this:

vars:
  aws:
    access_key: "{{ lookup(passbolt, 'AWS').password }}"
    secret_key: "{{ lookup(passbolt, 'AWS').description }}"

Then you will be able to generate a credentials profile file by using your new aws variable:

- name: Generate AWS credentials profile
  ansible.builtin.copy:
    dest: ${HOME}/.aws/credentials
    owner: "{{ lookup('env', 'USER') }}"
    mode: "0600"
    content: |
      [default]
      aws_access_key_id={{ aws.access_key }}
      aws_secret_access_key={{ aws.secret_key }}

Full example Ansible playground

We hope this article gave you the hitch to take the passbolt and ansible for spin. To simplify this, we place the code used in this article in an example repository. In this repository you will find a docker-compose.yml file that will create a small passbolt instance ready to play with ansible.

Clone the project:

git clone [email protected]:passbolt/lab-passbolt-ansible-poc.git

Launch the stack:

cd lab-passbolt-ansible-poc
docker-compose up -d

Jump in the ansible container:

docker-compose run ansible

You are now good to launch the ansible playbook to see it in action!

ansible-playbook playbooks/example-playbook.yml

Resources to go further

Here are some additional resources that were mentioned in this article:

We would like to thank @Ewertonmarschalk from passbolt community forum who created the python library used in this example Ansible lookup plugin.

If you are an Ansible afficionados, maybe you will also be interested by other ansible community projects such as @neuroforgede ansible role to setup passbolt with docker, or @daniel lynch Ansible Collection who contains another lookup plugin as well as ansible modules to interact with your passbolt instance by creating users, groups…

Passbolt community is awesome and we are delighted when we discover new projects, tools and integrations that uses the API. You guys rock!

Conclusion

That’s all for today! We talked about how to manage ansible secrets with passbolt and introduced the passbolt lookup plugin. We hope this gives you some ideas on how you can leverage passbolt to automate some of your workflows.

Feel free to open a discussion on the passbolt community forum to discuss your ideas or if you have further questions. We’ll be happy to read your thoughts about this.

See you soon for another sysops / devops topic!

h
b
c
e
i
a