Authentication

OpenID Connect

Glossary

TermDescription
OpenID TokenA JWT token with a specified format that Cloudsmith receives from an OIDC provider which we use to enable users to authenticate as a service account
OpenID Connect (OIDC) ProviderThe OIDC Token provider (GitHub Actions, CircleCI, etc)
ClaimsContained within the payload of the OpenID Token, used to verify the authenticity and restrict access of specific Provider requests to specific service accounts
ACCOUNTYour Cloudsmith Organization slug/identifier

How OIDC works with an OIDC identity provider and Cloudsmith

The following diagram gives an overview of how an OIDC provider integrates with your workflows and Cloudsmith.

  • Auth Server: OIDC provider
  • Client: Service requesting authentication
  • Implicit trust between Service and Auth Server is necessary to allow seamless OIDC token exchange and verification e.g. GitHub Actions OIDC Server (Auth Server) and its GitHub Actions Public Workers (Client).
  • Cloudsmith creates an OIDC trust relationship between a Cloudsmith service account and a Client that needs access to Cloudsmith.

OIDC flow

  1. Request token: The client initiates the workflow by requesting a token from the auth service to authenticate with Cloudsmith.
  2. Return token: The auth service receives the token request. After verification and validation, it generates a JWT token. The auth service and the client have implicit trust, allowing for this token exchange.
  3. Present token: The client presents a JWT token to Cloudsmith for access to resources.
  4. Verify token: Cloudsmith verifies the JWT token with the auth service to ensure its authenticity and validity. This step includes verifying claims.
  5. Return new token: Upon successful validation, Cloudsmith issues a short-lived access token to the client, granting access to Cloudsmith's resources for around 90 minutes to cover the duration of the job.

OIDC settings

OIDC Provider Settings for your organization are configured at:

https://app.cloudsmith.com/{ACCOUNT}/settings/authentication/openid

You must have the Manager or Owner role in your Cloudsmith organization to configure OIDC Provider Settings.

Note

OIDC Provider Settings can only be configured if there's at least one Service Account in your organization

Click "Create Provider Settings" to open the Create Provider Settings form:

To configure a provider, you must provide:

FieldDescription
Provider NameA Unique name for the provider
Provider URLA Provider URL. This is unique to each provider, for example for Github Actions it is: https://token.actions.githubusercontent.com Note: this needs to be the root URL i.e. it has the .well-known/openid-configuration portion of the URL removed.

This provides the configuration for the chosen provider; we use this to verify the provider signed the OpenID Token we received
Required OpenID token claimsThe required claims must be in the received OpenID Token's payload to authenticate successfully.

For example, tokens from CircleCI could specify the oidc.circleci.com/vcs-origin value, which would allow users to limit requests from a specific version control source repository to allow access to specified Cloudsmith Service Account(s).

We strongly encourage people to set at least one claim, as some providers share signing keys across all orgs, meaning that without any configured claims, any OIDC request from that provider could authenticate if they knew the service account(s) to target.

You can add a wildcard (.*) at the start of a claim value, at the end, or both. For example, .*@my-project.iam.gserviceaccount.com matches every email address in that domain. A wildcard in the middle of a value, or a value that contains only wildcards, is not supported.
Service accountsThe service accounts that the user wants to be able to authenticate as with the configured provider & claims combination

Changes will be applied immediately.

Note

If you need a single provider configuration to authenticate as many different service accounts based on a claim value, see Dynamic OIDC Mapping.

Provider documentation

Bitbucket Pipelines

Bitbucket Documentation

Bitbucket Request Example

  • Provider configuration:
    • Provider URL:
      https://api.bitbucket.org/2.0/workspaces/<ORG-NAME>/pipelines-config/identity/oidc
    • BITBUCKET REQUIRES CLAIMS TO BE PASSED (IT CANNOT BE EMPTY)
      • Navigate to:
        https://bitbucket.org/<ORG-NAME>/<REPO-NAME>/admin/pipelines/openid-connect
        Copy Audience and Identity provider URL and insert below
        • Create a claim with the following:
          {
              "aud": "ari:cloud:bitbucket::workspace/XXXX-XXXXX-XXXX-XXXXX-XXXX",
              "iss": "https://api.bitbucket.org/2.0/workspaces/ORG-NAME/pipelines-config/identity/oidc"
          }

Buildkite

Buildkite Documentation

  • Provider URL:
    https://agent.buildkite.com
  • Buildkite signs tokens for all Buildkite organizations with the same keys, and the CLI requests the cloudsmith audience by default. Add an organization_slug claim so that only jobs from your Buildkite organization can authenticate. To limit access further, add a pipeline_slug claim.
  • See Integrating Buildkite for a pipeline example.

