Open Source

Centralizing Operational Secrets with Ansible

Organizations need to manage secrets for operations and systems at scale, but solution effectiveness varies. In this blog, we explore options, their known gaps, and a solution Basis Theory developed for the Ansible community.

Centralizing Operational Secrets

Secrets are sensitive values, such as passwords, keys, and certificates, that must be shared across multiple systems—from applications to servers to build systems.

Some standard solutions to handle secrets are:

  1. Storing secrets within the CI/CD system: This approach stores the secrets in a secrets management solution within the CI/CD system - granting access only when performing builds and releases. Storing secrets in your CI/CD system requires any configuration be encrypted and stored in a secure location, which also risks these secrets being exposed via build logs as plaintext. 
  2. Passworded / Encrypted Files: Stores secrets in an encrypted file is a default solution for many automation tools - for example Ansible’s Vault utilizes this approach. A major drawback is passwords are needed to decrypt these files,creating another set of challenges by needing to to protect, rotate, and share this password. 
  3. Key Management Service (KMS): This approach connects systems to a KMS to enable safely retrieving secrets. KMSs secure the handling and management of the secrets although tend to be all-or-nothing when it comes to reading secrets, which risks exposing secrets to systems which should not have access. Keep in mind, KMS solutions require additional infrastructure and usage costs associated with them.

When asked to securely store, handle, access, and distribute secrets, existing solutions encounter problems. We want a solution that enables us to store a reference to the secret within our configuration or state files; easily distribute the secret across multiple systems and applications; restrict access to the secrets; and have the solution low cost.

To demonstrate how to solve this problem, we developed an Ansible Lookup Plugin. The Plugin stores a Basis Theory token within the Ansible configuration, allowing us to perform just-in-time lookups of the original secret value whenever we configure our systems.

Ansible Lookup Plugin

Ansible Lookup plugins retrieve data from outside sources, such as files, databases, key/value stores, APIs, and other services.” 

The Basis Theory Ansible Lookup Plugin works against Basis Theory’s REST API to retrieve the data. Just want to dive right into the code? Check out the Ansible Lookup in our GitHub repo.

First thing we need to do is create the plugin. We do this using our Basis Theory Python SDK.

We configure the client configuration and connection:


# Defining client wide api_key
configuration = basistheory.Configuration(
    host='https://api.basistheory.com',
    api_key=os.environ.get('BT_API_KEY')
)

with basistheory.ApiClient(configuration) as api_client:
    # Create an instance of the tokens API client
    token_client = tokens_api.TokensApi(api_client)
)

Then we retrieve our tokens using the <span class="code"/>token_client</span> with the <span class="code"/>get_by_id</span> method.


response = token_client.get_by_id(id=term)
ret.append(response)

To use this in Ansible, we just call the lookup like any other lookup, and the simplest example is getting back a value, setting a variable, and then interpolating that variable in a file:


- name: Just in time configure local Server Fact Variable
    set_fact:
        my_api_key: "{{ lookup('basistheory', '484dc5f6-1177-4243-abbf-775c11d2a17a') | community.general.json_query('data') }}"
- name: Write Template File
    template:
        src: lookup_test.j2
        dest: /tmp/lookup_test.cfg

And that’s it. With about a dozen lines of code and our Python SDK, we retrieved a secret directly from Basis Theory in our Ansible playbook.

Interested in trying Basis Theory? Simply register an account, name your first Tenant in our Web Portal, and create an application. Takes less than a minute and there’s no credit card required. Have questions? Contact us!

NEXT STEPS

Where to go from here?

{"type":"shift","speed":14,"random":1,"shift":1,"size":1,"rupture":70}
Usage-based pricing, but getting started is free
{"type":"shift","speed":20,"random":1,"shift":1,"size":1,"rupture":50}
Built by developers, for developers
{"type":"shift","speed":11,"random":1,"shift":1,"size":1,"rupture":50}
Helpful humans ready to work through your questions
{"type":"shift","speed":29,"random":1,"shift":1,"size":1,"rupture":50}
We’re building something special & would love your help