Skip to main content
Redhat Developers  Logo
  • Products

    Featured

    • Red Hat Enterprise Linux
      Red Hat Enterprise Linux Icon
    • Red Hat OpenShift AI
      Red Hat OpenShift AI
    • Red Hat Enterprise Linux AI
      Linux icon inside of a brain
    • Image mode for Red Hat Enterprise Linux
      RHEL image mode
    • Red Hat OpenShift
      Openshift icon
    • Red Hat Ansible Automation Platform
      Ansible icon
    • Red Hat Developer Hub
      Developer Hub
    • View All Red Hat Products
    • Linux

      • Red Hat Enterprise Linux
      • Image mode for Red Hat Enterprise Linux
      • Red Hat Universal Base Images (UBI)
    • Java runtimes & frameworks

      • JBoss Enterprise Application Platform
      • Red Hat build of OpenJDK
    • Kubernetes

      • Red Hat OpenShift
      • Microsoft Azure Red Hat OpenShift
      • Red Hat OpenShift Virtualization
      • Red Hat OpenShift Lightspeed
    • Integration & App Connectivity

      • Red Hat Build of Apache Camel
      • Red Hat Service Interconnect
      • Red Hat Connectivity Link
    • AI/ML

      • Red Hat OpenShift AI
      • Red Hat Enterprise Linux AI
    • Automation

      • Red Hat Ansible Automation Platform
      • Red Hat Ansible Lightspeed
    • Developer tools

      • Red Hat Trusted Software Supply Chain
      • Podman Desktop
      • Red Hat OpenShift Dev Spaces
    • Developer Sandbox

      Developer Sandbox
      Try Red Hat products and technologies without setup or configuration fees for 30 days with this shared Openshift and Kubernetes cluster.
    • Try at no cost
  • Technologies

    Featured

    • AI/ML
      AI/ML Icon
    • Linux
      Linux Icon
    • Kubernetes
      Cloud icon
    • Automation
      Automation Icon showing arrows moving in a circle around a gear
    • View All Technologies
    • Programming Languages & Frameworks

      • Java
      • Python
      • JavaScript
    • System Design & Architecture

      • Red Hat architecture and design patterns
      • Microservices
      • Event-Driven Architecture
      • Databases
    • Developer Productivity

      • Developer productivity
      • Developer Tools
      • GitOps
    • Secure Development & Architectures

      • Security
      • Secure coding
    • Platform Engineering

      • DevOps
      • DevSecOps
      • Ansible automation for applications and services
    • Automated Data Processing

      • AI/ML
      • Data Science
      • Apache Kafka on Kubernetes
      • View All Technologies
    • Start exploring in the Developer Sandbox for free

      sandbox graphic
      Try Red Hat's products and technologies without setup or configuration.
    • Try at no cost
  • Learn

    Featured

    • Kubernetes & Cloud Native
      Openshift icon
    • Linux
      Rhel icon
    • Automation
      Ansible cloud icon
    • Java
      Java icon
    • AI/ML
      AI/ML Icon
    • View All Learning Resources

    E-Books

    • GitOps Cookbook
    • Podman in Action
    • Kubernetes Operators
    • The Path to GitOps
    • View All E-books

    Cheat Sheets

    • Linux Commands
    • Bash Commands
    • Git
    • systemd Commands
    • View All Cheat Sheets

    Documentation

    • API Catalog
    • Product Documentation
    • Legacy Documentation
    • Red Hat Learning

      Learning image
      Boost your technical skills to expert-level with the help of interactive lessons offered by various Red Hat Learning programs.
    • Explore Red Hat Learning
  • Developer Sandbox

    Developer Sandbox

    • Access Red Hat’s products and technologies without setup or configuration, and start developing quicker than ever before with our new, no-cost sandbox environments.
    • Explore Developer Sandbox

    Featured Developer Sandbox activities

    • Get started with your Developer Sandbox
    • OpenShift virtualization and application modernization using the Developer Sandbox
    • Explore all Developer Sandbox activities

    Ready to start developing apps?

    • Try at no cost
  • Blog
  • Events
  • Videos

