jenkins-x, kubernetes

Setting secrets for Dex in Jenkins-X and Kubernetes

Setting secrets for Dex in Jenkins-X and Kubernetes

Dex is a nice little application that you can add to your Kubernetes cluster (easier when combined with Jenkins-X and Helm) that allows your user to authenticate via various OAuth providers. We are only interested in using Github as OAuth provider so this post will be focused on Github.

Helm Chart

We use this chart for our installation which is an official chart for Dex.

https://artifacthub.io/packages/helm/dex/dex

Our initial setup is very simple and here is an example chart values.

config:
  issuer: https://example.com/dex
  storage:
    type: kubernetes
    config:
      inCluster: true
  staticClients:
    - id: web-app
      name: Web App
      redirectURIs:
        - https://example.com/auth/callback
      secret: $DEX_CLIENT_SECRET
  connectors:
    - type: github
      id: github
      name: Github
      config:
        clientID: <client-id-here>
        clientSecret: $GITHUB_CLIENT_SECRET
        redirectURI: https://example.com/dex/callback
      scopes:
        - openid
        - email
        - profile
        - groups
        - federated:id
  enablePasswordDB: false
  oauth2:
    skipApprovalScreen: true
    alwaysShowLoginScreen: false
envFrom:
  - secretRef:
      name: dex-secrets

And our initial secret provides the following keys mapped to environment variables:

  • GITHUB_CLIENT_SECRET
  • DEX_CLIENT_SECRET

Dex Configuration

Based on our initial test, the secrets are populated properly into the environment variable. However, when we tried to use the secrets, turns out, the $DEX_CLIENT_SECRET value was passed as string literal. We don’t know whether this is the same with $GITHUB_CLIENT_SECRET. We cannot store the secret as plain text as it is unacceptable.

Based on Dex helm chart documentation, we can pass a secret by the key configSecret.name which should contain a key called config.yaml and that the value should be the dex config you wanted to pass. This means we will pass the whole content of a YAML file into this secret which includes new lines. Jenkins-X jx secret edit doesn’t like new lines but we have a solution for that.

Populate the whole config into secret

First, we need to change the dex helm chart values into something like this:

configSecret:
  name: dex-secrets

Then add a new key in our existing secret called config.yaml

apiVersion: v1
data:
  GITHUB_CLIENT_SECRET: ""
  DEX_CLIENT_SECRET: ""
  config.yaml: ""
kind: Secret
metadata:
  name: dex-secrets
type: Opaque

We don’t bother removing the old keys as we are also referencing them from our other applications.

Here is our full config file (secrets redacted of course).

issuer: https://example.com/dex
storage:
  type: kubernetes
  config:
    inCluster: true
staticClients:
  - id: web-app
    name: Web App
    redirectURIs:
      - https://example.com/auth/callback
    secret: <web-app-client-secret-here>
connectors:
  - type: github
    id: github
    name: Github
    config:
      clientID: <client-id-here>
      clientSecret: <client-secret-here>
      redirectURI: https://example.com/dex/callback
    scopes:
      - openid
      - email
      - profile
      - groups
      - federated:id
enablePasswordDB: false
oauth2:
  skipApprovalScreen: true
  alwaysShowLoginScreen: false

We can’t just copy and paste it into jx secret edit as new lines will break it. We need to convert this whole config into a single line using a very simple nodejs script. What it does is convert new lines into string literal \n and dumps the text into output.

// File: multi-line-to-single-line.js
const data = `this
is
multi
line`;
const lines = data.split("\n");
const line = lines.join('\\n');
console.log(line);

Paste in the full config into data constant then run this in your terminal (assuming a Linux-like environment).

node multi-line-to-single-line.js > single-line-config.txt

With this, we can get the single line config. Using jx secret edit, run the following:

jx secret edit -f secret-name

Then paste the single line text into the config.yaml key. Wait for Jenkins-X/Kubernetes propagate the changes into your pod for it to take effect.

That’s it!

You have just avoided storing your secret in your codebase!

Featured image by Pixabay.

Leave a reply

Your email address will not be published. Required fields are marked *