Authenticate to Chainguard's Registry

A guide on authenticating to Chainguard's registry to get container images
  10 min read

Public Container Images

Chainguard offers a collection of images that are publicly available, don’t require authentication, and are free to use by anyone. However, logging in with a Chainguard account and authenticating when pulling from the registry gives you access to the Chainguard Console, and provides a mechanism for Chainguard to contact you if there are any issues with images you are pulling. This may enable Chainguard to notify you of upcoming deprecations, changes in behavior, critical vulnerabilities and remediations for images you have recently pulled.

Signing Up

You can register a Chainguard account through our sign up form. This will create your account and a Chainguard IAM organization. If you already have an account, you can log in through the login page.

For more details on signing in, you can review our sign in guidance. If your organization is interested in (or already using) custom identity providers like Okta, you can read how to authenticate to Chainguard with custom identity providers.

Authenticating with the chainctl Credential Helper

You can configure authentication by using the credential helper included with chainctl. This is the workflow recommended by Chainguard.

First install chainctl and configure the credential helper:

chainctl auth configure-docker

This will update your Docker config file to call chainctl when an auth token is needed. A browser window will open when the token needs to be refreshed.

Pulls authenticated in this way are associated with your user.

Authenticating with a Pull Token

You can also create a “pull token” using chainctl. This generates a longer-lived token that can be used to pull images from other environments that don’t support OIDC, such as some CI environments, Kubernetes clusters, or with registry mirroring tools like Artifactory.

First install chainctl, then log in and configure a pull token:

chainctl auth configure-docker --pull-token

With the latest release of chainctl, this will print a docker login command that can be run in the CI environment to log in with a pull token.

You can also pass the --save flag, which will update your Docker config file with the pull token directly.

This token expires in 30 days by default, which can be modified using the --ttl flag. It sets the duration for the validity of the token. The maximum valid value is 8760h (equivalent to 365 days), Valid unit strings range from nanoseconds to hours and are ns, us, ms, s, m, and h, for example --ttl=24h.

Pulls authenticated in this way are associated with a Chainguard identity, which is associated with the organization selected when the pull token was created.

You can also export the pull token details into environment variables for authentication in automated systems.

Note on Multiple Pull Tokens

Running the chainctl auth configure-docker --pull-token command multiple times will result in multiple pull tokens being created. However, the tokens stored in your Docker config when using --save will overwrite old tokens.

Tokens cannot be retrieved once they have been overwritten so they must be extracted from the local Docker config and saved elsewhere if multiple are required.

Revoking a Pull Token

Pull tokens are associated with Chainguard identities so they can be viewed with:

chainctl iam identities list

To revoke a token, delete the associated identity.

chainctl iam identity delete <identity UUID>

Managing Pull Tokens in the Chainguard Console

You can also create and view pull tokens in the Chainguard Console.

After navigating to the Console, click on Settings in the left-hand navigation menu. From the Settings pane, click on Pull tokens. There, you’ll be presented with a table listing of all the active pull tokens for your selected organization.

This table shows the name of each pull token, their descriptions, the date they were created, and the number of days until they expire.

You can create a new pull token by clicking the Create pull token button at the top of the page. A new pane will appear where you can enter a name for the new pull token, add an optional description, and select when the pull token will expire. The Expiration drop-down menu has options for 30, 60, and 90 days, as well as a Custom expiration option. This will cause a Custom Expiration window to appear, allowing you to select the date when you’d like the token to expire.

After entering these details, click the Create token button and your new pull token will appear in the list with the rest of your organization’s tokens.

Authenticating with GitHub Actions

You can configure authentication with OIDC-aware CI platforms like GitHub Actions.

First create an identity using chainctl, which can be limited to only allow OIDC federation from certain GitHub workflow runs:

chainctl iam identity create github [GITHUB-IDENTITY] \
  --github-repo=${GITHUB_ORG}/${GITHUB_REPO} \
  --github-ref=refs/heads/main \
  --role=registry.pull