CircleCI

CircleCI Documentation

CircleCI Request Example

  • Provider URLs are unique per organization, the format is:
    https://oidc.circleci.com/org/<organization_id>

GitHub Actions

GitHub Actions Documentation

GitHub Actions Request Example

  • There is an extra step to generate an OpenID Token compared to CircleCI - this needs to be done before sending the token to us.
  • Because the keys used to verify the token are shared across all GitHub Actions for all organizations, at least one claim verification is strongly encouraged so that only jobs from your GitHub organization can authenticate. If only one claim is being configured, then the audience claim (aud) is probably best for this as it scopes it to your GitHub organization's requests.
  • See Setup GitHub Actions to authenticate to Cloudsmith using OIDC for a step-by-step guide.

GitLab

GitLab Documentation

GitLab Request Example

  • Provider URL defaults to:
    • https://gitlab.com
      • If you have a custom domain, the format would remain the same: https://<CUSTOM-GITLAB-DOMAIN>

Google Cloud

Google Cloud Documentation

  • Provider URL:
    https://accounts.google.com
  • Google signs ID tokens for all Google Cloud projects with the same keys, and the CLI requests the cloudsmith audience by default. Add claims that match only your own service accounts:
    • One service account: Add a sub claim set to the numeric unique ID of the service account. To get the unique ID, run:
      shell
      gcloud iam service-accounts describe SERVICE_ACCOUNT_EMAIL --format='value(uniqueId)'
    • All user-managed service accounts in a project: Add an email claim with a wildcard at the start, such as .*@PROJECT_ID.iam.gserviceaccount.com. Keep the project ID in the value. A broader value, such as .*@developer.gserviceaccount.com, also matches service accounts in other Google Cloud projects.
  • Default service accounts, such as PROJECT_NUMBER@cloudbuild.gserviceaccount.com and PROJECT_NUMBER-compute@developer.gserviceaccount.com, do not match the project wildcard. Use a sub claim for these accounts.
  • See Google Cloud in the CLI documentation for the supported credential types.

Jenkins

Jenkins Documentation

  • See Setup Jenkins to authenticate to Cloudsmith using OIDC for a step-by-step guide.

  • The provider URL will be the root URL of your Jenkins master. So if you access Jenkins at https://jenkins.<organization_id>.com, then your OIDC provider URL is https://jenkins.<organization_id>.com.

OIDC requests

With the settings configured, you can now have requests from your provider to use your Cloudsmith organization's OIDC endpoint to exchange the OpenID Token for a JWT token to authenticate with all Cloudsmith API endpoints.

Token exchange

To receive the Cloudsmith JWT token, you need to make a POST request to our OpenID endpoint. This POST request must have a body of oidc_token, with the OpenID Token as its value and service_slug as the slug of the service account the request wants to attempt to authenticate as.

The OIDC Endpoint for your Cloudsmith organization will be:
https://api.cloudsmith.io/openid/{ACCOUNT}/

If unsuccessful, the error message is designed to be generic so that it does not leak information (such as whether OIDC is configured, which claim failed, whether a service account is associated with the provider, etc.).

Cloudsmith CLI auto-discovery

The Cloudsmith CLI performs this token exchange automatically in supported CI environments. Set the CLOUDSMITH_WORKSPACE and CLOUDSMITH_SERVICE_SLUG environment variables, and the CLI discovers the CI provider's OIDC token and exchanges it on its first authenticated command. The CLI also accepts CLOUDSMITH_ORG in place of CLOUDSMITH_WORKSPACE. The GitHub Actions, Azure DevOps, and CircleCI integrations set these variables from their inputs. In Buildkite, the CLI requests the job's OIDC token from the Buildkite agent. For each supported environment, see Automatically discover OIDC credentials.

Examples:

Bitbucket Pipelines example

yaml
image: atlassian/default-image:3

