Page MenuHomePhabricator

Establish secure way of passing registry credentials from Jenkins to Docker
Closed, ResolvedPublic

Description

From T175297: Define new Jenkins pipeline for container build phase:

Another issue that has arisen in testing this is that the default credential store for Docker is very insecure. By default, it stores all usernames/passwords given to docker login in the clear (in ~/.docker/config.json) until a subsequent docker logout is called. That means there is a substantial window of time where any other Jenkins job running via the same remote agent could gain access to the registry credentials.

Docker has functionality for alternative credential stores so that passwords aren't stored in the clear, but that solution wouldn't protect against this particular attack vector. Any job running via the same agent (same machine as jenkins-deploy) will have read access to the store and thus the registry credentials.

A few other possibilities in addition to using a sane credential store:

  1. Somehow pass the docker config (containing creds) to docker push via stdin. This seems maaaybe possible via --config /dev/stdin but would be hacky as hell.
  2. Ensure all jobs or at least all other jobs that run on contint1001 (where we're going to eventually run the pipeline job) are isolated inside containers.
  3. Run a separate Jenkins agent as a different user on contint1001 for only the pipeline job.

Option #2 seems like the most secure to me but others should definitely weigh in.

Event Timeline

dduvall triaged this task as Medium priority.Sep 27 2017, 6:18 PM
dduvall moved this task from Backlog to CI on the Release Pipeline board.
dduvall added a subscriber: mmodell.

@thcipriani and I discussed options this morning and settled on having a simple Puppet-provisioned sudo-able script that reads credentials from a root-owned read-only file and then performs the push. It seems like a much more secure way than trying to work around two precarious security models, Docker login which writes passwords to files in the clear and Jenkins credentials which may end up being exposed in the console or elsewhere.

There's a Python Docker lib that provides a simply interface that essentially does everything docker push can do but it talks directly to a registry API endpoint and will accept credentials as a dict argument. A small cli script that calls out to it should suffice.

Registries should be limited to docker.io (for testing) and docker-registry.wikimedia.org. Otherwise, credentials could be easily exposed by simply executing script my.logging.domain/repo/image.

Change 382608 had a related patch set uploaded (by Thcipriani; owner: Thcipriani):
[operations/puppet@production] WIP: docker pusher

https://gerrit.wikimedia.org/r/382608

Change 382608 merged by Alexandros Kosiaris:
[operations/puppet@production] Deployment pipeline profile

https://gerrit.wikimedia.org/r/382608

thcipriani assigned this task to dduvall.