Manage Secrets

After you have obtained a token, you can use multiple ways to create/update/read/delete secrets in your claimed vault path.

HashiCorp Vault is used as a secret storage backend behind the Cloud Secrets, so after you provision your safes using Cloud Secrets web app, you have to use the same fully qualified domain name (FQDN) for reading/writing actual secrets, just by using regular Vault commands.

Vault is an excellent piece of software for storing, accessing and sharing secrets between humans and services. Vault uses client - server architecture and provides HTTP API as well as command-line interface for secrets management, however, how to manage user access to those secrets is an open question which doesn't have a straightforward answer.

When enabled, multiple authentication methods enable users and applications authenticate to Vault, including GitHub, LDAP, JWT/OIDC, RADIUS authentication methods, among many others. Some of the methods, like LDAP or OIDC, can be leveraged also for authorization. By defining relationships between the information obtained from the authentication method and Vault groups in advance, Vault can map access policies based on the information provided from the 3rd party authentication.
However, all of the authentication methods requires Vault to be configured in advance. Static policies must be mapped to authenticated entities, so if you expect some kind of self-service, where user can create their own safe space, you are on your own.

Case study - Hashicorp Vault

You can use Vault with:

  • A command-line interface (CLI) by using Vault binary

  • Ansible roles - save-secrets / load-secrets, that can run locally or within the Gitlab pipeline

  • calling HTTP API directly by using curl command or libraries like Python requests

Using Vault command-line interface (CLI)

To manage your secrets manually, you can use command-line interface of the Vault software itself:

  1. download Vault binary

  2. Setup environment variables:

  + `export VAULT_ADDR=<https://vault.example.com`>
  + `export VAULT_TOKEN=<your token>`
  1. Use CLI commands:

# list all entries under "secret/someproject" path
vault list secret/someproject

# read entry "mysecret" from "secret/someproject"
vault kv get secret/someproject/mysecret

# read "secret" field from "mysecret" secret located in "secret/someproject" path
vault kv get -field=secret secret/someproject/mysecret

# delete "mysecret" secret
vault delete secret/someproject/mysecret

# create new entry "yeatanotherpassword" with the "password=quert123" key/value pair  
vault kv put secret/someproject/yetanotherpassword password=quert123

You can find basic CLI usage guide also on a vendor site.

Using Ansible for managing secrets

When the secrets are expected to be available in Ansible variables, we are using Ansible roles to read / write secrets:

You must define mount point, Vault path & name of a secret. Roles can generate password on its own, if it does not exist:

Read secret to Ansible variable

- hosts: all
  become: false
  vars:
    secret_store: "vault"
    vault_mount: "secret"
    vault_path: "someproject"
    vars_stored:
      - var: "mysecret"
        key: "secret"
  roles:
    - ansible-load-secrets

Write secret to Vault

- hosts: all
  become: false
  vars:
    # full path will be secret/someproject/mysecret
    secret_store: "vault"
    vault_mount: "secret"
    vault_path: "someproject"
    vars_stored: # secret name and key for reading key/value pair
      - var: "mysecret"
        key: "secret"
  pre_tasks:
    - name: set variable content
      set_fact:
        mysecret: "DEADBEEF"
  roles:
    - ansible-save-secrets

Please note, that all secrets should be Base64 encoded.
For more information on how to use roles for reading/saving secrets, please check the appropriate role README files.

Accessing secrets via HTTP API

As with other methods, you need to know Vault address and have a valid token, then you can read/write/list secrets by calling secret store HTTP API:

# export environment variable
export VAULT_TOKEN=<your token>
# list secrets located in "somesafe"
curl \
    --header "X-Vault-Token: $VAULT_TOKEN" \
    --request LIST \
    <https://vault.example.com/v1/secret/someproject>
# write secret
curl \
    --header "X-Vault-Token: $VAULT_TOKEN" \
    --request POST \
    <https://vault.example.com/v1/secret/someproject/mysecret> \
    -d \
'{
  "dead":"beef"
}'
# read secret using http API
curl \
    --header "X-Vault-Token: $VAULT_TOKEN" \
    <https://vault.example.com/v1/secret/someproject/mysecret>