CI/CD In Confidence: How Pipelines Keeps Your Secrets

A friend that can’t keep a secret isn’t one you’ll rely on. The same is true for your mission critical CI/CD tool that you have to entrust with credentials for each integrated component.

Keeping your secrets safe can be a challenge for CI/CD tools, since they need to connect to such a variety of other services. Each one needs its own password or token that must be kept hidden from prying eyes. Revealing this sensitive data in the plaintext files that define your workflows is a huge security risk.

JFrog Pipelines was designed for secrecy from the start. Unlike many CI solutions that provide plugins or add-ons that need to be specially installed and maintained, secrets management is built into the way that Pipelines works.

Here’s how Pipelines integrations combine central secrets management with fine-grained access permissions of JFrog Platform to provide convenience, security, and administrator control.

Pipelines Integrations

Pipelines comes with the right variety of out-of-the-box integrations for the tools you’re likely to use most, so connecting to services is a snap. Adding an integration is often just giving it a friendly name, providing an API endpoint, and entering user credentials. Integrations ready to connect include GitHub, Bitbucket, Docker, Kubernetes, and Slack, as well as cloud services like AWS, GCP, and Azure.

Central Secret Storage

Pipelines stores the secrets you provide to all your integrations in a central storage vault, encrypted to keep them safe from any digital intruder.

For example, if Jasmine’s developer team uses a private Docker registry for container images, a Docker Registry integration is provided the username and password.

When Jasmine’s Pipelines DSL references this Docker Registry integration, it reveals only that integration’s friendly name (Jasmine_Docker) in the plaintext file. The Pipelines integration does the work to connect, and the secrets stay securely hidden from view.

integrations:
	- name: Jasmine_Docker			# Our private docker registry

In this way, all a developer needs to know is the integration’s friendly name to access the service. They never have to directly use the secrets that authorize connecting to the service. When a separate administrator configures integrations, developers on a team don’t need to manage or even know the secrets for the integrations they’re permitted to use, so those services can be safely shared without sharing secrets.

Administrator Control

For control, only a JFrog Platform administrator user can add, edit, or delete integrations. And Pipelines follows best security practice by obscuring vital secrets such as passwords or tokens in the UI with disc symbol text.

In a large, multi-team organization you probably don’t want every user to be able to access every service. When an admin adds or edits an integration, they can restrict access to only certain pipeline sources. In this way, operations can limit a service to use only by some pipelines and, by extension, to the users and groups that have permission to use those pipelines. 

So while it’s easy for a developer to use and share integrations, each can only connect to the services they’re permitted to see.

For example, Sanjay isn’t on Jasmine’s team, so he shouldn’t be able to push images to her private Docker registry. Here’s how Kim, the administrator, might restrict use of that integration to Jasmine’s team:

  1. Kim adds Jasmine’s project repository, e.g. jasmine/pipelinest as a pipeline source
  2. In the Docker Registry integration Jasmine_Docker, Kim assigns only the pipeline source jasmine/pipelines.
  3. In Administration | Permissions, Kim adds the pipeline source jasmine/pipelines to the permissions target for Jasmine’s team.

Developer Availability

Although Pipelines holds the integration’s secrets centrally, the Pipelines DSL can still access its particulars. When an integration is specified in a step’s integrations block it can be used in that step’s shell scripts. 

For example, if a pipeline needs to send a notification email when a build completes, it can use the built-in utility function and reference the SMTP integration that an administrator has added and named “TeamJasmine”:

integrations:
	- name: TeamJasmine			# SMTP integration
execution:
onSuccess:
- send_notification TeamJasmine --body "built docker image docker-local/demo:$pipeline_name.$run_number"

Similarly, if a shell script needs the values held by an integration, it can do so through environment variables. For example, to issue a Secure Shell (SSH) command using the private key in a SSHKeys integration:

integrations:
	- name: mySSHKeys				# SSH Keys integration
execution:
onExecute:
- echo "$int_mySSHKeys_privateKey" > key.txt
- chmod 400 key.txt
- ssh -i key.txt user@host 'do some work'

Neither of these examples ever expose keys or passwords in the plaintext Pipelines DSL file, so it’s safe to store it in an online source code repository. None of this critical information ever leaves the secure confines of your Pipelines environment.

Tops in Top Secret

Pipelines integrations enable you to share secure resources, while keeping the secrets that authorize their use extra safe. Using the JFrog Platform’s unified permissions model, you can grant access to those who need it and block access to everyone else.

That’s just one, but very important detail of Pipelines’ design for cloud native, enterprise-scale CI/CD. It’s a reflection of our comprehensive approach to building a system for one-stop DevOps.

Give it a try for yourself, and see how Pipelines can help speed your releases safely.