Note: The value passed to --github-repo should be equal to the repository name you expect to be returned in the subject field of the token from GitHub. If you need to further scope or change the subject you can find a number of useful examples in the “Example subject claims” section of GitHub’s OIDC documentation and then you may update the identity with chainctl iam identities update.

This creates a Chainguard identity that can be assumed by a GitHub Actions workflow only for the specified GitHub repository, triggered on pushes to the specified branch (such as refs/heads/main), with permissions only to pull from Chainguard’s registry.

When this identity is created, its ID will be displayed. Using this ID, you can configure your GitHub Actions workflow to install chainctl and assume this identity when the workflow runs:

name: Registry Example

on:
  push:
	branches: ['main']

permissions:
  contents: read
  id-token: write  # This is needed for OIDC federation.

jobs:
  example:
	runs-on: ubuntu-latest
	steps:
  	- uses: chainguard-dev/setup-chainctl@main
    	with:
      	identity: [[ The Chainguard Identity ID you created above ]]
  	- run: docker pull cgr.dev/chainguard/node

Pulls authenticated in this way are associated with the Chainguard identity you created, which is associated with the organization selected when the identity was created.

If the identity is configured to only work with GitHub Actions workflow runs from a given repo and branch, that identity will not be able to pull from other repos or branches, including pull requests targeting the specified branch.

Authenticating with CircleCI OIDC Token

You can configure authentication with OIDC-aware CircleCI platform.

First, use chainctl to create an assumed identity. This example uses a CircleCI ID of 1234 and will work for all projects in that organization. Replace 1234 with your identity issuer org. Modify the subject pattern regex to reduce the scope to specific repos in the organization.

chainctl iam identities create circleci-identity
--identity-issuer="https://oidc.circleci.com/org/1234"
--subject-pattern="org/1234/project/.+$"
--role=registry.pull
--parent=$ORGANIZATION

Use the identity created in the above command, shown here in the third run section as 5678, to configure your workflow to install chainctl and assume this identity when the workflow runs:

version: 2.1

jobs:
  install-and-authenticate:
    machine: true
    environment:
      CHAINCTL_TOKEN_FILE: "/tmp/oidc_token"

  steps:
    - checkout

    - run:
          name: Download chainctl
          command: |
            curl -o chainctl "https://dl.enforce.dev/chainctl/latest/chainctl_$(uname -s | tr '[:upper:]' '[:lower:]')_$(uname -m | sed 's/aarch64/arm64/')"

    - run:
        name: Install chainctl
        command: |
          sudo install -o $UID -g $(id -g) -m 0755 chainctl /usr/local/bin/

    - run:
        name: Configure Docker auth
        command: |
          sudo chainctl auth configure-docker --identity-token="$CIRCLE_OIDC_TOKEN" --identity "5678"

    - run:
        name: Pull Docker image
        command: |
          sudo docker pull cgr.dev/cgr-demo.com/python:latest

workflows:
  version: 2
  chainctl-workflow:
    jobs:
      - install-and-authenticate  

See the CircleCI documentation to learn more about using OpenID Connect tokens in CircleCI jobs.

Authenticating with Microsoft Entra ID OIDC Token

You can configure authentication with OIDC using Microsoft Entra ID (formerly Azure Active Directory).

To acquire an OIDC ID token in Entra, you must complete an OAuth 2.0/OIDC flow. Entra issues access tokens (for authorization) and ID tokens (for authentication) as separate but related JWTs or JSON Web Tokens. Access tokens grant API access, while ID tokens prove user identity.

If you use the implicit or hybrid flows in Entra ID, enable ID tokens (used for implicit and hybrid flows) for your application. This can be found under Authentication → Implicit grant and hybrid flows. Then, configure a redirect URI as described in Enable ID tokens.

