Registry authentication
This guide shows how to set up registry credentials for Contrast.
Applicability
This guide is relevant if you need to authenticate with a container registry for pulling images.
Prerequisites
How-to
Contrast CLI
The Contrast CLI, specifically the contrast generate subcommand, needs access to the registry to derive policies for the referenced container images.
The CLI authenticates to the registry using the docker_credential crate.
This crate searches some default locations for a registry authentication file, so it should find credentials created by docker login or podman login.
The only authentication method that's currently supported is Basic HTTP authentication with user name and password (or personal access token).
Identity token flows, such as the default mechanism of plain docker login, don't work.
Basic authentication can be forced with docker login -u $REGISTRYUSER.
You can override the credentials file used by Contrast by setting the environment variable DOCKER_CONFIG. This is useful for creating a credential file from scratch, as shown in the following script:
#!/bin/sh
registry="<put registry here>"
user="<put user id here>"
password="<put client secret here>"
export DOCKER_CONFIG=$(mktemp)
cat >"${DOCKER_CONFIG}" <<EOF
{
"auths": {
"$registry": {
"auth": "$(printf "%s:%s" "$user" "$password" | base64 -w0)"
}
}
}
EOF
contrast generate "$@"
Confidential guest VMs
For the Contrast image puller to be able to pull images from a private registry, it must be configured with the required authentication details.
Contrast uses its own TOML-based configuration format for this purpose.
This configuration must be provided as a secret to the node installer DaemonSet.
The node installer then handles installing the secret in the runtime directory on the host, from where the runtime then forwards it to the confidential pod VM, allowing the image puller to read it.
Kubernetes secrets are accessible to anyone with API access to the node, as well as anyone with access to etcd (source).
Anyone with these permissions is additionally able to change the configuration's content, with no way for Contrast to verify the integrity of the configuration eventually received by the image puller.
This allows an attacker to redirect image pull requests and configure an attacker-controlled registry to appear as legitimate. The attacker could then, for example, log which images are being pulled.
This does not allow an attacker to serve malicious images or alter the contents of valid images, since contrary to the image puller's configuration, pulled images are integrity-protected through their mandatory pinned digest.
Creating an image puller configuration
Various configuration options are available, both globally and per-registry. The following table shows the available global configuration options.
| Option | Description |
|---|---|
extra-env.HTTP_PROXY | proxy to use for plain HTTP requests |
extra-env.HTTPS_PROXY | proxy to use for HTTPS requests |
extra-env.NO_PROXY | registry domains for which the proxy should be bypassed |
Additionally, for each individual registry name, the following options are available under registries."name.":
| Option | Description |
|---|---|
ca-certs | a newline-concatenated list of PEM-encoded certificates |
insecure-skip-verify | disable transport security |
username | username, used together with password to authenticate with the registry |
password | password, used together with username to authenticate with the registry |
auth | an auth token authenticating the user with the registry |
identitytoken | used to authenticate the user and get an access token for the registry |
registrytoken | a bearer token to be sent to the registry |
Which of the authentication-related options (username and password, auth, identitytoken and registrytoken) are required depends on the configuration of your registry.
The ability to specify CA certificates mainly serves two purposes, namely allowing connections to registries that aren't publicly trusted in the web PKI,
and to restrict who can ostensibly intercept and log traffic for metadata analysis.
A number of example configurations for various use-case scenarios are shown below.
Example 1
In this scenario, there's an internal registry at registry.corp for workload images, but ghcr.io is used for Contrast images.
The internal registry is served from within the corporate firewall, while access to external registries is mediated by a proxy.
Other registries are allowed, as long as they don't require authentication.
[extra-env]
HTTP_PROXY = "https://proxy.corp"
HTTPS_PROXY = "https://proxy.corp"
NO_PROXY = ".corp"
[registries."registry.corp."]
ca-certs = '''
-----BEGIN CERTIFICATE-----
MIIBezCCASGgAwIBAgIUUugBbePTzyVApU4DLSMmHnXXjcwwCgYIKoZIzj0EAwIw
EzERMA8GA1UEAwwIWW91ck5hbWUwHhcNMjUxMDIxMTUwNDI0WhcNMjYxMDIxMTUw
NDI0WjATMREwDwYDVQQDDAhZb3VyTmFtZTBZMBMGByqGSM49AgEGCCqGSM49AwEH
A0IABIgsA5IEeiBq6jDpH2ttxrI96beeOqa+EpGqmznQmzpFkPEpLWMUt21Ien71
rxdeFC7ySuuu95VPjSvO7EUM9qyjUzBRMB0GA1UdDgQWBBTVnuI2o36Mrja3RvwE
82lWg2m19zAfBgNVHSMEGDAWgBTVnuI2o36Mrja3RvwE82lWg2m19zAPBgNVHRMB
Af8EBTADAQH/MAoGCCqGSM49BAMCA0gAMEUCIGmEkl8jxjxqyAxs3QoAXeIx++Bz
Zm9dwbeTbrKysrGXAiEA8ce6iyJUCZCZVVJs/HDLcPbOKc2EPZvdcGGjIlGXulo=
-----END CERTIFICATE-----
'''
[registries."ghcr.io."]
auth = "YnVyZ2VyZGV2OnRoaXNpc25vdG15cGFzc3dvcmQ="
Example 2
In this scenario, all container images are served from a public registry. However, the image owner wants to make sure that the traffic can't be intercepted by rogue CAs. Other registries are strictly forbidden.
[registries."very-secure.registri.es."]
auth = "bmljZTp0cnk="
ca-certs = '''
Root CA 1
-----BEGIN CERTIFICATE-----
MIIBfDCCASGgAwIBAgIUU5G42y9bIh8+AU38qVOmKocc0CwwCgYIKoZIzj0EAwIw
EzERMA8GA1UEAwwIWW91ck5hbWUwHhcNMjUxMDIxMTUyNzEwWhcNMjYxMDIxMTUy
NzEwWjATMREwDwYDVQQDDAhZb3VyTmFtZTBZMBMGByqGSM49AgEGCCqGSM49AwEH
A0IABOJlyBb/sHBmHRncTqk4lm6hBkBYlZGcScXfl/IuAVVIo4zCGBzCmvc7jYc2
+gyVp+wxuvm7NRza4e1QOfJfrxOjUzBRMB0GA1UdDgQWBBTRE8qju+GIWzr5xCik
MdBJFOd1lzAfBgNVHSMEGDAWgBTRE8qju+GIWzr5xCikMdBJFOd1lzAPBgNVHRMB
Af8EBTADAQH/MAoGCCqGSM49BAMCA0kAMEYCIQCn+fVmAzB8HOakKGLx6oXF0WP0
GJibphhjfHPdNWEDdQIhAN3KFNWIYtE35+/rZb5I+oVKnqKS8igdIU9lXmpOps1j
-----END CERTIFICATE-----
Root CA 2
-----BEGIN CERTIFICATE-----
MIIBezCCASGgAwIBAgIUUugBbePTzyVApU4DLSMmHnXXjcwwCgYIKoZIzj0EAwIw
EzERMA8GA1UEAwwIWW91ck5hbWUwHhcNMjUxMDIxMTUwNDI0WhcNMjYxMDIxMTUw
NDI0WjATMREwDwYDVQQDDAhZb3VyTmFtZTBZMBMGByqGSM49AgEGCCqGSM49AwEH
A0IABIgsA5IEeiBq6jDpH2ttxrI96beeOqa+EpGqmznQmzpFkPEpLWMUt21Ien71
rxdeFC7ySuuu95VPjSvO7EUM9qyjUzBRMB0GA1UdDgQWBBTVnuI2o36Mrja3RvwE
82lWg2m19zAfBgNVHSMEGDAWgBTVnuI2o36Mrja3RvwE82lWg2m19zAPBgNVHRMB
Af8EBTADAQH/MAoGCCqGSM49BAMCA0gAMEUCIGmEkl8jxjxqyAxs3QoAXeIx++Bz
Zm9dwbeTbrKysrGXAiEA8ce6iyJUCZCZVVJs/HDLcPbOKc2EPZvdcGGjIlGXulo=
-----END CERTIFICATE-----
'''
[registries."."]
ca-certs = "no PEM here means no CA certificates"
Example 3
In this scenario, there's an HTTP-only registry deployed into the cluster for ease of use. Transport security for this internal registry isn't important to the operators. Other registries should be used anonymously, but with TLS.
[registries."registry.default.svc.cluster.local."]
insecure-skip-verify = true
Example 4
This scenario is equivalent to the prior behavior: web PKI and no authentication.
Registry matching and subdomains
Registry domains are specified as fully qualified domain names.
Note the trailing dot in the examples above.
For a registry-specific configuration to be applied to a pull request, the image's registry must end exactly in the configuration's name.
A configuration above for registries.".registry.corp." will be applied to any and all registries available on subdomains of registry.corp, but not to registry.corp itself.
Pulling the image example.registry.corp/example/image@sha256:... will use the configuration given under registries.".registry.corp.", but registry.corp/example/image@sha256:... won't.
Additionally, example.registry.corp must be able to prove its identity by successfully completing a TLS handshake using one of the explicitly configured certificates.
If no certificates are configured, the hosts default web PKI certificates are used.
Multiple matches and global configuration
If multiple matching registry configurations exist, for example if both registries.".registry.corp." and registries.".corp." have configuration values set, then the most specific match will be chosen.
In the example, this would be registries.".registry.corp.".
To specify a catch-all configuration, use the key registries.".".
The option registries.".".ca-certs can be used to disable authentication with all unknown registries:
[registries."."]
ca-certs = '''
This option set, but no certificates provided, means no TLS handshake will succeed.
'''
IP addresses and ports
Currently, IP- and port-based configuration isn't supported. Please use Kubernetes' built-in tools to assign unique domain names to IP addresses, and use these for image references instead.