Getting Credentials from external Processes
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
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
If in shell context, can fetch the secret from an external process to the variable:
export OAUTH_CLIENT_SECRET=$(get-my-secret.sh)
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
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"]
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/" ]
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