CyberArk Conjur

This topic describes how to deploy Secretless in Kubernetes/OpenShift using CyberArk Conjur. Rather than supply your application with its database credentials directly, you deploy your application with the Secretless Broker sidecar to keep secrets out of your app and keep them secure.

Prerequisites

OpenShift vs Kubernetes

The code snippets in this topic use kubectl. If you are deploying OpenShift, replace each kubectl with oc

Assumptions

  • You have an application that requires a PostgreSQL or MySQL database

  • You are using a supported version of OpenShift or Kubernetes

  • You have already set up the database, it is accessible to apps running in your OpenShift / Kubernetes environment, it supports SSL, and you have credentials for the database

  • You want to store the credentials in CyberArk Conjur, and you already have it running

 

To find out more information on how to get Conjur up and running, see the Conjur docs.

In this topic we focus on using the Conjur-Kubernetes authenticator to authenticate with Conjur, so you may also find it helpful to start out by reading its documentation as well.

Before getting started, you may want to read up on How it works or Configuration.

Load Secrets

First, load your database credentials into Conjur. In this example we use PostgreSQL, however the setup for MySQL is similar.

  1. Create a Conjur policy. It defines variables for the database connection information and a secrets-users group with access to read the secrets.

     
    ---
    - !policy
      id: my-app
      body:
      - &variables
        - !variable address
        - !variable username
        - !variable password
    
      - !group secrets-users
    
      - !permit
        resources: *variables
        privileges: [ read, execute ]
        role: !group secrets-users
    
  2. Save the above policy as my-app.yml. Ensure you are logged in to Conjur using the CLI. Store the database connection details in your environment in POSTGRES_ADDRESS, POSTGRES_USERNAME, and POSTGRES_PASSWORD environment variables and run the following commands to load the Conjur policy and set the variable values:

     
    conjur policy load root my-app.yml
    conjur variable values add my-app/address $POSTGRES_ADDRESS
    conjur variable values add my-app/username $POSTGRES_USERNAME
    conjur variable values add my-app/password $POSTGRES_PASSWORD
     
    Loaded policy 'root'
    {
      "created_roles": {
      },
      "version": 1
    }
    Value added
    Value added
    Value added
     

    The command above loads the database policy into root. You may choose instead to load the policy into another policy branch. In addition, the command follows the syntax for the version 5.x Conjur API - if you are using Conjur EE v4.9.x, your syntax will be different and you should reference the Conjur v4 documentation for more information.

The Conjur documentation provides comprehensive guidelines for configuring the application identity that the Secretless Broker will use to authenticate to Conjur. Secretless Broker contains a Conjur authenticator, so the instructions in the documentation for configuring the Conjur authenticator should also be applied to Secretless. The CyberArk Conjur provides additional guidelines on configuring Secretless to authenticate with Conjur, including alternate authentication methods.

To use Secretless as a Conjur authenticator you need to assign it a machine identity. The type of identity you choose will determine the format of the host ID that Secretless uses to authenticate with Conjur; for now, in this guide, we will refer to Secretless Broker's Conjur identity as <conjur-host-id>.

Create the Secretless Broker configuration

Next, define the Secretless Broker configuration. Secretless uses this configuration to determine where to listen for incoming connections, where to route those connections, and where to get the credentials for each connection.

Write the following YAML to a file named secretless.yml.

 
listeners:
  - name: pg
    protocol: pg
    address: 0.0.0.0:5432
handlers:
  - name: pg
    listener: pg
    credentials:
      - name: address
        provider: conjur
        id: my-app/address
      - name: username
        provider: conjur
        id: my-app/username
      - name: password
        provider: conjur
        id: my-app/password

The configuration above instructs Secretless to listen on port 5432 for an incoming PostgreSQL connection. The credentials for the connection are going to come from the variables stored in the my-app Conjur policy branch.

 

By default Secretless Broker will connect to PostgreSQL using sslmode=require. For information on additional sslmode values available, please see the Handlers.

