Using Ansible Keyring Lookups

Wade Rossmann
3 min readJun 2, 2022

--

A stock photo of a lock on some keyboard keys that I thought looked neat.
Photo by FLY:D on Unsplash

Sometimes in order to run an Ansible play you need local, per-user secrets. For example, if your playbook joins a machine to a domain it will need the credentials of a domain administrator.

The naive solution is just to throw the credentials in plaintext in vars/secret.yml with an appropriate .gitignore so that they don’t accidentally get committed. But all it really takes is a thoughtless git add -af and you’re in trouble.

Of course, Ansible itself provides its own Vault functionality for encrypting secret files and/or vars. However, the downside of this is either using --ask-vault-pass and typing your password on every invocation, or using --vault-password-file which means you’re storing that password in plaintext somewhere and have similar risks.

But if you use GNOME, or something GNOME-adjacent, for your desktop environment, then you’re likely already got a solution ready to go: keyrings. Long story short, the GNOME keyring stores your secrets encrypted in ~/.local/share/keyrings and the agent starts with your login session to provide access.

Ansible uses Python’s keyring package to interface with this, though the way it operates is fairly rigid. I’ll get to this later.

Requirements

  1. The keyring Python package, eg: pip install keyring
  2. A running gnome-keyring-daemon process. This should start with your login, but if not then run gnome-keyring-daemon --unlock .

Setting the Secrets

From the command line, run keyring set foo bar which will prompt you to enter a password, but this is the value of the secret that you are storing.

Using the Secrets in Ansible

Using the above secret is as simple as lookup('keyring', 'foo bar') .

Python’s Weird Implementation of Keyring

The broad stroke of the GNOME keyring is that each entry is identified by one or more attribute-value pairs, has a label, and of course a secret. These attribute-value pairs can really be anything you like, but the Python implementation strictly locks these to service and username attributes, and constructs a generic label.

Eg: For keyring set foo bar the following entry will be made in the default keyring:

Label: Password for 'bar' on 'foo'
Attributes:
application: Python keyring library
service: foo
username: bar

To make an equivalent entry using GNOME’s own secret-tool utility:

secret-tool store \
--label="Password for 'bar' on 'foo'" \
application 'Python keyring library' \
service foo \
username bar

You can also view and manage keyring entries via the Seahorse GUI utility, which is useful when it comes time to rotate passwords, but beware that as of this writing there is no apparent way to set attributes on entries during creation.

“But I want to securely share secrets across the whole environment and/or organization!”

Then I cannot recommend Hashicorp’s Vault highly enough. The basic secrets engine will do exactly this, but there are also additional engine for thing like running an internal PKI CA, or performing transit encryption.

Use it.

Disclaimer: I am not paid, endorsed, or otherwise beholden to Hashicorp. They just make really good stuff.

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

Wade Rossmann
Wade Rossmann

No responses yet

Write a response