Migrate from the legacy GitHub Actions OIDC flow

5 minute read

If your GitHub Actions workflow sets EXPERIMENTAL_GITHUB_OIDC_TOKEN_AUTH=1, it is using the legacy GitHub Actions OIDC flow. That flow still works with the latest CLI but is deprecated: new pipelines should use the generic OIDC flow instead, and existing pipelines should migrate.

For the recommended, non-deprecated setup, refer to Authenticate a pipeline with OIDC.

Migrate at your own pace. CloudBees Smart Tests automatically falls back to the legacy repository-claim verification when a GitHub Actions token has no matching Trusted OIDC subject registered yet, so pipelines that still rely on a legacy repository-to-workspace association keep authenticating, whether they run the latest CLI or an older release. Upgrade the CLI to the latest version anyway: it sends an explicit signal that keeps routing deterministic and requests the correct audience for the generic flow.

The two flows compared

Aspect Legacy (deprecated) Generic (recommended)

CLI env var

EXPERIMENTAL_GITHUB_OIDC_TOKEN_AUTH=1

SMART_TESTS_GITHUB_OIDC_TOKEN_AUTH=1

What CloudBees Smart Tests matches

The repository claim on the GitHub id-token, against a repository-to-workspace association in an internal table.

The normalized sub claim (repo:OWNER/REPO) against a Trusted OIDC subject in your workspace.

How the mapping is created

CloudBees Support must associate your GitHub repository with your workspace. You cannot self-serve.

Self-service in the web app under Settings → Trusted OIDC subjects.

Workflow YAML

Requires SMART_TESTS_ORGANIZATION and SMART_TESTS_WORKSPACE (as UUIDs) in the workflow.

SMART_TESTS_ORGANIZATION and SMART_TESTS_WORKSPACE are exported by smart-tests verify --oidc, so the workflow does not hardcode them.

Audience check

Not enforced.

Enforced: the id-token must carry https://app.cloudbees.io/smart-tests in its aud claim. The CLI requests this automatically.

Status

Deprecated. Kept working for backward compatibility; will be removed in a future release.

Recommended for all new and existing pipelines.

Migrate an existing workflow to the generic flow

  1. Upgrade the CloudBees Smart Tests CLI in your workflow to the latest version (pip install --upgrade smart-tests).

  2. Run the pipeline once with smart-tests verify --oidc under the generic flow to obtain your repository’s normalized subject. You can do this in a temporary branch by replacing the legacy env var with the generic one and letting the first run fail:

    env: SMART_TESTS_GITHUB_OIDC_TOKEN_AUTH: '1' # Remove the legacy env var: # EXPERIMENTAL_GITHUB_OIDC_TOKEN_AUTH: '1' # Remove the hard-coded org/workspace, `verify --oidc` exports them: # SMART_TESTS_ORGANIZATION: "..." # SMART_TESTS_WORKSPACE: "..." permissions: id-token: write contents: read # ... steps: - run: pip install --upgrade smart-tests - run: | eval "$(smart-tests verify --oidc)" smart-tests record build --name "gh-${GITHUB_RUN_ID}"
  3. Copy the normalized-sub block from the pipeline log (it looks like repo:OWNER/REPO) and register it in the CloudBees Smart Tests web app under Settings → Trusted OIDC subjects. For more information, refer to Register the pipeline for the exact steps.

  4. Re-run the pipeline. It now succeeds under the generic flow.

  5. Once verified, remove the legacy EXPERIMENTAL_GITHUB_OIDC_TOKEN_AUTH env var and any hardcoded SMART_TESTS_ORGANIZATION / SMART_TESTS_WORKSPACE from the workflow permanently.

The legacy repository-to-workspace association in CloudBees Smart Tests’s internal database is left in place after migration, it is simply no longer consulted. You do not need to contact Support to remove it. If you want to fall back to the legacy path temporarily, put EXPERIMENTAL_GITHUB_OIDC_TOKEN_AUTH=1 back and the CLI will route through the legacy code path.

Legacy flow reference

Keep this section for existing workflows that have not yet migrated. New setups should use the generic flow instead.

Prerequisites

  • Your repository is hosted on GitHub (public or private).

  • Your CI pipeline uses GitHub Actions.

  • The latest CloudBees Smart Tests CLI is installed in your workflow. Older releases still authenticate through the automatic legacy fallback; use the latest release so routing stays explicit.

  • CloudBees Support has associated your GitHub repository with your CloudBees Smart Tests workspace. If you have not yet done so, contact CloudBees Support with your CloudBees Smart Tests organization, workspace, and GitHub owner/repo.

Tokenless authentication does not work for workflows triggered by pull requests from forked repositories. GitHub does not issue OIDC tokens in that context.

Find your organization and workspace IDs in CloudBees Unify

