Pages

Wednesday, March 6, 2019

Jenkins - Injecting Secrets into Build Jobs

Jenkins commonly store user credentials , api keys, access tokens , username and passwords to talk with other systems and services. These need to be stored carefully. The credentials as simple strings are serialized to the disk as plain text and can lead to number of problems.

The best way is to store the credentials as secrets. This way the key to decrypt secrets in stored in the secrets/ directory in jenkins which has high protection. But how can we access these secrets into our build jobs. In this article we will see how we can access secrets in jenkins jobs.

Jenkins provides multiple plugins to allow secrets to be accessed by the build jobs. The following 3 plugins need to be installed.

Credentials - Provides a centralized way to define credentials that can be used by jenkins instance, plugins and build jobs

Credentials Binding - This plugin allows to configure build jobs to inject credentials as environment variables

Plain Credentials - This plugin is necessary for the credentials binding plugin to work. A dependency

These plugins are installed by default. After installing the credentials plugin, the jenkins sidebar will have the new credentials link that can be used to define credentials and secrets.

Click the Credentials link -> Global Credentials -> Add Credentials ->
Select a credential kind that can be used from the jobs. The common type of the credentials are 
Username and password
Secret file
Secret text

Username and Password - Lets create a secret with a username and password and see how we can access them in the build job. Click on the credentials link and create a user and password as below,
Accessing these user name and password in the build job is quite easy with the use of credentials binding plugin. Once the plugin is installed, in the job -> Build Environment, we can see a check box with “use secrets text(s) or file(s)” . Once we click that, we get a add button. Click on the add button to choose a binding. We chose the user name and password (separated) binding as we want the user name and password to be available to the job.

We need to provide 2 variables to bind. In this case i defined 2 variable USERNAME and PASSWORD and choosed the credential that i created earlier. Now the username and password that i defined in the credential will be binded to the above variables so that we can access them. Now if i say “echo $USERNAME” it will display the user name that i defined in the credential. In the Post Build actions, i can take a “execute shell” and inside the shell i can give the 

echo $USERNAME
Echo $PASSWORD

These will print the user name and password that i have defined in the credentials.

Secret Text - Similar to the user name and password we can also create a secret text credential much for tokens etc. Create your secret text as below,
And Bind that as below,

In the execute shell enter,
echo $USERNAME

This will print the secret text that i entered in the credentials.

Secret file - The case of secret file is different. We need to define a file on the disk and add contents to that. Then we will upload the file and make that available to the job. In this case the contents of the file are not available or not binding automatically as in above cases. The secret file will be uploaded and will be available to refer with a name that we define in ID.

In the above case, the file can be referenced with the id “secretfile-id”. Now once the binding is done as below,
Now i can refer the secret file that i uploaded earlier with name secretfile-id. Now a new variable SECRETFILE is created and binded to the id secretfile-id. Now i can refer the file using the env variable SECRETFILE.

In the execute shell, we can add the code as,
MY_FILE_DATA=`cat $SECRETFILE`
echo "The secret file data is: $MY_FILE_DATA"

This was we can access the file as well as contents of the file. We can then write our parsing of the contents from the file.

This is how we can pass secrets to the Jobs in Jenkins. Hope this helps.

Note - One thing while defining any of these is to define they with global scope so that they can be accessible from any of the build jobs. Also we need to define them with the ID so that this ID can be referenced from the jobs.

No comments :

Post a Comment