If you use the authorization code flow (recommended), request the openid scope to receive an ID token; you don’t need to select any of the portal checkboxes. Then, authenticate a user and request an ID token.

NOTE: For CI workloads, Microsoft’s workload identity federation (federated identity credentials) exchanges your CI’s OIDC token for an access token to a resource; it does not issue ID tokens. If you need a non-interactive OIDC ID token for Chainguard, you will have an easier time using your CI provider’s native OIDC issuer directly with Chainguard, or you need to run an interactive user flow (for example, device code) to obtain an ID token.

Retrieve and save an ID token as a local environment variable. The following examples use MS_ENTRA_ID_OIDC_TOKEN.

Next, use chainctl to create an assumed identity. Replace {tenant} with your Entra ID tenant ID (GUID). Modify the subject pattern regular expression to reduce access from all users from that issuer to a more appropriate scope for your needs.

chainctl iam identities create entraid-identity \
  --identity-issuer="https://login.microsoftonline.com/{tenant}/v2.0" \
  --subject-pattern="^.+$" \ # matches all users from this issuer, adjust to restrict access
  --role=registry.pull \
  --parent="$ORGANIZATION"

Use the identity created in the above command, shown here in the third run section as entraid-identity, to configure your workflow to install chainctl and assume this identity when the workflow runs:

version: 2.1

jobs:
  install-and-authenticate:
    machine: true

  steps:
    - checkout

    - run:
          name: Download chainctl
          command: |
            curl -o chainctl "https://dl.enforce.dev/chainctl/latest/chainctl_$(uname -s | tr '[:upper:]' '[:lower:]')_$(uname -m | sed 's/aarch64/arm64/')"

    - run:
        name: Install chainctl
        command: |
          sudo install -o $UID -g $(id -g) -m 0755 chainctl /usr/local/bin/

    - run:
        name: Configure Docker auth
        command: |
          sudo chainctl auth configure-docker --identity-token="$MS_ENTRA_ID_OIDC_TOKEN" --identity "entraid-identity"

    - run:
        name: Pull Docker image
        command: |
          sudo docker pull cgr.dev/cgr-demo.com/python:latest

workflows:
  version: 2
  chainctl-workflow:
    jobs:
      - install-and-authenticate  

Refer to the Microsoft documentation to learn more about using OpenID Connect tokens on the Microsoft Entra ID platform. Of special note is their warning about reading and validating their tokens:

Don’t attempt to validate or read tokens for any API you don’t own, including the tokens in this example, in your code. Tokens for Microsoft services can use a special format that will not validate as a JWT, and may also be encrypted for consumer (Microsoft account) users. While reading tokens is a useful debugging and learning tool, do not take dependencies on this in your code or assume specifics about tokens that aren’t for an API you control.

Chainguard does not require you to parse or validate the Microsoft-issued token yourself. Instead, just pass the token to chainctl as shown above.

Authenticating with Kubernetes

You can also configure a Kubernetes cluster to use a pull token, as described above.

When you create a pull token with --save, your Docker config file is updated to include that token and configure it to be used when pulling images from cgr.dev.

After that, you can create a Kubernetes secret based on those credentials, following these instructions:

kubectl create secret generic regcred \
	--from-file=.dockerconfigjson=<path/to/.docker/config.json> \
	--type=kubernetes.io/dockerconfigjson

Important Note: this will also make any other credentials you have configured in your Docker config available in the secret. Ensure only the necessary credentials are included.

Then you can create a Pod that uses that secret, following these instructions:

apiVersion: v1
kind: Pod
metadata:
  name: cgr-example
spec:
  containers:
  - name: nginx
	image: cgr.dev/chainguard/nginx:latest
  imagePullSecrets:
  - name: regcred

For this example, save the file as cgr-example.yaml. Then you can create and get the Pod:

kubectl apply -f cgr-example.yaml
kubectl get pod cgr-example

Learn more in our sign in guidance.

Last updated: 2025-08-11 15:22