Sensitive Data Management in Modern Installations using CasC

2 minute readKnowledge base

Issue

CasC bundles are typically stored in SCM repositories, which could lead to exposing sensitive data to the wrong people if credentials (and secrets in general) were not correctly protected.

Resolution

There are 3 ways to securely pass data in CasC using Credentials Plugin:

  • Importing data from external credential providers

  • Passing secrets through variables

  • Passing secrets through encrypted strings

In general, in CasC implementations, credentials can be configured as follows:

credentials: system: domainCredentials: - credentials: - usernamePassword: scope: SYSTEM id: <your-credential-id> username: <your-username> password: <your-password>

For obvious security reasons it is not recommended that the credential password (sometimes also usernames) are input as plain text. How these secrets are passed to the CasC credentials block is what we discuss in this article.

Find more examples of its usage here.

Importing credentials from external providers

Credentials Plugin offers an API that can be used to retrieve credentials from external sources. Kindly note that you might need to create an additional role to grant the instance pod with access to the requested secrets information. Some popular credential provider plugins are:

Please refer to our support policies to get more acquainted with the support level that we can provide for each of the plugins above depending on their tier.

When an external Credentials provider is configured in Jenkins through CasC, there is no need to define credentials inside. Jenkins will be able to take the credentials from external storage by ID as in the following example:

- kubernetes: connectTimeout: 5 containerCapStr: "10" credentialsId: "k8s-user-password" jenkinsUrl: "http://localhost:8080"

Passing secrets through variables

Managing sensitive data was one of the first requested features for CasC. CasC supports string substitution in bash-style syntax: ${PARAMETER:-defaultvalue} so one can write and share YAML configuration samples, without any risk of exposing sensitive information. This can also be used to customize configurations without the need to edit a YAML document.

There are several ways to obtain the target variable value:

Passing secrets through encrypted strings

Secrets can be passed as encoded strings wrapped by {}. This feature uses the hudson.util.Secret engine to define encrypted credentials in CasC. Encryption makes use of the Jenkins-internal secret key, which is unique for every Jenkins instance. Thus, these credentials are not portable between instances.

To get the encryption of a secret, run from your controller Groovy console:

hudson.util.Secret.fromString("your-secret").getEncryptedValue()

To achieve the opposite, run:

hudson.util.Secret.fromString("{AAAAAAA=}").getPlainText()

Tested product/plugin versions

CloudBees CI Managed Controller: 2.361.1.2 CloudBees CasC Client Plugin: 1.67 CloudBees CasC Items API Plugin: 1.29 Credentials Plugin: 1129.vef26f5df883c Credentials Binding Plugin: 523.vd859a_4b_122e6