Developer Guide - docker/docker-credential-helpers

The docker-credential-helpers project (https://github.com/docker/docker-credential-helpers) provides a set of credential helpers for the Docker engine, enabling secure storage of authentication information. This guide focuses on the architecture of these helpers, specifically the credentials.Helper interface, building new helpers in Go, and creating a robust development workflow.

Design Philosophy

The docker-credential-helpers project follows a simple protocol for communication between the Docker engine and the credential helpers. The helpers are any program or script that follows this protocol, which is heavily inspired by Git. The helpers use the first argument in the command to identify the action.

Key Technologies and Dependencies

  • Go: The primary language used for building credential helpers.
  • golang.org/x/sys: A Go package for low-level interaction with the operating system.
  • github.com/danieljoos/wincred: A Go package for interacting with the Windows Credential Manager.
  • github.com/docker/docker-credential-helpers/client: A Go package for interacting with the Docker credential store.
  • github.com/docker/docker-credential-helpers: The main Go package for building credential helpers.
  • github.com/docker/docker-credential-osxkeychain: A Go package for interacting with the macOS Keychain.
  • github.com/docker/docker-credential-secretservice: A Go package for interacting with Secret Service API compatible stores.
  • github.com/docker/docker-credential-pass: A Go package for interacting with the pass password manager.
  • golangci/golangci-lint: A Go linter for static code analysis.
  • crazymax/osxcross: A tool for cross-compiling Go applications for macOS on other platforms.

credentials.Helper Interface

The credentials.Helper interface is the foundation for building credential helpers. It defines two methods: Get() and List().

  • Get(): Retrieves credentials for a specific registry.
  • List(): Lists all available credentials.

To build a new credential helper, create a new Go package that implements the credentials.Helper interface.

Example:

package mynewhelper

import (
"github.com/docker/docker-credential-helpers/credentials"
)

type MyNewHelper struct{}

func (h *MyNewHelper) Get(endpoint string) (map[string]string, error) {
// Implement the Get method for your helper
}

func (h *MyNewHelper) List() (map[string][]string, error) {
// Implement the List method for your helper
}

Building New Helpers in Go

To build a new credential helper in Go, follow these steps:

  1. Create a new directory for your helper.
  2. Initialize a new Go module with go mod init <module-name>.
  3. Implement the credentials.Helper interface in a new Go file.
  4. Add the github.com/docker/docker-credential-helpers package as a dependency.
  5. Implement the Get() and List() methods for your helper.
  6. Build your helper with go build.

Creating a Robust Development Workflow

To create a robust development workflow, consider the following steps:

  1. Use golangci/golangci-lint for static code analysis.
  2. Write tests for your helper.
  3. Use crazymax/osxcross for cross-compiling your helper for different platforms.
  4. Set up continuous integration (CI) to test your helper on multiple platforms.

Docker Configuration

The Docker engine uses the credsStore and credHelpers properties to specify the default credential store and preferential credential helpers for specific registries.

Example:

{
"credsStore": "osxkeychain",
"credHelpers": {
"myregistry.com": "mynewhelper"
}
}

Authentication with the Container Registry

To authenticate with a container registry, use the docker login command with the appropriate credentials.

Example:

docker login -u <username> -p <access_token> $CI_REGISTRY

Docker Desktop Release Notes

Docker Desktop now installs credential helpers from Github releases.

Sources: