Introduction

This page discusses how to avoid passwords in configuration files by using configured credential processes or environment variables.This is especially needed when credentials change often and / or are stored in central infrastructure such as personal or company wide password managers. In addition to that, you might find it useful when working with cmemc in CI/CD pipelines.

Environment Variables

As described in the Configuration with Environment Variables document, cmemc can be configured with environment variables. The following code snippet demonstrates behaviour:

export CMEM_BASE_URI="https://your-cmem.eccenca.dev/"
export OAUTH_GRANT_TYPE="client_credentials"
export OAUTH_CLIENT_ID="cmem-service-account"
export OAUTH_CLIENT_SECRET="...secret..."
cmemc graph list
CODE

In the context of a CI/CD pipeline e.g. on github, these credentials can be taken from the repository secrets:

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: run cmemc 🔁
    env:
        OAUTH_CLIENT_SECRET: ${{ secrets.OAUTH_CLIENT_SECRET }}
        ...
    run: |
            cmemc graph list
CODE

If in shell context, can fetch the secret from an external process to the variable:

export OAUTH_CLIENT_SECRET=$(get-my-secret.sh)
CODE

External Processes

Another option, which is interesting when working with multiple Corporate Memory instances, is to configure an external process in your cmemc configuration file.

In order to get credential information from an external process, you can use the following configuration keys to setup an external executable:

  • OAUTH_PASSWORD_PROCESS, to setup the process to get the use password when using grant type password.
  • OAUTH_CLIENT_SECRET_PROCESS, to setup the process to get the client secret when using grant type client_credentials.
  • OAUTH_ACCESS_TOKEN_PROCESS, to setup the process to get the direct access token.

The credential executable can use the other cmemc environment keys of the configuration block for fetching the credential (e.g. CMEM_BASE_URI and OAUTH_USER).

If the credential executable is not given with a full path, cmemc will look into your environment PATH for something which can be executed.

The configured process needs to return the credential on the first line of stdout. In addition to that, the process needs to exit with exit code 0 (without failure).

The following config section demonstrates this behaviour:

[your-cmem]
CMEM_BASE_URI=https://your-cmem.eccenca.dev/
OAUTH_GRANT_TYPE=client_credentials
OAUTH_CLIENT_ID=cmem-service-account
OAUTH_CLIENT_SECRET_PROCESS=get-my-secret.sh
TEXT

In addition to that, if you need to add options to the call, you need to write the call as list:

[your-cmem]
CMEM_BASE_URI=https://your-cmem.eccenca.dev/
OAUTH_GRANT_TYPE=client_credentials
OAUTH_CLIENT_ID=cmem-service-account
OAUTH_CLIENT_SECRET_PROCESS=["getpass.sh", "parameter1", "parameter2"]
TEXT


Here is an working example with the MacOS Keychain, which can be queried with the command line tool secret.

This example fetches a password for account cmem-service-account on service https://your-cmem.eccenca.dev/.

OAUTH_CLIENT_SECRET_PROCESS=["security", "find-generic-password", "-w", "-a", "cmem-service-account", "-s", "https://your-cmem.eccenca.dev/" ]
TEXT

The corresponding keychain entry looks like this:

In order to avoid repeating this long line in a cmemc configuration with lots of entries, this could be wrapped in a shell script like this:

get-cmemc-pass-via-macos-keychain.sh

#!/usr/bin/env bash

if [ "${OAUTH_GRANT_TYPE}" = "client_credentials" ]; then
    security find-generic-password -w -a "${OAUTH_CLIENT_ID}" -s "${CMEM_BASE_URI}" || exit 1
    exit 0
fi
if [ "${OAUTH_GRANT_TYPE}" = "password" ]; then
    security find-generic-password -w -a "${OAUTH_USER}" -s "${CMEM_BASE_URI}" || exit 1
    exit 0
fi
exit 1
BASH