pipelines:
  default:
    - step:
        name: Cloudsmith OIDC Authentication
        oidc: true  # Enable OIDC for this step
        script:
          # Define variables
          - CLOUDSMITH_ORG="YOUR-ORG"         # Replace with your Cloudsmith organization
          - SERVICE_SLUG="SERVICE-ACCOUNT-SLUG"                    # Replace with your Cloudsmith service slug


          # Install required utilities
          - apt-get update && apt-get install -y curl jq

          # Exchange Bitbucket OIDC token for Cloudsmith token and capture the response
          - |
            OIDC_RESPONSE=$(curl -s -X POST -H "Content-Type: application/json" \
            -d "{\"oidc_token\":\"$BITBUCKET_STEP_OIDC_TOKEN\", \"service_slug\":\"${SERVICE_SLUG}\"}" \
            "https://api.cloudsmith.io/openid/${CLOUDSMITH_ORG}/")
          - |
            echo "OIDC Response: $OIDC_RESPONSE"

          # Extract the Cloudsmith token from the response
          - |
            CLOUDSMITH_TOKEN=$(echo "$OIDC_RESPONSE" | jq -r '.token')

          # Authenticate with Cloudsmith API
          - |
            curl --request GET \
            --url "https://api.cloudsmith.io/user/self/" \
            --header "X-Api-Key: Bearer ${CLOUDSMITH_TOKEN}" \
            --header "accept: application/json"

          # Output the obtained Cloudsmith token
          - |
            echo "Cloudsmith Token: ${CLOUDSMITH_TOKEN}"

CircleCI example

Using the Cloudsmith CircleCI orb, the install-cli command installs the standalone Cloudsmith CLI and the configure-oidc command exports the service account context the CLI needs. The CLI exchanges the CircleCI OIDC token on its first authenticated command:

yaml
version: 2.1

orbs:
  cloudsmith: cloudsmith/cloudsmith@3.0.0

workflows:
  cloudsmith_oidc_publish:
    jobs:
      - publish:
          context: my-context

jobs:
  publish:
    executor: cloudsmith/default
    steps:
      - checkout
      - cloudsmith/install-cli
      - cloudsmith/configure-oidc:
          organization: my-org
          service-account: my-service-account
      - run:
          name: Publish package
          command: cloudsmith push raw my-org/my-repo dist/app.tar.gz

The job must use at least one CircleCI context so CircleCI issues an OIDC token. Set verify-auth: true on configure-oidc to run cloudsmith whoami during setup and fail early if authentication is not configured correctly. See Integrating CircleCI for further details.

GitHub Actions example

yaml
name: OpenID Connect Demo
run-name: ${{ github.actor }} is testing out GitHub Actions with OpenID Connect 🚀
on: [push]

permissions:
  id-token: write # Required for OIDC authentication
  contents: read # Required for actions/checkout

jobs:
  test-openid-connect:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Set up Cloudsmith CLI with OIDC
        uses: cloudsmith-io/cloudsmith-cli-action@v3
        with:
          oidc-namespace: 'your-oidc-workspace' # Replace with your Cloudsmith workspace
          oidc-service-slug: 'your-service-account-slug' # Replace with the slug of your Cloudsmith service account

      - name: Verify authentication
        run: cloudsmith whoami

For further details on configuring Github Actions for OIDC see the guide here or review the documentation of the Cloudsmith CLI GitHub Action.

GitLab example

This example installs the standalone Cloudsmith CLI using the install script. GitLab exposes the OIDC token as CLOUDSMITH_OIDC_TOKEN, which the CLI discovers and exchanges automatically.

yaml
variables:
  CLOUDSMITH_ORG: "YOUR-WORKSPACE-SLUG"
  CLOUDSMITH_SERVICE_SLUG: "YOUR-SERVICE-ACCOUNT-SLUG"

stages:
  - setup

install_cloudsmith_cli:
  stage: setup
  image: ubuntu:24.04
  id_tokens:
    CLOUDSMITH_OIDC_TOKEN:
      aud: "https://api.cloudsmith.io/openid/${CLOUDSMITH_ORG}/"
  script:
    # Install the tools required to run the installer
    - apt-get update && apt-get install -y curl ca-certificates

    # Install the standalone Cloudsmith CLI
    - install_output="$(curl -fsSL https://install.cloudsmith.com/raw/versions/latest/cli.sh | sh -s -- --version 1.20.1)"
    - bin_dir="$(printf '%s\n' "$install_output" | sed -n 's/^bin_dir=//p')"
    - export PATH="$bin_dir:$PATH"

    # Verify that the CLI discovers the GitLab token and authenticates
    - cloudsmith whoami

Using the JWT

The JWT token generated by the OIDC endpoint can be used as an API key:
X-Api-Key header: "X-Api-Key: Bearer OIDC_TOKEN"

This token is active for 2 hours from the time of creation.

This token works with all Cloudsmith API endpoints to manage resources and format-specific endpoints, e.g., The Ruby endpoint to get all available packages.

This token will also work with the Command-Line Interface when specified as CLOUDSMITH_API_KEY.