OpenID Connect
OpenID Connect (OIDC) overview
You can use Cloudsmith's support for OpenID Connect to enable short-lived authentication tokens, helping to secure your pipelines against the exposure of credentials.
Glossary
Term | Description |
---|---|
OpenID Token | A 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) Provider | The OIDC Token provider (GitHub Actions, CircleCI, etc) |
Claims | Contained within the payload of the OpenID Token, used to verify the authenticity and restrict access of specific Provider requests to specific service accounts |
ACCOUNT | Your Cloudsmith Organization slug/identifier |
How does OIDC work with an OIDC Identity Provider and Cloudsmith?
The following diagram gives an overview of how a 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 it's GithHub 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:
- Request token: The client initiates the workflow by requesting a token from the auth service to authenticate with Cloudsmith.
- 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.
- Present token: The client presents a JWT token to Cloudsmith for access to resources.
- Verify token: Cloudsmith verifies the JWT token with the auth service to ensure its authenticity and validity. This step includes verifying claims.
- 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://cloudsmith.io/orgs/{ACCOUNT}/settings/openid-connect/
You must have the Manager or Owner role in your Cloudsmith organization to configure OIDC Provider Settings.
OIDC Provider Settings can only be configured if there's at least one Service Account in your organization
Click "Create" to open the Create Provider Settings form:
To configure a provider, you must provide:
Field | Description |
---|---|
Provider Name | A Unique name for the provider |
Provider URL | A 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 removedThis provides the configuration for the chosen provider, we use this to verify the OpenID Token we received was signed by the provider |
Required OpenID Token Claims | The required claims that must be present in the received OpenID Token's payload to successfully authenticate. 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. |
Service Accounts | The service accounts that the user wants to be able to authenticate as with the configured provider & claims combination |
Changes will be applied immediately.
Provider Documentation
- Provider URLs are unique per organization, the format is:
https://oidc.circleci.com/org/<organization_id>
- 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 configure then the audience claim (
aud
) is probably best for this as that scopes it to requests from the your GitHub organization. - See Setup GitHub Actions to authenticate to Cloudsmith using OIDC for a step by step guide.
OIDC requests
With the settings configured, you can now have requests from your provider 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}/
Examples:
GitHub Actions
name: OpenID Connect Demo
run-name: ${{ github.actor }} is testing out GitHub Actions with OpenID Connect 🚀
on: [push]
permissions:
id-token: write
jobs:
test-openid-connect:
runs-on: ubuntu-latest
steps:
- run: echo "Testing out OpenID Connect in GitHub Actions."
- run: |
value=$(curl -H "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" "$ACTIONS_ID_TOKEN_REQUEST_URL&audience=api://AzureADTokenExchange" | jq '.value')
echo "$value"
jwt=$(curl -X POST -H "Content-Type: application/json" -d "{\"oidc_token\":$value, \"service_slug\":\"github-service\"}" https://api.cloudsmith.io/openid/{ACCOUNT}/ | jq -r '.token' )
echo "OIDC token from Cloudsmith: $jwt"
For further details on configuring Github Actions for OIDC see the guide at https://help.cloudsmith.io/docs/setup-cloudsmith-to-authenticate-with-oidc-in-github-actions.
CircleCI
version: 2.1
commands:
make_oidc_request:
steps:
- run: |
echo "Testing CircleCI OIDC!"
jwt=$(curl -X POST -H "Content-Type: application/json" -d "{\"oidc_token\":\"$CIRCLE_OIDC_TOKEN_V2\", \"service_slug\":\"{SERVICE_SLUG}"}" https://api.cloudsmith.io/openid/{ACCOUNT}/ | jq -r '.token')
echo "OIDC token from Cloudsmith: $jwt"
jobs:
build:
docker:
- image: cimg/base:current
steps:
- make_oidc_request
workflows:
test-workflow:
jobs:
- build:
context:
- circle-oidc-test
If successful, this will give a JWT token that can be used as an API key
If unsuccessful, you will receive an error message that is intentionally quite generic - This is by design, so that we do not leak any information (such as if OIDC is configured, which claim failed, whether a service account is associated with the provider, etc).
Additionally, as of version 1.0.6
of the Cloudsmith orb you can use the authenticate-with-oidc
command to perform this step automatically.
version: 2.1
orbs:
cloudsmith: cloudsmith/[email protected]
python: circleci/[email protected]
jobs:
publish:
executor: python/default
steps:
- checkout
- cloudsmith/authenticate-with-oidc:
organization: <your organization slug>
service-account: <service account slug>
- cloudsmith/ensure-api-key
- cloudsmith/install-cli
- run:
name: Build Python package
command: python setup.py sdist
- cloudsmith/publish:
cloudsmith-repository: <organization_slug>/<repository_slug>
package-path: dist/*.tar.gz
package-format: python
workflows:
cloudsmith_publish:
jobs:
- publish
Using the JWT
The JWT token generated by the OIDC endpoint can be used like 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, as well as 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
Updated 6 months ago