mirror of
https://github.com/docker/docs.git
synced 2026-11-04 10:01:00 +00:00
docs: add OIDC connections troubleshooting and clarify rulesets (#26276)
adding troubleshooting, failure UI, examples for rulesets --------- Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
547efd2d03
commit
db384a4bd8
4 files changed
+321
-58
No files matched your search
@@ -20,7 +20,7 @@ vendor that can grant fine-grained access to your Docker resources.
|
||||
|
||||
OIDC connections follow the OpenID Connect (OIDC) standard. Establishing a
|
||||
trust relationship involves creating the connection, configuring a
|
||||
workflow, and testing. For example, a trust relationship between Docker and
|
||||
workflow, and testing. A connection, then, is the named trust relationship in Docker Home that workflows point to. For example, a trust relationship between Docker and
|
||||
GitHub follows these steps:
|
||||
|
||||
- GitHub issues a JWT ID token for the workflow run.
|
||||
@@ -41,3 +41,4 @@ For how OIDC connections compare to organization access tokens, see
|
||||
|
||||
- [Create an OIDC connection](/manuals/security/authentication/oidc-connections/create-manage.md)
|
||||
- [OIDC rulesets and subject claims](/manuals/security/authentication/oidc-connections/rulesets-claims.md)
|
||||
- [Troubleshoot OIDC connections](/manuals/security/authentication/oidc-connections/troubleshoot.md)
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
title: Create and manage OIDC connections
|
||||
linkTitle: Create and manage connections
|
||||
linkTitle: Create and manage
|
||||
description: Create and manage OIDC connections in Docker Home, then authenticate GitHub Actions to Docker Hub with docker/login-action and short-lived tokens
|
||||
keywords: oidc connections, create oidc connection, github actions, docker/login-action, DOCKERHUB_OIDC_CONNECTIONID, openid connect, docker hub, enterprise security, admin
|
||||
tags: [admin]
|
||||
@@ -26,8 +26,9 @@ with a short-lived token.
|
||||
1. Sign in to [Docker Home](https://app.docker.com/), select your
|
||||
organization, then go to **Identity & auth**.
|
||||
1. Select **OIDC connections**.
|
||||
1. Select **Create OIDC connection** and fill in the OIDC connection form.
|
||||
- Provide rulesets and subject claims. Other values are optional.
|
||||
1. Select **Create OIDC connection** and fill in the form.
|
||||
- **Connection name**, a **Ruleset name**, and a **Subject claim** are
|
||||
required. **Description** is optional.
|
||||
- For rulesets, subject claims, and resources, see
|
||||
[OIDC connections rulesets and subject claims](/manuals/security/authentication/oidc-connections/rulesets-claims.md).
|
||||
1. Select **Create connection**.
|
||||
@@ -73,7 +74,8 @@ connections** page.
|
||||
1. Find the row with your target connection ID.
|
||||
1. Select the action menu icon for your options.
|
||||
- **Edit** opens the **Edit OIDC connection** page where you can copy
|
||||
your connection ID, update rulesets, or view the **Failures** table.
|
||||
your connection ID, update rulesets, or open the **Failures** tab.
|
||||
See [View connection failures](#view-connection-failures).
|
||||
- **Deactivate** temporarily disables access to your GitHub workflow.
|
||||
- **Activate** restores access to your GitHub workflow.
|
||||
- **Delete** permanently deletes a connection.
|
||||
@@ -92,6 +94,51 @@ fails at the token-exchange step until you activate the connection.
|
||||
> replacement connection ID in every affected workflow before it runs
|
||||
> again.
|
||||
|
||||
## View connection failures
|
||||
|
||||
Docker records a failure when a workflow reaches the token-exchange step
|
||||
for your connection and no ruleset matches the token's claims. For GitHub
|
||||
Actions, Docker only logs the failure when the token's repository
|
||||
namespace matches a namespace in a `sub` rule on the connection. An
|
||||
unrelated repository can still receive `access denied` without a
|
||||
**Failures** row.
|
||||
|
||||
1. Sign in to [Docker Home](https://app.docker.com/), select your
|
||||
organization, then go to **Identity & auth**.
|
||||
1. Select **OIDC connections**.
|
||||
1. Find the connection, open the action menu, and select **Edit**.
|
||||
1. On the **Edit OIDC connection** page, select the **Failures** tab.
|
||||
|
||||
The **Failures** tab is view-only. It lists past failed exchanges so you
|
||||
can compare claims to rulesets. It does not run a test or accept inputs.
|
||||
|
||||
If Docker has not recorded any failures for the connection, the tab shows
|
||||
**No failures have been reported for this connection**.
|
||||
|
||||
> [!NOTE]
|
||||
> Wrong connection IDs, deactivated connections, and token problems that
|
||||
> fail before claim matching do not appear on **Failures**. See
|
||||
> [Troubleshoot OIDC connections](/manuals/security/authentication/oidc-connections/troubleshoot.md).
|
||||
|
||||
### Read a failure entry
|
||||
|
||||
Each failure row includes:
|
||||
|
||||
- The date and time of the failed exchange
|
||||
- The ruleset rule that did not match, shown as `claim = expected value`
|
||||
(for example, `sub = repo:my-org/my-repo:ref:refs/heads/main`)
|
||||
- The incoming claim value from the GitHub ID token, marked with ❌ when
|
||||
it does not match
|
||||
|
||||
To inspect every claim in the token, expand **Show all claims**. The
|
||||
expanded table lists **Incoming claim** and **Value**. Claims that failed
|
||||
validation appear with ❌.
|
||||
|
||||
Use the unmatched expected value and the incoming value together to
|
||||
decide whether to update the ruleset or the workflow that produced the
|
||||
token.
|
||||
|
||||
## Next steps
|
||||
|
||||
- [OIDC connections rulesets and subject claims](/manuals/security/authentication/oidc-connections/rulesets-claims.md)
|
||||
- [Troubleshoot OIDC connections](/manuals/security/authentication/oidc-connections/troubleshoot.md)
|
||||
@@ -1,72 +1,62 @@
|
||||
---
|
||||
title: OIDC connections rulesets and subject claims
|
||||
title: Configure OIDC rulesets and subject claims
|
||||
linkTitle: Rulesets and subject claims
|
||||
description: Configure rulesets and subject claims to control OIDC workflow access
|
||||
keywords: oidc connections, rulesets, subject claims, github actions, jwt claims, access control, wildcards, enterprise security
|
||||
description: >-
|
||||
Rulesets and subject claims control which GitHub Actions workflows can
|
||||
push images, pull images, read public repositories, and connect to Docker
|
||||
Build Cloud.
|
||||
keywords: >-
|
||||
oidc connections, rulesets, subject claims, github actions, openid connect,
|
||||
image push, image pull, docker build cloud, wildcards, access control
|
||||
tags: [admin]
|
||||
weight: 20
|
||||
toc_max: 2
|
||||
aliases:
|
||||
- /enterprise/security/oidc-connections/rulesets-claims/
|
||||
---
|
||||
|
||||
{{< summary-bar feature_name="OIDC connections" >}}
|
||||
|
||||
Rulesets and subject claims define what actions your GitHub workflows can
|
||||
take with your Docker resources. Use them to authorize GitHub workflow
|
||||
behaviors for an OIDC connection.
|
||||
Rulesets and subject claims authorize which GitHub workflows can use which
|
||||
Docker resources on an OIDC connection.
|
||||
|
||||
## Rulesets
|
||||
|
||||
A ruleset is a set of conditions that Docker evaluates against an incoming
|
||||
GitHub ID token. When a workflow triggers an OIDC exchange, Docker checks
|
||||
the token against every ruleset defined in your connection. If a ruleset's
|
||||
conditions are satisfied, Docker grants access based on the parameters set
|
||||
by that ruleset.
|
||||
When a workflow triggers an OIDC exchange, Docker checks the token's
|
||||
subject claim against every ruleset on the connection. If the subject
|
||||
claim matches, Docker grants the resources and scopes on that ruleset.
|
||||
|
||||
Each ruleset contains the following fields:
|
||||
Each ruleset has these fields:
|
||||
|
||||
- Label: A name for the ruleset.
|
||||
- Rules: One or more conditions based on OIDC token claims, such as the
|
||||
repository name, branch, or workflow path.
|
||||
- These are expressed as subject claim strings.
|
||||
- See [Subject claims](#subject-claims).
|
||||
- Resources: The Docker resources a workflow can access when the ruleset
|
||||
matches. See [Resources](#resources).
|
||||
- Scopes: The permissions granted on those resources, such as read or write
|
||||
access.
|
||||
- **Ruleset name**: A name for the ruleset.
|
||||
- **Subject claim**: One `sub` string from the GitHub ID token.
|
||||
- **Resources**: What the workflow can access.
|
||||
- **Scopes**: The access granted on those resources.
|
||||
|
||||
You can define between 1 and 5 rulesets per connection. Use multiple
|
||||
rulesets to apply different access levels across different workflows or
|
||||
branches. If more than one ruleset matches an incoming token, Docker merges
|
||||
the resources from all matching rulesets and grants access to the combined
|
||||
set.
|
||||
You can add one to five rulesets on a connection. If more than one
|
||||
ruleset matches a token, Docker grants the union of their resources and
|
||||
scopes.
|
||||
|
||||
## Subject claims
|
||||
|
||||
A subject claim is the `sub` field in a GitHub-issued JWT ID token. It
|
||||
encodes details of a workflow into a single string, identifying the
|
||||
workflow by organization, repository, branch, environment, and so on.
|
||||
encodes the workflow's organization, repository, branch, environment, and
|
||||
related details into a single string. The repository, branch, tag, pull
|
||||
request, or environment is part of that string, not a separate field.
|
||||
|
||||
Docker uses the subject claim as the primary condition when evaluating your
|
||||
ruleset rules. The default subject claim format is:
|
||||
The default format is:
|
||||
|
||||
```text
|
||||
repo:<org>/<repo>:ref:refs/heads/<branch>
|
||||
```
|
||||
|
||||
For example:
|
||||
You can use wildcards to match across repositories or branches:
|
||||
|
||||
```text
|
||||
repo:octo-org/octo-repo:ref:refs/heads/main
|
||||
```
|
||||
|
||||
The exact format varies and depends on what triggered the workflow.
|
||||
|
||||
- A branch push, pull request, tag, or environment deployment each produces
|
||||
a different `sub` value.
|
||||
- Refer to
|
||||
[GitHub's OpenID Connect reference](https://docs.github.com/en/actions/reference/security/oidc)
|
||||
for the full list of formats.
|
||||
| Pattern | Matches |
|
||||
| :--------------------------------------------- | :--------------------------------------------------- |
|
||||
| `repo:my-org/my-repo:ref:refs/heads/main` | Only the `main` branch of a specific repository |
|
||||
| `repo:my-org/*` | All repositories in the organization |
|
||||
| `repo:my-org/my-repo:ref:refs/heads/release-*` | All branches starting with `release-` |
|
||||
|
||||
> [!NOTE]
|
||||
> GitHub repositories created after July 15, 2026 use immutable
|
||||
@@ -75,23 +65,81 @@ The exact format varies and depends on what triggered the workflow.
|
||||
> [GitHub changelog](https://github.blog/changelog/2026-04-23-immutable-subject-claims-for-github-actions-oidc-tokens/)
|
||||
> for more details.
|
||||
|
||||
You can use wildcards to match across repositories or branches:
|
||||
|
||||
| Pattern | Matches |
|
||||
| :--------------------------------------------- | :---------------------------------------------- |
|
||||
| `repo:my-org/my-repo:ref:refs/heads/main` | Only the `main` branch of a specific repository |
|
||||
| `repo:my-org/*` | All repos in the organization |
|
||||
| `repo:my-org/my-repo:ref:refs/heads/release-*` | All branches starting with `release-` |
|
||||
For the full list of formats, see
|
||||
[GitHub's OpenID Connect reference](https://docs.github.com/en/actions/reference/security/oidc).
|
||||
|
||||
## Resources
|
||||
|
||||
Resources define the Docker resources a workflow can access when a ruleset
|
||||
matches. You specify resources per ruleset, alongside the scopes that
|
||||
determine the level of access granted.
|
||||
A resource is a Docker Hub repository or Docker Build Cloud builder.
|
||||
Scopes on the matching ruleset decide what the workflow can do with a defined resource.
|
||||
|
||||
Docker Hub repositories and Docker Build Cloud are supported resources.
|
||||
- A repository resource is a Docker Hub repository in your organization.
|
||||
**Image Pull** and **Image Push** apply to that repository. **Read
|
||||
public repositories** applies to public repositories.
|
||||
- A Docker Build Cloud resource uses the **Cloud Connect** scope, so the
|
||||
workflow can connect and build in Docker Build Cloud.
|
||||
|
||||
## Ruleset examples
|
||||
|
||||
The following examples are working setups you can adapt. They are not
|
||||
exhaustive, and they are not the only valid way to configure a
|
||||
connection. Use them when you decide how to allocate your five
|
||||
rulesets.
|
||||
|
||||
Start with one ruleset. Add more when different branches or permissions
|
||||
need to change independently. Each example is a complete setup on its
|
||||
own.
|
||||
|
||||
### Publish from main and use Build Cloud
|
||||
|
||||
Use one ruleset when the same workflows need several permissions and
|
||||
you want to change those permissions together.
|
||||
|
||||
| Ruleset name | Subject claim | Resources and scopes |
|
||||
| :----------- | :-------------------------------------------- | :------------------------------------------------------------------------------------------------- |
|
||||
| `main` | `repo:octo-org/octo-repo:ref:refs/heads/main` | Repository `octo-org/octo-repo` with **Image Push**, and Docker Build Cloud with **Cloud Connect** |
|
||||
|
||||
Other branches receive `access denied` unless you add another ruleset.
|
||||
|
||||
### Different access for release branches and main
|
||||
|
||||
Split into two rulesets when release work should only pull an image,
|
||||
but `main` should publish it. You can then tighten release access
|
||||
without editing the publish rule.
|
||||
|
||||
| Ruleset name | Subject claim | Resources and scopes |
|
||||
| :------------- | :------------------------------------------------- | :-------------------------------------------------- |
|
||||
| `release-pull` | `repo:octo-org/octo-repo:ref:refs/heads/release-*` | Repository `octo-org/octo-repo` with **Image Pull** |
|
||||
| `main-push` | `repo:octo-org/octo-repo:ref:refs/heads/main` | Repository `octo-org/octo-repo` with **Image Push** |
|
||||
|
||||
With this setup:
|
||||
|
||||
- Branches whose names start with `release-` can pull the image.
|
||||
- Workflows on `main` can publish the image.
|
||||
- Other branches, such as `feature-x`, receive `access denied`.
|
||||
|
||||
### Combine a broad read rule with a narrow push rule
|
||||
|
||||
Use two overlapping rulesets when every repository in the GitHub org
|
||||
should read public images, but only `main` in one repository should
|
||||
publish.
|
||||
|
||||
| Ruleset name | Subject claim | Resources and scopes |
|
||||
| :----------- | :-------------------------------------------- | :----------------------------------------------------- |
|
||||
| `main-push` | `repo:octo-org/octo-repo:ref:refs/heads/main` | Repository `octo-org/octo-repo` with **Image Push** |
|
||||
| `org-read` | `repo:octo-org/*` | Public repositories with **Read public repositories** |
|
||||
|
||||
With this setup:
|
||||
|
||||
- A workflow on `main` matches both rulesets, so it can publish the
|
||||
image and read public repositories.
|
||||
- A workflow on any other branch or repository in `octo-org` matches
|
||||
`org-read` only, so it can read public repositories.
|
||||
- Deleting `org-read` removes the shared read permission and leaves the
|
||||
publish rule unchanged.
|
||||
|
||||
## Next steps
|
||||
|
||||
- [OIDC connections overview](/manuals/security/authentication/oidc-connections/_index.md)
|
||||
- [Create or manage OIDC connections](/manuals/security/authentication/oidc-connections/create-manage.md)
|
||||
- [Troubleshoot OIDC connections](/manuals/security/authentication/oidc-connections/troubleshoot.md)
|
||||
@@ -0,0 +1,167 @@
|
||||
---
|
||||
title: Troubleshoot OIDC connections
|
||||
linkTitle: Troubleshoot
|
||||
description: >-
|
||||
Troubleshoot common OIDC connection token-exchange errors with GitHub
|
||||
Actions
|
||||
weight: 30
|
||||
keywords: >-
|
||||
oidc troubleshooting, oidc connection errors, Failures tab, github actions
|
||||
oidc, subject claims, rulesets, docker login-action,
|
||||
DOCKERHUB_OIDC_CONNECTIONID, access denied, connection_id is invalid,
|
||||
subject_token
|
||||
tags: [Troubleshooting, admin]
|
||||
toc_max: 2
|
||||
---
|
||||
|
||||
{{< summary-bar feature_name="OIDC connections" >}}
|
||||
|
||||
OIDC connection problems can stem from mismatched rulesets, an inactive
|
||||
or incorrect connection ID, or your GitHub Actions workflow. The following
|
||||
sections describe common errors and how to resolve them.
|
||||
|
||||
To inspect failed token exchanges in Docker Home, see
|
||||
[View connection failures](/manuals/security/authentication/oidc-connections/create-manage.md#view-connection-failures).
|
||||
|
||||
## Subject claim does not match a ruleset
|
||||
|
||||
### Error message
|
||||
|
||||
In GitHub Actions, the login step fails during token exchange. Docker
|
||||
returns:
|
||||
|
||||
```text
|
||||
access denied
|
||||
```
|
||||
|
||||
When Docker records the failure, the **Failures** tab shows the expected
|
||||
subject claim next to the incoming `sub` value from GitHub. If there is
|
||||
no failure row, confirm the workflow uses the correct connection ID and
|
||||
that a ruleset `sub` pattern covers that repository's namespace. See
|
||||
[View connection failures](/manuals/security/authentication/oidc-connections/create-manage.md#view-connection-failures).
|
||||
|
||||
### Causes
|
||||
|
||||
- The workflow's repository, branch, tag, pull request, or environment
|
||||
produces a different `sub` value than the ruleset expects.
|
||||
- The ruleset uses a narrow pattern and the workflow runs from a
|
||||
different ref (for example, a feature branch instead of `main`).
|
||||
- The ruleset still uses a mutable `repo:org/repo:...` subject while the
|
||||
GitHub repository issues an immutable subject claim. See
|
||||
[Subject claims](/manuals/security/authentication/oidc-connections/rulesets-claims.md#subject-claims).
|
||||
|
||||
### Solutions
|
||||
|
||||
1. Open the connection's **Failures** tab, if a row exists, and compare
|
||||
the expected `sub` value with the incoming value marked ❌.
|
||||
1. Update the ruleset's **Subject claim** on the **Rulesets** tab so it
|
||||
matches the workflow, or use a wildcard where appropriate. See
|
||||
[Rulesets and subject claims](/manuals/security/authentication/oidc-connections/rulesets-claims.md).
|
||||
1. Select **Save connection**, then re-run the GitHub Actions workflow.
|
||||
|
||||
## Connection ID is invalid or the connection is inactive
|
||||
|
||||
### Error message
|
||||
|
||||
In GitHub Actions, the login step fails during token exchange. Docker
|
||||
returns:
|
||||
|
||||
```text
|
||||
connection_id is invalid
|
||||
```
|
||||
|
||||
If the workflow omits the connection ID entirely, Docker returns
|
||||
`connection_id is required when subject_token_type is id_token`
|
||||
instead.
|
||||
|
||||
`connection_id is invalid` also appears when the ID is malformed, does
|
||||
not exist, or the connection is deactivated or deleted. Deactivated and
|
||||
deleted connections are not available for token exchange, so Docker
|
||||
treats the ID as invalid.
|
||||
|
||||
This failure does not add a row on the **Failures** tab.
|
||||
|
||||
### Causes
|
||||
|
||||
- `DOCKERHUB_OIDC_CONNECTIONID` is missing from the workflow, or its
|
||||
value does not match the connection ID shown in Docker Home.
|
||||
- The connection was deactivated from the **OIDC connections** action
|
||||
menu. Inactive connections use the same invalid-ID error as unknown
|
||||
IDs.
|
||||
- The connection was deleted and the workflow still references the old
|
||||
ID.
|
||||
|
||||
### Solutions
|
||||
|
||||
1. In Docker Home, open **OIDC connections** and confirm the connection
|
||||
status.
|
||||
1. If the connection is inactive, open the action menu and select
|
||||
**Activate**.
|
||||
1. If the connection was deleted, create a new connection and update
|
||||
`DOCKERHUB_OIDC_CONNECTIONID` in every affected workflow. See
|
||||
[Create and manage OIDC connections](/manuals/security/authentication/oidc-connections/create-manage.md).
|
||||
1. If the connection is active, copy the connection ID from the **Edit
|
||||
OIDC connection** page and confirm the workflow uses that exact
|
||||
value.
|
||||
|
||||
## Subject token errors
|
||||
|
||||
### Error message
|
||||
|
||||
In GitHub Actions, the login step fails before or during token exchange.
|
||||
Docker may return one of:
|
||||
|
||||
```text
|
||||
subject_token is required
|
||||
subject_token is invalid
|
||||
subject_token has expired
|
||||
subject_token audience mismatch
|
||||
subject_token issuer mismatch
|
||||
```
|
||||
|
||||
These failures do not appear on the **Failures** tab because the
|
||||
exchange fails before Docker evaluates your rulesets.
|
||||
|
||||
### Causes
|
||||
|
||||
- The workflow does not supply a GitHub OIDC ID token to the login step.
|
||||
- The token expired, is not yet valid, or does not match the expected
|
||||
issuer or audience.
|
||||
- The token cannot be verified against the provider's keys.
|
||||
|
||||
### Solutions
|
||||
|
||||
1. Confirm the job grants GitHub permission to issue an OIDC token:
|
||||
|
||||
```yaml
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
```
|
||||
|
||||
1. Use `docker/login-action` version 4.5.0 or later with your
|
||||
organization name and connection ID. See
|
||||
[Configure a GitHub Actions workflow](/manuals/security/authentication/oidc-connections/create-manage.md#configure-a-github-actions-workflow).
|
||||
1. Re-run the workflow so GitHub issues a fresh ID token.
|
||||
|
||||
## Username is not an organization
|
||||
|
||||
### Causes
|
||||
|
||||
- The `username` input to `docker/login-action` is a personal Docker Hub
|
||||
account instead of an organization name.
|
||||
- Only organization accounts can sign in with OIDC connections.
|
||||
|
||||
### Solutions
|
||||
|
||||
1. Set `username` to the Docker organization that owns the OIDC
|
||||
connection.
|
||||
1. Confirm that organization matches the one where you created the
|
||||
connection in Docker Home.
|
||||
|
||||
## Related information
|
||||
|
||||
- [Create and manage OIDC connections](/manuals/security/authentication/oidc-connections/create-manage.md)
|
||||
- [View connection failures](/manuals/security/authentication/oidc-connections/create-manage.md#view-connection-failures)
|
||||
- [OIDC rulesets and subject claims](/manuals/security/authentication/oidc-connections/rulesets-claims.md)
|
||||
- [OIDC connections overview](/manuals/security/authentication/oidc-connections/_index.md)
|
||||
Reference in new issue
Block a user