Overview

When using Jenkins as a CI and CD tool, we often need to use some confidential information, such as GitHub credentials or SSH keys for machines. We typically do not want everyone to see this information, so we look into various Jenkins concepts to see if there is something that meets our needs.

As a result, we find Jenkins Credentials and think it meets our requirements, so we store our confidential information in Credentials. However, after some time, you will realize that the reality is not so simple.

Credentials Are Stored Locally

Although Credentials are encrypted, Jenkins needs to store them somewhere. Whether stored in a database or a file, there is always a place for these data. In fact, Jenkins stores this information in the directory $JENKINS_HOME/secrets/, for example:

  1. [root@liqiang.io]# sudo ls -al /var/lib/jenkins/secrets
  2. total 40
  3. drwx------ 2 jenkins jenkins 4096 Jun 4 11:35 .
  4. drwxr-xr-x 16 jenkins jenkins 4096 Jun 13 11:32 ..
  5. -rw-r--r-- 1 jenkins jenkins 48 May 29 08:15 hudson.console.ConsoleNote.MAC
  6. -rw-r--r-- 1 jenkins jenkins 32 May 29 08:21 hudson.model.Job.serverCookie
  7. -rw-r--r-- 1 jenkins jenkins 272 May 29 08:07 hudson.util.Secret
  8. -rw-r--r-- 1 jenkins jenkins 32 May 29 07:50 jenkins.model.Jenkins.crumbSalt
  9. -rw-r--r-- 1 jenkins jenkins 256 May 29 07:50 master.key
  10. -rw-r--r-- 1 jenkins jenkins 272 May 29 08:01 org.jenkinsci.main.modules.instance_identity.InstanceIdentity.KEY
  11. -rw-r--r-- 1 jenkins jenkins 272 May 29 08:26 org.jenkinsci.plugins.workflow.log.ConsoleAnnotators.consoleAnnotator
  12. -rw-r--r-- 1 jenkins jenkins 48 Jun 4 11:35 org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices.mac

This information can be copied. If someone can access my Credentials files, they will be able to fully access my entire Jenkins instance and everything it can access.

Credentials Can Be Printed

In addition to the risk of local file leakage, in practice, when using these Credentials, the information is transmitted in plaintext (otherwise, how would our applications use it?). It is passed to applications as environment variables. For example, my Jenkins Pipeline has the following parameters:

Figure: This is a description of the picture

Then in my Jenkins job configuration, I can directly read this environment variable:

  1. [root@liqiang.io]# cat Jenkinsfile
  2. ... ...
  3. stage('create vke cluster(terragrunt apply)') {
  4. steps {
  5. dir("/home/jenkins/${ENV}/${CLUSTER_NAME}") {
  6. sh 'TEST_ACCESS_KEY=${ACCESS_KEY} TEST_SECRET_KEY=${SECRET_KEY} terragrunt apply -auto-approve'
  7. ... ...

If this was not a legitimate Jenkins job but a malicious script, I could print the encrypted information like this:

  1. [root@liqiang.io]# cat Jenkinsfile
  2. ... ...
  3. stage('create vke cluster(terragrunt apply)') {
  4. steps {
  5. dir("/home/jenkins/${ENV}/${CLUSTER_NAME}") {
  6. sh 'echo "ACCESS_KEY = ${ACCESS_KEY}"'
  7. sh 'echo "SECRET_KEY = ${SECRET_KEY}"'
  8. ... ...

So, it is clear that Credentials are not entirely secure.

Truly Secure Practices

Since Credentials are not completely secure, are there truly secure practices? In my opinion, this is similar to the issues faced with Kubernetes Secrets. We can use additional measures to ensure the security of transmission (to avoid the first issue and part of the second issue). For malicious applications, we can ensure that only legitimate applications can access the encrypted data through application identity verification.

However, these are just personal thoughts and have not been practically tested. If you encounter similar needs and have different opinions, feel free to leave a comment for discussion.

References