Organization and workspace display names are not unique and should not be used. In the legacy flow you must set the IDs (UUIDs) in the SMART_TESTS_ORGANIZATION and SMART_TESTS_WORKSPACE environment variables. Using display names can resolve to the wrong workspace and cause authentication to fail. (The generic flow avoids this entirely, verify --oidc derives the correct IDs from the registered subject.)

CloudBees Smart Tests is integrated with the CloudBees Unify, where organizations can be nested. CloudBees Smart Tests flattens this hierarchy: the top-level (root) organization maps to your CloudBees Smart Tests organization, and every sub-organization (at any nesting depth) maps to a CloudBees Smart Tests workspace under that same organization.

This means:

  • SMART_TESTS_ORGANIZATION is the top-level (root parent) organization ID in CloudBees Unify.

  • SMART_TESTS_WORKSPACE is the ID of the sub-organization whose data you want to send to CloudBees Smart Tests.

For example, given the following CloudBees Unify org hierarchy:

Stark Industries (11111111-1111-1111-1111-111111111111) <-- top-level (root) org └── Avengers (22222222-2222-2222-2222-222222222222) └── Engineering (33333333-3333-3333-3333-333333333333) └── Payments Team (44444444-4444-4444-4444-444444444444) <-- sub-org you want to use

To send data for the Payments Team sub-organization, set:

SMART_TESTS_ORGANIZATION: "11111111-1111-1111-1111-111111111111" SMART_TESTS_WORKSPACE: "44444444-4444-4444-4444-444444444444"

Where to find the IDs

Find the top-level organization ID on the Organization profile page, in the Organization ID field.

Organization profile page
Figure 1. Organization profile page showing the Organization ID

Find the sub-organization ID by selecting that sub-organization in the CloudBees platform and opening its Organization profile page.

If you need help finding the correct IDs, contact CloudBees Support.

GitHub Actions YAML configuration (legacy)

Once tokenless authentication is enabled for your project by Support, do the following:

  1. Configure environment variables in your CI pipeline:

    1. SMART_TESTS_ORGANIZATION: top-level (root) organization ID (UUID)

    2. SMART_TESTS_WORKSPACE: sub-organization ID (UUID) whose data you want to send

    3. EXPERIMENTAL_GITHUB_OIDC_TOKEN_AUTH: set this to 1

  2. Add the permissions section of your GitHub Actions YAML file.

Tokenless authentication relies on OpenID Connect (OIDC) tokens. To use an OIDC token in GitHub Actions, you need to configure permissions to retrieve it. As described in the GitHub Help Article, id-token: write permission needs to be added.

This permission can be added for one job or to the entire workflow:

name: Verify Smart Tests tokenless authentication (legacy) on: pull_request: paths: - gradle/** env: # Use your organization and workspace IDs (UUIDs), not their display names. SMART_TESTS_ORGANIZATION: "00000000-0000-0000-0000-000000000000" SMART_TESTS_WORKSPACE: "11111111-1111-1111-1111-111111111111" EXPERIMENTAL_GITHUB_OIDC_TOKEN_AUTH: '1' permissions: id-token: write contents: read jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - uses: actions/setup-python@v5 with: python-version: '3.13' - name: Set up JDK 1.8 uses: actions/setup-java@v4 with: distribution: temurin java-version: 8 - name: {PRODUCT} run: | pip install --user --upgrade smart-tests export PATH=~/.local/bin:$PATH smart-tests verify working-directory: ./gradle

Frequently Asked Questions

What is included in the OIDC token?

GitHub provides a detailed explanation and example of the OIDC token. For more information, refer to Understanding the OIDC token.

How does CloudBees Smart Tests verify the OIDC token?

In the generic flow (recommended), the CLI presents a GitHub id-token that has https://app.cloudbees.io/smart-tests as its aud. CloudBees Smart Tests verifies the signature against GitHub’s public JWKS and checks that the normalized sub (repo:OWNER/REPO) is registered as a Trusted OIDC subject in your workspace.

In the legacy flow, when you apply for tokenless authentication we associate your GitHub repository with your CloudBees Smart Tests workspace in an internal database. When you run the CLI, the CloudBees Smart Tests API server verifies the OIDC token and checks that the repository claim in it matches the stored association.

Why is the legacy flow being deprecated?

Two reasons:

  • The generic flow is fully self-service, no Support ticket is required to onboard a new repository.

  • One authentication code path covers every CI provider, which reduces the surface for bugs and makes it easier to reason about audit trails and revocation.

I have an older CLI in my workflow. What happens?

The pipeline keeps authenticating. An older CLI does not send the GitHub-OIDC-Legacy header, so its token takes the generic path on the server, but CloudBees Smart Tests automatically falls back to the legacy repository-claim verification for a workspace that still has a legacy repository association and no registered Trusted OIDC subject. Upgrade to the latest CLI anyway so routing is explicit and the correct audience is requested, then migrate to the generic flow as described above.