Skip to content

Latest commit

 

History

History
265 lines (212 loc) · 10 KB

authentication.md

File metadata and controls

265 lines (212 loc) · 10 KB

Authenticating to container image registries

To resolve digests for private images, digester requires credentials to authenticate to container image registries.

Authentication modes

Digester supports two modes of authentication: offline and online.

Offline authentication

When using offline authentication, digester uses credentials available on the node or machine where it runs. This includes the following credentials:

  1. Google service account credentials available via Application Default Credentials for authenticating to Container Registry and Artifact Registry.

    For implementation details, see the github.com/google/go-containerregistry/pkg/v1/google and golang.org/x/oauth2/google Go packages.

  2. Credentials and credential helpers specified in the Docker config file, for authenticating to any container image registry. The file name is config.json, and the default file location is the directory $HOME/.docker. You can override the default location of the config file using the DOCKER_CONFIG environment variable.

    For implementation details, see the github.com/google/go-containerregistry/pkg/authn and github.com/docker/cli/cli/config Go packages.

  3. Ambient credentials for GitHub Container Registry (ghcr.io), Amazon Elastic Container Registry, and Azure Container Registry.

Online authentication

When using online authentication, digester authenticates using the following credentials:

  1. The imagePullSecrets listed in the pod specification and the service account used by the pod. Digester retrieves these secrets from the Kubernetes cluster API server.

    For implementation details, see the github.com/google/go-containerregistry/pkg/authn/kubernetes Go package.

  2. Credentials specified in the Docker config file, for authenticating to any container image registry. The file name is config.json, and the location can be the container working directory ($PWD/config.json), or a directory called .docker under the user home directory ($HOME/.docker/config.json) or the file system root directory (/.docker/config.json).

    For implementation details, see the github.com/google/go-containerregistry/pkg/authn and github.com/docker/cli/cli/config Go packages.

  3. Cloud provider-specific instances of the Keychain interface. For instance, the implementation for Google uses Google service account credentials from the file referenced by the GOOGLE_APPLICATION_CREDENTIALS environment variable, or retrieves credentials from the node or Workload Identity metadata server.

    For implementation details, see the github.com/google/go-containerregistry/pkg/authn/k8schain Go package.

The client-side KRM function defaults to offline authentication, whereas the webhook defaults to online authentication. You can override the default authentication mode using the --offline command-line flag or the OFFLINE environment variable.

KRM function offline authentication

The KRM function uses offline authentication by default. By running digester as a local binary using the kpt --exec flag, or the kustomize --exec-path flag, the KRM function has access to container image registry credentials in the current environment, such as the current user's Docker config file and credential helpers.

Run digester as a local binary using the kpt --exec flag:

kpt fn eval [manifest directory] --exec [path/to/digester]

If your Docker config file contains your container image registry credentials and you do not need a credential helper, you can run digester in a container. Mount your Docker config file in the container using the --mount flag:

VERSION=v0.1.15
kpt fn eval [manifest directory] \
    --as-current-user \
    --env DOCKER_CONFIG=/.docker \
    --image ghcr.io/google/k8s-digester:$VERSION \
    --mount type=bind,src="$HOME/.docker/config.json",dst=/.docker/config.json \
    --network

The --network flag provides external network access to digester running in the container. Digester requires this to connect to the container image registry.

KRM function online authentication

To use online authentication with the digester KRM function, set the OFFLINE=false environment variable. Use this command to run the digester KRM function as a local binary::

OFFLINE=false kpt fn eval [manifest directory] --exec ./digester

If you want to run the KRM function in a container, mount your kubeconfig file:

VERSION=v0.1.15
kpt fn eval [manifest directory] \
    --as-current-user \
    --env KUBECONFIG=/.kube/config \
    --env OFFLINE=false \
    --image ghcr.io/google/k8s-digester:$VERSION \
    --mount type=bind,src="$HOME/.kube/config",dst=/.kube/config \
    --network

When using online authentication, digester connects to the Kubernetes cluster defined by your current kubeconfig context.

The user defined by the current context must have permissions to read the imagePullSecrets and service accounts listed in the Pod specifications.

You can provide an alternative kubeconfig file by setting the value of the --kubeconfig command-line flag or the KUBECONFIG environment variable to the full path of an alternative kubeconfig file.

Webhook online authentication

The webhook uses online authentication by default, and it uses the digester-admin Kubernetes service account to authenticate to the API server.

The digester-manager-role ClusterRole provides read access to all Secrets and ServiceAccounts in the cluster, and the digester-manager-rolebinding ClusterRoleBinding binds this role to the digester-admin Kubernetes service account in the digester-system namespace.

Webhook offline authentication

If you don't want to give the digester webhook read access to Secrets and ServiceAccounts in the cluster, you can enable offline authentication (--offline=true). With offline authentication, you can provide credentials to the webhook using a Docker config file:

  1. Set the offline flag value to true in the webhook Deployment manifest:

    kpt fn eval manifests --image gcr.io/kpt-fn/apply-setters:v0.2 -- offline=true
  2. Create a Docker config file containing map entries with usernames and passwords for your registries:

    REGISTRY_HOST=[your container image registry authority, e.g., registry.gitlab.com]
    REGISTRY_USERNAME=[your container image registry user name]
    REGISTRY_PASSWORD=[your container image registry password or token]
    
    cat << EOF > docker-config.json
    {
      "auths": {
        "$REGISTRY_HOST": {
          "username": "$REGISTRY_USERNAME",
          "password": "$REGISTRY_PASSWORD"
        }
      }
    }
    EOF
  3. Create a Secret in the digester-system namespace containing the config file:

    kubectl create secret generic docker-config --namespace digester-system \
        --from-file config.json=$(pwd)/docker-config.json
  4. Create a patch file for the webhook-controller-manager Deployment. The patch adds the Docker config file Secret as a volume, and mounts the volume on the Pods:

    cat << EOF > manifests/docker-config-patch.json
    [
      {
        "op": "add",
        "path": "/spec/template/spec/containers/0/volumeMounts/-",
        "value":{
          "mountPath": ".docker",
          "name": "docker",
          "readOnly": true
        }
      },
      {
        "op": "add",
        "path": "/spec/template/spec/volumes/-",
        "value": {
          "name": "docker",
          "secret": {
            "defaultMode": 420,
            "secretName": "docker-config"
          }
        }
      }
    ]
    EOF
  5. Add the patch to the kustomize manifest:

    cat << EOF >> manifests/Kustomization
    patches:
    - path: docker-config-patch.json
      target:
        group: apps
        version: v1
        kind: Deployment
        name: digester-controller-manager
    EOF
  6. Deploy the webhook with the patch:

    kubectl apply --kustomize manifests

If you use offline authentication, you can remove the rule in the digester-manager-role ClusterRole that grants access to secrets and serviceaccounts, see manifests/cluster-role.yaml.