1

So I created encrypted key using ansible-vault create my.key.

Then I use it as var:

my_key: "{{ lookup('file','{{ inventory_dir }}/group_vars/my.key') }}"

And then when running my playbook, like this:

- name: Create My Private Key
  ansible.builtin.copy:
    content: "{{ secrets.my_key }}"
    dest: "{{ secrets_key }}"
    no_log: true

It does properly create key on remote host and it is then unencrypted. But I'm thinking if this is the right way to do it? Does it unencrypt at the right time and I am not exposing sensitive data where it should not be?

I thought encrypted variables must also have !vault keyword specified. But if I do this for my my_key, I get this error:

fatal: [v14-test]: FAILED! => {"msg": "input is not vault encrypted data. "}

So this got me worried, that file is unencrypted at the wrong time or maybe message is misleading or something.

Is this the right way to do it? Or I should do it differently?

Andrius
  • 19,658
  • 37
  • 143
  • 243

1 Answers1

0

Firstly, a definitive answer as to whether this approach is appropriate, is directly linked to what you want to achieve from encryption. Therefore all the answers here can do is talk about how Vault works and then you can decide if it is right for your requirements.

Fundamentally what you are doing is a 'correct' usage of Ansible Vault, although I have not previously seen it used in quite this workflow (typically I have seen create used for encrypting YAML files of vars).

Using your method, your secret is turned into ciphertext and stored in my.key (which can be confirmed by using basic text tools such as cat, less or more). You will see the first line of the file, contains a bunch of metadata that allows Ansible to understand the file contents and decrypt on demand.

At runtime, Ansible will then use the password/key for the encrypted file (accessed through a number of methods) to decrypt the file contents into plain text and then store it in the variable my_key for use during the play.

A non-exhaustive list of things to consider when determining if Ansible Vault is the right approach for you:

  • Ansible Vault encryption is purely designed to protect secrets at rest (i.e. when they are stored on your hard disk)
  • At run time, the secrets are converted into plain text and treated like any other variable/string data, however the file on disk still contains ciphertext so the plaintext is only accessible within the running Ansible process (i.e. on a multi-user system, at no point can anybody view the plaintext simply by looking inside the my.key file. However, depending on their level of access, skills and what your Ansible tasks are doing, they may be able to access the plaintext from the running process.)
  • Given inside the process the data is just plain text, it is vulnerable to leakage (for example by writing the contents out into a log file - checkout the Ansible no_log option)
  • At run time, Ansible needs some way to access the key necessary to decrypt the ciphertext. It provides a variety of methods, including prompting the user, accessing it from a file stored on disk, accessing it from an Env var, using scripts/integrations to pull it from another secrets mgmt tool. Careful thought needs to be given about which option is chosen, relative to what you are looking to achieve from the encryption (e.g. if your goal is to protect your data in the event that your laptop gets stolen, then storing the key in a file on the same system, renders the whole operation pointless). Quite often, with more sophisticated methods, you can still end up in a 'chicken and egg' situation, once more relative to what your goal from using encryption is
  • I might be talking complete cobblers or be a nefarious individual trying to sow disinformation, so read the docs thoroughly if the value of the secrets if significant to you :)

Unfortunately there is no getting away from generally good security is harder to achieve than the illusion of good security :|

clockworknet
  • 2,736
  • 1
  • 15
  • 19
  • I do encrypt some variable values directly on `yml` file. For key, I decided to encrypt file separately, as encrypted contend is quite big, so it would pollute vars. And I don't want to encrypt `whole` yml, as I would not see var keys etc. And yeah, I also use `no_log`, to prevent leakage. So I guess my approach is safe enough:) – Andrius Oct 22 '21 at 09:16