Access Quay on OpenShift with short-lived credentials

April 22, 2025
Andrew Block
Related topics:
ContainersSecurity
Related products:
Developer SandboxRed Hat OpenShiftRed Hat Quay

Share:

    The increasing adoption of short-lived credentials has enabled organizations to align with zero-trust principles and increase their overall security posture. As introduced in our first article, How short-lived credentials in Quay improve security, quay.io and the self-managed Red Hat Quay now support the generation of short-lived credentials to enable access to the registry. This feature opens the door to a wide range of options for managing integrations with Quay in a secure fashion.

    In the previous article, we used a JSON Web Token (JWT) provided by the Red Hat build of Keycloak to invoke the /oauth2/federation API within Quay to generate a set of short-lived credentials. In this second article of our three-part series, we will demonstrate how to enable additional tools and methodologies to access Quay in a secure manner using short-lived credentials.

    Enabling Quay robot account federation

    To use the federation capability within Quay, a robot account must be available. A robot account can be created either within an organization (for example, "quay_federation") or in the account of an individual user. Within the organization or user account, select the Robot Accounts tab and click the Create robot account button. Enter "keyless" as the name of the robot and complete the remaining dialog options as desired to complete the robot account creation process.

    In addition to a robot account needing to be available, federation can only be achieved interactively when using the Quay v2 user interface. This capability is enabled by default in quay.io. However, this feature may not be enabled within the self-managed Red Hat Quay. Consult the Red Hat Quay documentation for steps to enable this feature.

    OpenShift service account token federation

    A popular method for accessing external services within Red Hat OpenShift is to make use of service account federation. Once enabled (such as in the case of AWS Security Token Service (STS) or Azure Workload Identity), service account tokens are generated using an OpenID Connect (OIDC) provider configured within the target platform. When combined with the volume projection feature of service accounts, a JWT can be injected as a volume within a pod so that a workload can make use of the value. In addition, since OpenShift manages the lifecycle of the token, not only are the values short-lived, but a new token is generated automatically upon expiration time. We can make use of this feature to exchange the JWT provided by OpenShift for a set of Quay credentials.

    To demonstrate this feature, you will need an OpenShift environment with service account federation enabled with the service account issuer referencing an external OIDC endpoint. If you are leveraging one of the aforementioned integrations in your OpenShift environment, you are all set to go. If you do not have an OpenShift environment where this feature is enabled, a good alternative is the Developer Sandbox, integrated with AWS STS.

    In the following example, we will create a workload inside a cluster that hypothetically wants to communicate with a Quay registry. Instead of relying on static, long-lived credentials, we will enable it to use short-lived robot tokens from Quay. We will do this by giving the workload pod access to a token in the form of a simple text file in its local filesystem. The token is signed by an OIDC provider that the cluster has been configured with. The same OIDC provider will be configured inside Quay as a trusted issuer. 

    This constitutes a mutual trust, also referred to as "federation." This allows application logic inside the workload pod to use this token to authenticate to Quay and get a short-lived credential back in return. That credential token can then be used to communicate with and automate against Quay. The workload needs to request a new token from Quay regularly once the old one expires (we won’t cover this in the example, for brevity). This is more secure than a long-lived credential assigned to the pod (e.g., via an environment variable or ConfigMap) that, when leaked, can be used to wreak havoc by malicious actors without any time limit.

    If you followed along with the previous article, the method discussed below essentially automates the first part of the article, where the token was created manually from within Red Hat build of Keycloak.

    Once a suitable environment has been selected, authenticate to the cluster using the OpenShift command-line interface (CLI) and create a new namespace called quay-keyless that will contain resources to interact with Quay.

    cat <<EOF | oc apply -f -
    apiVersion: v1
    kind: Namespace
    metadata:
      name: quay-keyless
    spec: {}
    EOF

    Note:

    If you are running in the Developer Sandbox, a namespace will be provided for you. For each of the example manifests that will be provided, place the namespace field with the name of the namespace allocated for you.

    Now, given that access to Quay will leverage service account federation, an OpenShift service account will need to be created in order for it to be federated with Quay. Create a dedicated service account called quay-keyless using the following command:

    cat <<EOF | oc apply -f -
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: quay-keyless
      namespace: quay-keyless
    EOF

    Finally, create a simple workload deployment that can be used to exchange credentials with Quay:

    cat <<EOF | oc apply -f -
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: quay-keyless
      namespace: quay-keyless
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: quay-keyless
      strategy:
        type: Recreate
      template:
        metadata:
          labels:
            app: quay-keyless
            deployment: quay-keyless
        spec:
          containers:
          - command:
            - /bin/bash
            - -c
            - |
              #!/bin/bash
    
              while true; do sleep 10; done
            image: registry.redhat.io/ubi9/skopeo:latest
            name: quay-keyless
            resources: {}
            volumeMounts:
            - mountPath: /var/run/secrets/tokens
              name: openshift-token
              readOnly: true
            - name: run-containers
              mountPath: /run/containers
          serviceAccountName: quay-keyless
          volumes:
          - name: openshift-token
            projected:
              defaultMode: 420
              sources:
              - serviceAccountToken:
                  audience: openshift
                  expirationSeconds: 7200
                  path: openshift-token
          - name: run-containers
            emptyDir: {}
    EOF

    There are several properties of note within this deployment. First, the quay-keyless service account that was previously created is being used to run the workload as defined by the serviceAccountName property. Next, and most likely the most significant property of the deployment for this demonstration, is the projected service account token volume:

    volumes:
    - name: openshift-token
      projected:
        defaultMode: 420
        sources:
        - serviceAccountToken:
            audience: openshift
            expirationSeconds: 7200
            path: openshift-token

    By specifying this property, the kubelet obtains a token from the kube-apiserver and mounts the value in a file referenced by the corresponding volume mount.

    With all of the resources created within the cluster, let’s see how we can make use of these capabilities. Confirm that the workload pod was created successfully and is currently running:

    oc get pods -n quay-keyless

    A result similar to the following should be returned:

    NAME                            READY   STATUS    RESTARTS   AGE
    quay-keyless-85f4c77d7f-cpqk2   1/1     Running   0          3h

    Now that the workload has been confirmed to be running, obtain a remote shell session within the pod:

    oc rsh -n quay-keyless deployment/quay-keyless

    Within the workload pod, we can use the token that was injected by the projected service account token volume. The token is located in a file called openshift-token in the /var/run/secrets/tokens directory.

    Confirm the file is present and contains a JWT:

    cat /var/run/secrets/tokens/openshift-token

    Next, confirm that the token was obtained from an externally facing OIDC issuer and not the internal Kubernetes API server. This is important because Quay must be able to contact this endpoint in order to validate the token. Execute the following command to extract the OIDC issuer from the JWT:

    cat /var/run/secrets/tokens/openshift-token | cut -d '.' -f 2 | sed 's/[^=]$/&==/' | base64 -d | python3 -c 'import json,sys;print(json.load(sys.stdin)["iss"])'

    If https://kubernetes.default.svc is the value that was returned from the prior command, the OpenShift environment being leveraged does not have the service account federation feature enabled and cannot be used for this purpose. Otherwise, take note of this value, as it will be used in subsequent steps.

    The OIDC issuer is one of two values that Quay uses to verify a supplied JWT has rights to federate. The other value is the subject. In this case, the subject is the OpenShift service account. Obtain the subject from the JWT:

    cat /var/run/secrets/tokens/openshift-token | cut -d '.' -f 2 | sed 's/[^=]$/&==/' | base64 -d | python3 -c 'import json,sys;print(json.load(sys.stdin)["sub"])'

    system:serviceaccount:quay-keyless:quay-keyless should be the value that is returned, as the subject takes the form system:serviceaccount:<namespace>:<name>, which aligns with how the namespace and the corresponding resources were configured.

    Now that the OIDC issuer and the subject have been obtained, these values can be associated with the Quay robot account in order for credentials to be exchanged. Return to the Quay instance and navigate to the Robot accounts tab where the keyless robot account that was previously created is located. Click the menu kebab next to the keyless robot account and select Set robot federation (Figure 1).

    Dialog to configure Federation for a Robot account
    Figure 1: Dialog to configure federation for a robot account.

    Click the plus (+) button and enter the OIDC Issuer and subject that was retrieved previously from the JWT within the pod. Click Save to apply the changes and then Close to minimize the dialog (Figure 2).

    Robot account Federation dialog
    Figure 2: Robot account federation dialog.

    With the settings in Quay configured to enable robot account federation, return to the OpenShift command line and obtain a session in the quay-keyless deployment again if the prior session timed out so that we can verify the integration.

    Once in the workload pod, set a few environment variables to simplify the commands that will be issued. First, set the QUAY_REGISTRY_HOSTNAME environment variable representing the hostname of the Quay registry instance. For example, if quay.io is the desired target instance, the value of the QUAY_REGISTRY_HOSTNAME variable would be quay.io:

    export QUAY_REGISTRY_HOSTNAME=<quay_registry>

    Next, set the full name of the robot account in a variable called ROBOT_ACCOUNT. The full name of a robot account is represented by the organization for which the robot account is part of and the name of the robot account, separated by a plus (+) sign. For the robot account previously created, the full name is <organization>+keyless:

    export ROBOT_ACCOUNT=<full_robot_account_name>

    To avoid an overly verbose command when invoking Quay, set the JWT_TOKEN_CMD environment variable to represent the command that is used to obtain the JWT:

    export JWT_TOKEN_CMD="cat /var/run/secrets/tokens/openshift-token"

    Now, execute the credential exchange by invoking the /oauth2/federation/robot/token Quay endpoint and passing in the name of the robot account and the contents of the JWT into the curl command and setting the output within an environment variable called QUAY_TOKEN:

    QUAY_TOKEN=$(curl -s --user ${ROBOT_ACCOUNT}:$($JWT_TOKEN_CMD) https://${QUAY_REGISTRY_HOSTNAME}/oauth2/federation/robot/token | python3 -c 'import json,sys;print(json.load(sys.stdin)["token"])')

    Inspect the contents of the QUAY_TOKEN environment variable to confirm it contains the JWT enabling access to Quay resources:

    echo $QUAY_TOKEN

    The combination of the robot account and the token obtained from the federation endpoint can be used to gain access to protected resources, such as a private repository within Quay. The application inside the workload pod can now leverage this token to interact with Quay. It is also responsible for regularly refreshing this token from Quay, either when it expires or when the projected token issued from the Kubernetes API server is rotated. 

    Note that the Kubernetes API server rotates projected tokens in place, meaning that the application inside the workload pod must reread the token from the path (/var/run/secrets/tokens/openshift-token in our example) once it has expired. As a result, the application must routinely reread the token so that it ensures that it leverages the most up-to-date value.

    The workload pod is leveraging an image containing the skopeo binary which can be used to interact with the remote Quay registry to perform operations such as listing tags, inspecting manifests, and copying content. Log in to the Quay instance using the credentials retrieved previously:

    skopeo login --username ${ROBOT_ACCOUNT} --password ${QUAY_TOKEN} ${QUAY_REGISTRY_HOSTNAME}

    A Login Succeeded! message indicates skopeo was able to authenticate to Quay successfully.

    Federated robot account credentials are valid for 1 hour. Since the returned token from Quay is a JWT itself, the expiration time can be found in the exp token claim.

    By leveraging a JWT as an identity from a projected service account token issued from an issuer Quay trusts, we were able to perform an exchange to obtain a set of short-lived credentials from the Quay API endpoint. This credential can be used to access resources in Quay and follows best practices, since it is time-limited and its permission scope is limited to the permissions associated with the robot account (least privilege principle).

    SPIFFE/SPIRE

    While OpenShift service account federation provides an integrated method for supplying an identity to a workload, one of the biggest drawbacks is that it is not available in all environments, such as an on-premise OpenShift cluster. An alternate solution that does support workload identity capabilities and can be used in public and private cloud environments is SPIFFE (Secure Production Identity Framework for Everyone) and its corresponding implementation SPIRE (The SPIFFE Runtime Environment). Similar to service account federation, an identity can be obtained from SPIRE and exchanged for a set of Quay credentials. While SPIRE supports the use of X.509 certificate-based identities, JWT-based identities will once be used to authenticate to Quay. Learn more about SPIFFE/SPIRE with an excellent overview of the use cases and how to get started.

    SPIRE deployment

    The installation of SPIRE to an OpenShift environment is facilitated by a Helm based deployment. Elevated privileges within the OpenShift environment are required in order to deploy SPIRE. As a result, the Developer Sandbox cannot be used.

    First, set a variable called APP_DOMAIN that represents the apps domain of the cluster:

    export APP_DOMAIN=apps.$(oc get dns cluster -o jsonpath='{ .spec.baseDomain }')

    Next, clone the upstream Helm chart repository to the local machine:

    git clone https://github.com/spiffe/helm-charts-hardened.git

    Now, deploy the SPIRE Custom Resource Definition chart:

    helm upgrade --install --create-namespace -n spire-mgmt spire-crds helm-charts-hardened/charts/spire-crds

    Then deploy the SPIRE chart:

    helm upgrade --install --create-namespace -n spire-mgmt spire helm-charts-hardened/charts/spire -f install/spire/spire-helm-values.yaml --set global.spire.namespaces.create=true --set global.spire.trustDomain=$APP_DOMAIN --values helm-charts-hardened/examples/tornjak/values.yaml --values helm-charts-hardened/examples/tornjak/values-ingress.yaml --render-subchart-notes --debug

    After a few minutes, SPIRE will be deployed to OpenShift. Confirm the following commands return the expected results.

    First, check the contents of the spire-server namespace:

    oc -n spire-server get pods

    A successful result should return 3 running pods with all containers running and READY similar to the following:

    NAME                                                    READY   STATUS    RESTARTS   AGE
    spire-server-0                                          3/3     Running   0          9m17s
    spire-spiffe-oidc-discovery-provider-7788f57c55-7zt7r   3/3     Running   0          9m17s
    spire-tornjak-frontend-6bb4dc6d7c-b7kn7                 1/1     Running   0          9m17s

    Then, check the contents of the spire-system namespace:

    oc get daemonset -n spire-system

    Confirm that both spire-agent and spire-spiffe-csi-driver DaemonSets are up and running:

    NAME                      DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
    spire-agent               3         3         3       3            3           <none>          21m
    spire-spiffe-csi-driver   3         3         3       3            3           <none>          21m

    Obtain Quay credentials using SPIRE identities

    Now that SPIRE has been installed successfully, let’s update our workload deployment so that it can obtain an identity from SPIRE. Execute the following command to update the deployment: 

    oc patch -n quay-keyless deployment/quay-keyless --patch-file /dev/stdin <<EOF
    {
      "spec": {
        "template": {
          "spec": {
            "containers": [
              {
                "command": [
                  "/bin/bash",
                  "-c",
                  "#!/bin/bash\n\ncat << EOF > /opt/app-root/src/get-spiffe-token.py\n#!/opt/app-root/bin/python\n\nfrom spiffe import JwtSource\nimport argparse\n\n\nparser = argparse.ArgumentParser(description='Retrieve SPIFFE Token.')\nparser.add_argument(\"-a\", \"--audience\", help=\"The audience to include in the token\", default=\"openshift\")\nargs = parser.parse_args()\n\nwith JwtSource() as source:\n    jwt_svid = source.fetch_svid(audience={args.audience})\n    print(jwt_svid.token)\nEOF\n\nchmod +x /opt/app-root/src/get-spiffe-token.py\n\npip install spiffe\n\n# Add .ready File\ntouch /opt/app-root/src/.ready\n\nwhile true; do sleep 10; done\n"
                ],
                "env": [
                  {
                    "name": "SPIFFE_ENDPOINT_SOCKET",
                    "value": "unix:///run/spire/sockets/spire-agent.sock"
                  }
                ],
                "image": "registry.redhat.io/ubi9/python-311:latest",
                "name": "quay-keyless",
                "startupProbe": {
                  "exec": {
                    "command": [
                      "/bin/bash",
                      "-c",
                      "ls /opt/app-root/src/.ready"
                    ]
                  },
                  "failureThreshold": 60,
                  "periodSeconds": 10,
                  "successThreshold": 1,
                  "timeoutSeconds": 1
                },
                "volumeMounts": [
                  {
                    "mountPath": "/run/spire/sockets",
                    "name": "spiffe-workload-api",
                    "readOnly": true
                  }
                ]
              }
            ],
            "volumes": [
              {
                "csi": {
                  "driver": "csi.spiffe.io",
                  "readOnly": true
                },
                "name": "spiffe-workload-api"
              }
            ]
          }
        }
      }
    }
    EOF

    Wait for the updated deployment to roll out. Once the new pod becomes available and ready, obtain a remote shell session once again:

    oc rsh -n quay-keyless deployment/quay-keyless

    The updated deployment generated a script named get-spiffe-token.py which simplifies obtaining a JWT from the SPIRE workload API. The script is located in the /opt/app-root/src directory (default HOME directory where the remote session began).

    Execute the script to retrieve the JWT from SPIRE:

    /opt/app-root/src/get-spiffe-token.py

    For the SPIRE JWT to be used to exchange credentials with Quay, the OIDC issuer and subject must be extracted.

    Execute the following command to obtain the OIDC issuer of the SPIRE OIDC discovery provider:

    /opt/app-root/src/get-spiffe-token.py | cut -d '.' -f 2 | sed 's/[^=]$/&==/' | base64 -d | python -c 'import json,sys;print(json.load(sys.stdin)["iss"])'

    Now obtain the subject:

    /opt/app-root/src/get-spiffe-token.py | cut -d '.' -f 2 | sed 's/[^=]$/&==/' | base64 -d | python -c 'import json,sys;print(json.load(sys.stdin)["sub"])'

    The value of the subject returned should be in the form spiffe://<trust_domain>/ns/quay-keyless/sa/quay-keyless as it includes the namespace the workload is deployed within and the service account that is used to run the workload.

    With the OIDC issuer and subject obtained, return to the Quay instance and navigate to the Robot accounts tab where the keyless robot account that was previously created is located. Click the menu kebab next to the keyless robot account and select Set robot federation.

    Click the plus (+) button to add an additional federation configuration by entering the OIDC issuer and subject that was obtained from the SPIRE JWT within the pod. Click Save to apply the changes and then Close to minimize the dialog.

    Once again, we will repeat many of the same steps that were performed previously within the service account federation section. First, set the QUAY_REGISTRY_HOSTNAME environment variable representing the hostname of the Quay registry instance. For example, if quay.io is the desired target instance, the value of the QUAY_REGISTRY_HOSTNAME variable would be quay.io:

    export QUAY_REGISTRY_HOSTNAME=<quay_registry>

    Next, set the full name of the robot account in a variable called ROBOT_ACCOUNT. The full name of a robot account is represented by the organization for which the robot account is part of and the name of the robot account, separated by a plus (+) sign. For the robot account previously created, the full name is <organization>+keyless:

    export ROBOT_ACCOUNT=<full_robot_account_name>

    To avoid an overly verbose command when invoking Quay, set the JWT_TOKEN_CMD environment variable to represent the command that is used to obtain the JWT:

    export JWT_TOKEN_CMD="/opt/app-root/src/get-spiffe-token.py"

    Now, execute the credential exchange by invoking the /oauth2/federation/robot/token Quay endpoint and passing in the name of the robot account and the contents of the JWT into the curl command and setting the output within an environment variable called QUAY_TOKEN:

    QUAY_TOKEN=$(curl -s --user ${ROBOT_ACCOUNT}:$($JWT_TOKEN_CMD) https://${QUAY_REGISTRY_HOSTNAME}/oauth2/federation/robot/token | python -c 'import json,sys;print(json.load(sys.stdin)["token"])')

    Inspect the contents of the QUAY_TOKEN environment variable to confirm it contains the JWT enabling access to Quay resources:

    echo $QUAY_TOKEN

    The presence of a JWT indicates that the integration was successful. By leveraging SPIFFE provided identities, we can simplify and secure access to resources within Quay across the hybrid cloud.

    What's next

    In this article, we explored two ways to assign workloads in pods on an OpenShift cluster with an identity to allow it to authenticate to Quay. We were able to use this identity to exchange a set of short-lived credentials for secure interaction with the Quay API. We did not need to embed classic, long-lived credentials to authenticate. This method works solely on the basis of identity in the form of a token signed by a trusted OIDC Issuer. In one instance, identity was given to the pod by the Kubernetes API server, which was configured with an external OIDC provider. In the other example, the token was obtained by communicating with SPIRE as the OIDC provider over a UNIX socket.

    This dramatically reduces the attack surface to the cluster-internal network and nodes. Leveraging short-lived credentials also lowers the probability and impact of accidental leaks, for instance, by persisting them inadvertently in a Git repository. Even if a short-lived credential leaked, it could only be used for a limited amount of time before it automatically expires.

    Both examples focused on workloads inside pods that want to communicate with a Quay registry. But the cluster infrastructure also communicates with container registries to check for new images, authenticate image pulls, or facilitate pushes. In the final installment of this series, we will focus on how we can enable the cluster to leverage short-lived credentials with Quay. Stay tuned for part 3 next week!

    Last updated: April 23, 2025

    Related Posts

    • How short-lived credentials in Quay improve security

    • How the External Secrets Operator manages Quay credentials

    • Using Quay.io to find vulnerabilities in your container images

    • Optimizing Quay/Clair: Profiling, performance, and efficiency

    Recent Posts

    • How to run a fraud detection AI model on RHEL CVMs

    • How we use software provenance at Red Hat

    • Alternatives to creating bootc images from scratch

    • How to update OpenStack Services on OpenShift

    • How to integrate vLLM inference into your macOS and iOS apps

    What’s up next?

    Learn how to set up and use the Developer Sandbox for Red Hat OpenShift. With the Developer Sandbox, you experience hands-on learning resources without setup or configuration, and learn to develop quicker than ever before.

    Start the activity
    Red Hat Developers logo LinkedIn YouTube Twitter Facebook

    Products

    • Red Hat Enterprise Linux
    • Red Hat OpenShift
    • Red Hat Ansible Automation Platform

    Build

    • Developer Sandbox
    • Developer Tools
    • Interactive Tutorials
    • API Catalog

    Quicklinks

    • Learning Resources
    • E-books
    • Cheat Sheets
    • Blog
    • Events
    • Newsletter

    Communicate

    • About us
    • Contact sales
    • Find a partner
    • Report a website issue
    • Site Status Dashboard
    • Report a security problem

    RED HAT DEVELOPER

    Build here. Go anywhere.

    We serve the builders. The problem solvers who create careers with code.

    Join us if you’re a developer, software engineer, web designer, front-end designer, UX designer, computer scientist, architect, tester, product manager, project manager or team lead.

    Sign me up

    Red Hat legal and privacy links

    • About Red Hat
    • Jobs
    • Events
    • Locations
    • Contact Red Hat
    • Red Hat Blog
    • Inclusion at Red Hat
    • Cool Stuff Store
    • Red Hat Summit

    Red Hat legal and privacy links

    • Privacy statement
    • Terms of use
    • All policies and guidelines
    • Digital accessibility

    Report a website issue