To store the configuration in Kubernetes / OpenShift and make it accessible to the Secretless sidecar container, create a new ConfigMap in Kubernetes using the newly created secretless.yml.

 
kubectl create configmap my-app-secretless-config --from-file=secretless.yml

If your Conjur instance uses TLS for communication, Secretless will also need access to your Conjur SSL certificate. The most convenient way to make it available is by storing it in a ConfigMap. You can run the following commands to retrieve the Conjur SSL certificate and store it in a ConfigMap named conjur-ssl-cert

 
openssl s_client -showcerts \
  -connect <CONJUR_APPLIANCE_URL> </dev/null 2>/dev/null \
  | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > conjur.pem

kubectl create configmap conjur-ssl-cert --from-file ssl-certificate=conjur.pem

In the command above, replace <CONJUR_APPLIANCE_URL> with the URL of the Conjur instance Secretless Broker will connect to.

Update Your Application

If you are already running your application elsewhere, it likely already has some method of retrieving or storing database credentials and opening the database connection.

To prepare your application to connect to the database via Secretless instead, you can remove any existing database credentials from the application and configure it to connect to localhost:5432 - the port that Secretless is listening on.

That's it! It really is that simple to set up your app to use Secretless.

Add the Secretless Broker Sidecar to Your App Deployment

Secretless Broker is deployed as a sidecar container in the same pod as your application. You can deploy Secretless with your app by modifying your application manifest to include the Secretless Broker container definition with its configuration ConfigMap provided via a volume mount.

An example application manifest is provided below.

 
---
apiVersion: apps/v1
kind: Pod
metadata:
name: my-app
namespace: demo
labels:
  app: my-app
spec:
  containers:
  # <-- Your container definition here -->
  # - name: my-app
  #   image: my-app:latest
  - name: secretless-broker
    image: cyberark/secretless-broker:latest
    args: ["-f", "/etc/secretless/secretless.yml"]
    ports:
    - containerPort: 5432
    env:
    - name: MY_POD_NAME
      valueFrom:
        fieldRef:
          fieldPath: metadata.name
    - name: MY_POD_NAMESPACE
      valueFrom:
        fieldRef:
          fieldPath: metadata.namespace
    - name: MY_POD_IP
      valueFrom:
        fieldRef:
          fieldPath: status.podIP
    - name: CONJUR_APPLIANCE_URL
      value: "{{ CONJUR_APPLIANCE_URL }}"
    - name: CONJUR_AUTHN_URL
      value: "{{ CONJUR_AUTHN_URL }}"
    - name: CONJUR_ACCOUNT
      value: {{ CONJUR_ACCOUNT }}
    - name: CONJUR_AUTHN_LOGIN
      value: "<conjur-host-id>"
    - name: CONJUR_SSL_CERTIFICATE
      valueFrom:
        configMapKeyRef:
          name: conjur-ssl-cert
            key: ssl-certificate
    volumeMounts:
    - name: config
      mountPath: "/etc/secretless"
      readOnly: true
  volumes:
  - name: config
    configMap:
      name: my-app-secretless-config

The manifest above includes some placeholders for a few variables required to properly configure Secretless Broker to communicate with Conjur. For information about setting each of these variables, please see the table below. For more information on all of the environment variables defined in the Secretless container definition above, please see the Conjur authenticator documentation.

Environment Variable

Description

CONJUR_APPLIANCE_URL

URL pointing to Conjur instance or load balancer

CONJUR_AUTHN_URL

URL pointing to authenticator service endpoint, usually of the form CONJUR_APPLIANCE_URL/authn-k8s/<AUTHENTICATOR_ID>

CONJUR_ACCOUNT

Conjur account that you set up when you configured Conjur

 

Before you deploy your application you will want to ensure the Conjur host identity for Secretless has access to the secrets in the my-app policy, otherwise the broker will be unable to retrieve them.

Run

Once you have updated your application manifest to include the configured Secretless Broker sidecar, save it as my-app-manifest.yml and apply it to deploy the pod. Your application will begin to access PostgreSQL via Secretless Broker without ever knowing the database credentials.

 
kubectl create -f my-app-manifest.yml

Next steps

 
9.7