DEV Community

Cover image for Jenkins Security: Storing Secrets
Lionel♾️☁️
Lionel♾️☁️

Posted on

Jenkins Security: Storing Secrets

Jenkins is by far one of my favorite open source tools. Jenkins is an open source automation that that helps and provides support for building and deploying apps. Jenkins Plugins are what enable it to be customized and extended.

You are new to Jenkins? Quickly try it out by running its docker image, with the command

docker run -p 8080:8080 jenkins/jenkins

CI/CD

Automation is fundamental to Continuous Integration and Countinuous Delivery. Jenkins build can be setup for Continuous Integration tasks such as running integration testing. And Continuous Delivery activities such as building a final jar and pushing it to a repository or building a Docker image and pushing it to a registry. However all such integrations require credentials for authorization. Applications tend have a lot of other secrets such as Certificates for authentication for MASSL, credentials for upstream systems, databases and API tokens.

We cannot talk of Continuous Integration and Continuous Delivery (CI/CD) and not talk about automation. Jenkins is a CI tool and its builds can be configured to run Continuous Integration tasks such software integration testing. Not only that but Continuous Delivery actions such as creating a final jar (java app artifact) and pushing it to a repository or even creating a Docker image and pushing it to a registry are examples of Continuous Delivery activities. All of these integrations however need credentials to be able to work. Certificates for authentication for MASSL credentials for upstream systems, databases, and API tokens are common secrets in applications.

Jenkins Plugins for Secret Management

Below are some plugins that allow basic credential management:

N.B. These plugins are available in default installation of Jenkins.

Below are secrets which are supported by default:

test

Using secrets in Freestyle Job

For our test, let’s create a Free style Jenkins Project and use Credentials plugins to store our Dockerhub credentials. As seen below, select Username and password (separated) and enter bindings for the credentials. Basically, these are the environment variables that username and password will be available as:

test

Once that is done, next click on Add and select the right scope and enter Dockerhub credentials:

test

Now here is an example of how we use our credentials

secrets

Using Credentials in Jenkins Pipeline

Now let us look how we can use our credentials in Jenkins Pipeline. In the following stage of our Jenkinsfile we are will be using artifactory-credentials to login to the artifactory and push our docker images to it. Also note that usernameVariable and passwordVariable are available in the withCredentials block:



    stage("docker_push") {
      withCredentials([usernamePassword(credentialsId: 'artifactory-credentials', 
        passwordVariable: 'ARTIFACTORY_KEY', 
        usernameVariable: 'ARTIFACTORY_USER')]) 
      {
        sh "echo $ARTIFACTORY_KEY | docker login -u $ARTIFACTORY_USER --password-stdin ${REGISTRY_URL}"
        sh "docker tag myapp:latest ${REGISTRY_URL}/myapp:${shortCommit}"
        sh "docker push ${REGISTRY_URL}/myapp:${shortCommit}"
      } 


Enter fullscreen mode Exit fullscreen mode

Retrieving Secrets

Jenkins tries to provide some sense of security by masking the credentials in logs. It does that by looking for an exact match and replaces them with asterisks (*****). But note also that this control can simply be bypassed by a user with edit permission by encoding the credentials in the pipeline and printing them in logs.

test

test

Please note that the first echo results in our password being masked since it matches our password string.

Now let us decode the encoded password and see what it gives us:



dev@ubu:~ $ echo YWRtaW4xMjM0Cg== | base64 -d
admin1234


Enter fullscreen mode Exit fullscreen mode

Let us explain this. Actually, Jenkins credentials are stored in Jenkins master encrypted by Jenkins instance id. This file usually exists in your linux server at /var/lib/jenkins/credentials.xml. It is therefore very easy to decrypt credentials saved in Jenkins for Jenkins administrators. Moreover, do note that any user that can SSH to Jenkins can read the encrypted credentials file since it has read permissions for everyone. Let us look at that:



dev@ubu:/var/lib/jenkins$ ls -la credentials.xml 
-rw-r--r-- 1 jenkins jenkins 4650 Mar 26 09:28 credentials.xml


Enter fullscreen mode Exit fullscreen mode

This file has passwords encrypted with Jenkins Id:



<com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl>
    <scope>GLOBAL</scope>
    <id>artifactory-credentials</id>
    <description></description>
    <username>admin</username>
    <password>{AQAAABAAAAAQom3LN7ei0wdm9cdOlGOa4GxDHzpndn0BUPeI4biARto=}</password>
</com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl>


Enter fullscreen mode Exit fullscreen mode

Our favorite CI-tool, Jenkins provides a handy utility at /script of the URL that can be used to decrypt passwords with the following script:



encryptedPassword = '{AQAAABAAAAAQom3LN7ei0wdm9cdOlGOa4GxDHzpndn0BUPeI4biARto=}'
passwd = hudson.util.Secret.decrypt(encryptedPassword)
println(passwd)


Enter fullscreen mode Exit fullscreen mode

test

In Conclusion, it is very clear that secrets entered in Jenkins will not be disclosed. Any user that can use a secret in a build can decode and see it. All and any user that can SSH into Jenkins master server can decrypt all secrets using /script utility if they can login to Jenkins Web UI.

Management Issues with Hardcoding Credentials

As we just saw, the principle of least privilege cannot be effectively employed when just using Jenkins Credentials Plugin. Therefore, there has to be a better solution for auditable credential sharing within team, credential rotation and automatic build provisioning that we can use. For that, I would suggest a number of credential management products such as Hashicorp Vault, Cyberark Vault and AWS Secrets Manager. Some open source products like CredStash for AWS help with credential management.

Top comments (0)