Authenticating Open Source DC/OS with Third Party Services

Richard Girges
3 min readDec 21, 2016

--

I’ve recently started using the open-source version of DC/OS to deploy Docker containers and I couldn’t be happier with the results.

However, the most mind-boggling part of the entire setup was getting my company’s third-party Jenkins cluster to authenticate with DC/OS in an automated fashion.

Open-source DC/OS utilizes OAuth to authenticate your GitHub, Gmail, or Microsoft account with your DC/OS cluster. There’s documentation provided that walks you through how to create API tokens. But there are two problems with this workflow:

  • The API token expires in five days
  • Generating a new API token requires re-logging into your DC/OS cluster, which requires opening a browser to complete the OAuth flow

There is no official way to authenticate your DC/OS cluster with a third party service (such as Jenkins) in an automated fashion. So here’s how I managed to do it.

WARNING: This is a temporary workaround until more robust authentication features are rolled out for open-source DC/OS.

I’m running on the following specs although these instructions can be tweaked to work on any platform.

  • CentOS 7.2
  • Open-Source DC/OS 1.8

Step 1: Retrieve your DC/OS Cluster’s Master Secret

  • SSH into one of your DC/OS master nodes
  • Grab the contents of the following file:
cat /var/lib/dcos/dcos-oauth/auth-token-secret

WARNING: KEEP THIS SECRET SAFE. It can provide full-blown access to your DC/OS cluster.

Step 2: Generate a JSON Web Token

We’re going to use our Cluster’s Master Secret to generate a JWT for use by our third-party service (in our case, Jenkins).

I’m using Python in this example to generate the JWT. However, you’re free to use any library of your choice.

Install some python-related libraries (CentOS-specific instructions):

sudo yum -y install python-devel python-pip libxslt-devel libffi-devel openssl-devel
sudo pip install --upgrade pip
sudo pip install PyJWT
sudo pip install cryptography

Create a Python script (i.e. generate_dcos_token.py):

import jwt
import time
from datetime import datetime
from datetime import timedelta
expTime = time.time() + (3600 * 876000)token = jwt.encode({'exp':expTime, 'uid': 'user@somewhere.com'}, '<CLUSTER_SECRET>', algorithm='HS256')
print token

IMPORTANT:

  • Replace <CLUSTER_SECRET> with your Cluster's Master Secret
  • Replace user@somewhere.com with your DCOS user's username (most likely an email address)
  • Change expTime to a UNIX timestamp reflecting the date you'd like your token to expire
  • I’m setting the token to expire in 100 years in this example [NOT RECOMMENDED]
  • A better workflow would probably be to setup your CI system to automatically generate a new token every few days

Run the python script and save the JWT token that the script prints out to your console:

python ./generate_dcos_token.py

Step 3: Confirm the JWT works

Run the following command to confirm the JWT token works

curl -X GET <DCOS_CLUSTER_URL>/acs/api/v1/users -H "Authorization: token=<JWT>"

IMPORTANT:

  • Replace <JWT> with your newly generated JWT token
  • Replace <DCOS_CLUSTER_URL with your DCOS Master Cluster’s endpoint

Step 4: Use the JWT in your CI

In our case, we’re using an external Jenkins cluster to execute Marathon deployments. To do this, we added the JWT to Jenkins as a Secret Text Credential for use with the Jenkins Marathon Plugin:

Finito!

You are now able to programmatically generate API tokens for open-source DC/OS, bypassing the need for manual intervention!

--

--