---
title: Using image pull secrets
---

# Using image pull secrets {#using-image-pull-secrets}

To authenticate with container registries and pull images across OpenShift Container Platform projects or from secured registries, you can configure and use image pull secrets. You first obtain the registry authentication credentials, which are typically found in the `~/.docker/config.json` file for Docker or the `~/.config/containers/auth.json` file for Podman, created by the [pull secret from Red Hat OpenShift Cluster Manager](https://console.redhat.com/openshift/install/pull-secret) process. This content is then used to create or update the global `pullSecret` object within your cluster.

> [!NOTE]
> If you are using the OpenShift image registry and are pulling from image streams located in the same project, then your pod service account should already have the correct permissions. No additional action should be required.

## Allowing pods to reference images across projects {#images-allow-pods-to-reference-images-across-projects_using-image-pull-secrets}

To allow pods in one OpenShift Container Platform project to reference images from another project, you can bind a service account to the `system:image-puller` role in the target project. Use the `oc policy add-role-to-user` or `oc policy add-role-to-group` command to grant cross-project image access.

> [!NOTE]
> When you create a pod service account or a namespace, wait until the service account is provisioned with a Docker pull secret. If you create a pod before its service account is fully provisioned, the pod fails to access the OpenShift image registry.

**Procedure**

1. Allow pods in `project-a` to reference images in `project-b` by entering the following command. In this example, the service account `default` in `project-a` is bound to the `system:image-puller` role in `project-b`:

   ```terminal
   $ oc policy add-role-to-user \
       system:image-puller system:serviceaccount:project-a:default \
       --namespace=project-b
   ```
2. Optional: Allow access for any service account in `project-a` by using the `add-role-to-group` flag. For example:

   ```terminal
   $ oc policy add-role-to-group \
       system:image-puller system:serviceaccounts:project-a \
       --namespace=project-b
   ```

## Allowing pods to reference images from other secured registries {#images-allow-pods-to-reference-images-from-secure-registries_using-image-pull-secrets}

Pull secrets enable pods in OpenShift Container Platform to authenticate with secured registries and pull container images. Docker and Podman store authentication credentials in configuration files that you can use to create pull secrets for your service accounts.

The following files store your authentication information if you have previously logged in to a secured or insecure registry:

- **Docker**: By default, Docker uses `$HOME/.docker/config.json`.
- **Podman**: By default, Podman uses `$HOME/.config/containers/auth.json`.

> [!NOTE]
> Both Docker and Podman credential files and the associated pull secret can contain multiple references to the same registry if they have unique paths, for example, `quay.io` and `quay.io/<example_repository>`. However, neither Docker nor Podman support multiple entries for the exact same registry path.

```json {title="Example config.json file"}
{
   "auths":{
      "cloud.openshift.com":{
         "auth":"b3Blb=",
         "email":"you@example.com"
      },
      "quay.io":{
         "auth":"b3Blb=",
         "email":"you@example.com"
      },
      "quay.io/repository-main":{
         "auth":"b3Blb=",
         "email":"you@example.com"
      }
   }
}
```

```yaml {title="Example pull secret"}
apiVersion: v1
data:
  .dockerconfigjson: ewogICAiYXV0aHMiOnsKICAgICAgIm0iOnsKICAgICAgIsKICAgICAgICAgImF1dGgiOiJiM0JsYj0iLAogICAgICAgICAiZW1haWwiOiJ5b3VAZXhhbXBsZS5jb20iCiAgICAgIH0KICAgfQp9Cg==
kind: Secret
metadata:
  creationTimestamp: "2021-09-09T19:10:11Z"
  name: pull-secret
  namespace: default
  resourceVersion: "37676"
  uid: e2851531-01bc-48ba-878c-de96cfe31020
type: Opaque
```

### Creating a pull secret {#creating-pull-secret_using-image-pull-secrets}

To authenticate with container registries in OpenShift Container Platform, you can create pull secrets from existing Docker or Podman authentication files. You can also create secrets by providing registry credentials directly by using the `oc create secret docker-registry` command.

**Procedure**

1. Create a secret from an existing authentication file:

   1. For Docker clients using `.docker/config.json`, enter the following command:

      ```terminal
      $ oc create secret generic <pull_secret_name> \
          --from-file=.dockerconfigjson=<path/to/.docker/config.json> \
          --type=kubernetes.io/dockerconfigjson
      ```
   2. For Podman clients using `.config/containers/auth.json`, enter the following command:

      ```terminal
      $ oc create secret generic <pull_secret_name> \
           --from-file=<path/to/.config/containers/auth.json> \
           --type=kubernetes.io/podmanconfigjson
      ```
2. Optional: If you do not already have a Docker credentials file for the secured registry, you can create a secret by running the following command:

   ```terminal
   $ oc create secret docker-registry <pull_secret_name> \
       --docker-server=<registry_server> \
       --docker-username=<user_name> \
       --docker-password=<password> \
       --docker-email=<email>
   ```

### Using a pull secret in a workload {#using-pull-secret_using-image-pull-secrets}

To allow workloads to pull images from private registries in OpenShift Container Platform, you can link the pull secret to a service account by entering the `oc secrets link` command or by defining it directly in your workload configuration YAML file.

**Procedure**

1. Link the pull secret to a service account by entering the following command. Note that the name of the service account should match the name of the service account that pod uses. The default service account is `default`.

   ```terminal
   $ oc secrets link default <pull_secret_name> --for=pull
   ```
2. Verify the change by entering the following command:

   ```terminal
   $ oc get serviceaccount default -o yaml
   ```

   ```yaml {title="Example output"}
   apiVersion: v1
   imagePullSecrets:
   - name: default-dockercfg-123456
   - name: <pull_secret_name>
   kind: ServiceAccount
   metadata:
     annotations:
       openshift.io/internal-registry-pull-secret-ref: <internal_registry_pull_secret>
     creationTimestamp: "2025-03-03T20:07:52Z"
     name: default
     namespace: default
     resourceVersion: "13914"
     uid: 9f62dd88-110d-4879-9e27-1ffe269poe3
   secrets:
   - name: <pull_secret_name>
   ```
3. Optional: Instead of linking the secret to a service account, you can alternatively reference it directly in your pod or workload definition. This is useful for GitOps workflows such as ArgoCD. For example:

   ```yaml {title="Example pod specification"}
   apiVersion: v1
   kind: Pod
   metadata:
     name: <secure_pod_name>
   spec:
     containers:
     - name: <container_name>
       image: quay.io/my-private-image
     imagePullSecrets:
     - name: <pull_secret_name>
   ```

   ```yaml {title="Example ArgoCD workflow"}
   apiVersion: argoproj.io/v1alpha1
   kind: Workflow
   metadata:
     generateName: <example_workflow>
   spec:
     entrypoint: <main_task>
     imagePullSecrets:
     - name: <pull_secret_name>
   ```

### Pulling from private registries with delegated authentication {#images-pulling-from-private-registries_using-image-pull-secrets}

To pull images from private registries that delegate authentication to a separate service in OpenShift Container Platform, you can create pull secrets for both the authentication server and the registry endpoint. Use the `oc create secret docker-registry` command to create separate secrets for each service.

**Procedure**

1. Create a secret for the delegated authentication server by entering the following command:

   ```terminal
   $ oc create secret docker-registry \
       --docker-server=sso.redhat.com \
       --docker-username=developer@example.com \
       --docker-password=******** \
       --docker-email=unused \
       redhat-connect-sso
   ```
2. Create a secret for the private registry by entering the following command:

   ```terminal
   $ oc create secret docker-registry \
       --docker-server=privateregistry.example.com \
       --docker-username=developer@example.com \
       --docker-password=******** \
       --docker-email=unused \
       private-registry
   ```

## Updating the global cluster pull secret {#images-update-global-pull-secret_using-image-pull-secrets}

To add new registries or update authentication for your OpenShift Container Platform cluster, you can update the global pull secret by appending new credentials to the *additional-pull-secret*. To do this, you can use the `oc set data secret/additional-pull-secret -n kube-system` command. Hypershift manages the new credential propagation among the HostedCluster nodes.

> [!IMPORTANT]
> The global pull secret is a HostedControlPlane feature only and is not an OCP standalone feature.
>
> To transfer your cluster to another owner, you must initiate the transfer in [OpenShift Cluster Manager](https://console.redhat.com/openshift) and then update the pull secret on the cluster. Updating a cluster’s pull secret without initiating the transfer in OpenShift Cluster Manager causes the cluster to stop reporting Telemetry metrics in OpenShift Cluster Manager.
>
> For more information, see *Transferring cluster ownership* under *Additional resources* in the Red Hat OpenShift Cluster Manager documentation.

**Prerequisites**

- You have access to the cluster as a user with the `cluster-admin` role.

**Procedure**

1. Optional: To append a new pull secret to the existing pull secret:

   1. Download the pull secret by entering the following command:

      ```terminal
      $ oc get secret/pull-secret -n openshift-config --template='{{index .data ".dockerconfigjson" | base64decode}}' > <pull_secret_location>
      ```

      where:

      `<pull_secret_location>`
      :   Specifies the path to the pull secret file.
   2. Add the new pull secret by entering the following command:

      ```terminal
      $ oc registry login --registry="<registry>" \
      --auth-basic="<username>:<password>" \
      --to=<pull_secret_location>
      ```

      where:

      `<registry>`
      :   Specifies the new registry. You can include many repositories within the same registry, for example: `--registry="<registry/my-namespace/my-repository>`.

      `<username>:<password>`
      :   Specifies the credentials of the new registry.

      `<pull_secret_location>`
      :   Specifies the path to the pull secret file.
2. Update the global pull secret for your cluster by entering the following command. Note that this update rolls out to all nodes, which can take some time depending on the size of your cluster.

   ```terminal
   $ oc set data secret/pull-secret -n openshift-config \
     --from-file=.dockerconfigjson=<pull_secret_location>
   ```

   where:

   `<pull_secret_location>`
   :   Specifies the path to the new pull secret file.

   This merges your additional pull secret with the original HostedCluster pull secret, making it available to all nodes in the cluster.
3. Optional: Modify the additional pull secret added by entering the following command:

   ```terminal
   $ oc edit secret additional-pull-secret -n kube-system
   ```

   The secret must contain a valid DockerConfigJSON format.

   ```yaml {title="Example pull secret"}
   apiVersion: v1
   kind: Secret
   metadata:
     name: additional-pull-secret
     namespace: kube-system
   type: kubernetes.io/dockerconfigjson
   data:
     .dockerconfigjson: <base64-encoded-docker-config-json>
   ```

   This results in the following states of the each pull secret:

   - **Original**: immutable
   - **Additional**: mutable
   - **Global**: final state of both the original and additional pull secrets
4. Optional: Delete the additional pull secret added by entering the following command:

   ```terminal
   $ oc delete secret additional-pull-secret -n kube-system
   ```

   This triggers the automatic cleanup process across your nodes.

**Additional resources**
{._additional-resources}

- [Quay.io container registry](https://quay.io/)
- [Red Hat container registry](https://registry.redhat.io)
- [Transferring cluster ownership](https://docs.redhat.com/en/documentation/openshift_cluster_manager/1-latest/html-single/managing_clusters/index#transferring-cluster-ownership_downloading-and-updating-pull-secrets)
