Skip to main content
INS // Insights

Docker Hub OIDC Replaces Stored Tokens

Updated October 2026 · 6 min read

Docker Hub OIDC replaces the access token a workflow has been passing as a password. GitHub issues a short-lived identity token for the run. Docker exchanges it and signs the job into Docker Hub. The stored access token, personal or organization-scoped, is deleted after that path is the one the job actually uses. Teams that only add the new login and leave the secret in place have not finished. The secret is the finding.

Rutagon builds the cutover on the workflows that push and pull. The client owns the Docker organization. Rutagon builds the pipeline change and the evidence that the secret is gone. Container scanning and image policy stay the subject of container security in production CI. This article is the registry credential.

Where this cutover applies

Docker documents OIDC connections for GitHub as the trusted third party, and the same page says GitHub Enterprise Cloud and GitHub Enterprise Server are not supported. If the workflows live on either of those, we stop. We do not invent a compatible flag. The stored token stays until there is a supported identity, and the evidence says why the cutover did not proceed. Pretending the connection exists is worse than a dated exception.

The connection is created by an organization owner or editor in Docker Home, under Identity and auth, OIDC connections. Rulesets and subject claims are part of that form. The connection id is copied once and stored as configuration, not as a secret password. Docker documents the workflow side in Create and manage OIDC connections.

Only an organization account can sign in this way. The username in the login step is the Docker organization name. A personal Docker account in that field will not complete the exchange. We check the organization name before we delete anyone's access token.

The login action has to be version 4.5.0 or later. Older pins of that action still expect a password. A workflow that looks migrated and pins an older action will fail at the exchange, and someone will paste the access token back. We pin a version that meets that floor, and we read the pin in review.

Docker Hub OIDC login we put in the workflow

The job needs permission to request an identity token. The login step passes the organization name and the connection id. It does not pass a password. Docker's documented shape is the one we use:

permissions:
  contents: read
  id-token: write
steps:
  - name: Docker login
    uses: docker/login-action@v4
    with:
      username: org-name
    env:
      DOCKERHUB_OIDC_CONNECTIONID: connection-id

The environment value is the connection id copied from Docker Home. It identifies which trust relationship to use. It is not a long-lived registry password. The action exchanges the GitHub token and signs in during that step. The following build or push uses that session.

We remove the password input from the same step in the same change. Leaving both teaches the job nothing and leaves the secret for the next person to reuse. The first green run is a workflow that cannot see the old token. If the run fails, the rollback is to restore the password input from the sealed copy, not to invent a second connection in a hurry. After the green run, the sealed copy is what we delete.

Deactivate on the connection is the pause. A deactivated connection does not issue Docker access tokens, so the login fails at the exchange until it is activated again. That is the right control while we test a ruleset. Delete is permanent. Docker warns that any workflow still pointing at the deleted id fails at the exchange. We do not delete the connection to "clean up" during the week we are still moving workflows. We delete the stored access token. The connection stays.

Secrets that have to leave

The secret we remove is the access token the old step used as a password. Docker's SSO guidance tells CI to use a personal access token or an organization access token instead of a password, and it points GitHub Actions at an OIDC connection instead of a long-lived token. Both kinds of stored token are in scope if a workflow references them. Organization secrets and repository secrets both get searched. A reusable workflow in another repository is a caller we inventory before revocation.

Image pull on developer laptops is not this cutover. People should use their own login. A laptop that was using the CI token is another copy of the secret, and it is revoked when the token is revoked. We say that out loud before revocation so the outage is expected. The CI job is the system we are fixing. Personal access for engineers is individual, and it is reviewed as user access, not hidden inside the pipeline token.

Sibling work: Artifactory tokens come out through JFrog OIDC. Cloud API keys come out through GitHub Actions OIDC to AWS. The Docker Hub connection does not sign the job into a cloud account. We do not overload it to do that.

Evidence after the token is gone

The pack we file is the connection id, the organization name, the workflows that log in without a password field, and the time the stored access token was deleted from the secret store. A picture of the OIDC connections page is not enough. The workflow file is the proof the password input is gone. The secret-store audit is the proof the token value is gone. Both go into the GRC you already run.

A failed exchange after deletion is an incident with a specific cause: the connection was deactivated, the id was deleted, or the action pin is too old. The fix is on that cause. Restoring the access token as the permanent fix reopens the finding. We would rather fail the build for an hour than put the long-lived token back as the steady state.

This is pipeline work under Kubernetes and containerization when the images feed a cluster, and it is the same login change when the images only go to the registry. Rutagon's own image publish uses a short-lived exchange rather than a stored registry token. That is how we run the pipeline. It is not a certification you can cite as yours.

Frequently Asked Questions

Does Docker Hub OIDC work on GitHub Enterprise Server?

Docker's connection docs limit the trusted third party to GitHub and state that GitHub Enterprise Cloud and GitHub Enterprise Server are not supported. We do not proceed with a fake connection on those hosts. The stored token remains, with that limitation written into the evidence, until a supported identity exists.

What value goes in the username field?

The Docker organization name. Only organization accounts can complete this sign-in. A personal account name in that field is a misconfiguration, not a fallback. We verify the organization before the stored access token is removed.

When is the stored access token deleted?

After the workflow has a successful run that does not receive the token as an input. Deleting it first, with no green exchange, is how teams paste the token back during an outage. Deactivate on the connection is available if we need to pause issuance without destroying the connection id.

What is the connection id?

The identifier Docker Home shows after the OIDC connection is created. The workflow passes it in DOCKERHUB_OIDC_CONNECTIONID. It selects the trust relationship. It is not a registry password, and deleting the connection makes every workflow that still references that id fail at exchange.

What do auditors receive?

The connection id, the workflows whose login step has no password, and the deletion time of the stored access token. We file that in the GRC you already run. The login action has to be 4.5.0 or later or the exchange is not the exchange the vendor documents.

Talk to us about your credential elimination pilot. Contact Rutagon at rutagon.com/contact, 907-841-8407, or contact@rutagon.com.