Developer Tools

Command-Line Interface

The Cloudsmith Command Line Interface (CLI) is a Py2/Py3 text-based interface to the API. This allows users, machines and other services to access and integrate smoothly with Cloudsmith without requiring explicit plugins or tools.

Installation

You can install or deploy the latest CLI application from:

Installing with pip

The easiest way is to use pip, such as:

shell
pip install --upgrade cloudsmith-cli

Or you can get the latest pre-release version from Cloudsmith:

shell
pip install --upgrade cloudsmith-cli --extra-index-url=https://dl.cloudsmith.io/public/cloudsmith/cli/python/index/

Installing with zipapp

Distributing Python applications can be challenging because, as an interpreted language, Python requires an interpreter to run code, unlike compiled languages that produce standalone executables. However, for smaller, pure-Python programs, a Python Zip application offers a straightforward solution for bundling and sharing your work. This method packages all the necessary code into a single ZIP file.

Requirements

python3 required to use this installation method.

bash
# download latest release and make it executable
curl -s https://api.github.com/repos/cloudsmith-io/cloudsmith-cli/releases/latest | sed -n 's/"browser_download_url": //p' | xargs wget -qO cloudsmith.pyz
chmod +x ./cloudsmith.pyz
# move it into your $PATH
sudo mv ./cloudsmith.pyz /usr/local/bin/cloudsmith

You are ready to use it:

bash
cloudsmith -h

Installing with Homebrew Tap

Homebrew is a package manager that can be installed and used in different operative systems (MacOS, Linux, and also Windows). To install the Cloudsmith CLI with Brew, add the tap first:

bash
brew tap cloudsmith-io/cloudsmith-cli

Then, install it with:

bash
brew install cloudsmith-cli

And you should be able to start using it. If you need to upgrade:

bash
brew upgrade cloudsmith-cli

For issues with the tap, please open a GitHub issue or contact support@cloudsmith.com.

Deploying the CLI containerized

Cloudsmith maintains a Docker image for the Cloudsmith CLI⁠ built for use in CI/CD pipelines and automation environments.

To deploy it, replace the API_TOKEN with the API Token associated to the service account you want to use, specifying the Cloudsmith CLI command you want to use. For example, you can run cloudsmith whoami:

bash
docker run --rm \
-e CLOUDSMITH_API_KEY=API_TOKEN \
cloudsmith/cloudsmith-cli:1.8.3 \
whoami

Successful execution of the command above will return the member or service account associated to the API Token used:

text
Retrieving your authentication status from the API ... OK
You are authenticated as:
M. Bolton (slug: mbolton, email: mbolton@initech.com)

For example, you can use the Cloudsmith CLI container to push a python package to your workspace/repository WORKSPACE/REPOSITORY. In this example, the python package PACKAGE.whl is located in /path_to_package/, and the package is being mounted in the container filesystem in /tmp/ as my_package.whl:

bash
docker run --rm \
-e CLOUDSMITH_API_KEY=API_TOKEN \
-v "/path_to_package/PACKAGE.whl:/tmp/my_package.whl" \
cloudsmith/cloudsmith-cli:1.8.3 \
push python WORKSPACE/REPOSITORY /tmp/my_package.whl 

Successful execution of the command will return:

text
Checking python package upload parameters ... OK
Checking PACKAGE.whl file upload parameters ... OK
Requesting file upload for PACKAGE.whl ... OK
Uploading PACKAGE.whl:
Creating a new python package ... OK
Created: WORKSPACE/REPOSITORY/PACKAGEwhl (package_slug)

Synchronising PACKAGEwhl:

Package synchronised successfully in 6.001236 second(s)!

Getting your API Key

You'll need to authenticate Cloudsmith for any CLI actions that result in accessing private data or changing resources (such as pushing a new package to a repository). There are two ways to retrieve your API Key:

1. Via the Cloudsmith web app

Go to the API Key page in your user settings to view the API Key.

2. via the Cloudsmith CLI

You can retrieve your API key using the cloudsmith login command:

bash
cloudsmith login
Login: you@example.com
Password: PASSWORD
Repeat for confirmation: PASSWORD

Use email for login

Please ensure you use your email for the 'Login' prompt and not your user slug/identifier.

The resulting output is:

Retrieving API token for 'you@example.com' ... OK
Your API token is: 1234567890abcdef1234567890abcdef

Once you have your API key, you can put it in your credentials.ini file, use it as an environment variable export CLOUDSMITH_API_KEY=<YOUR_API_KEY>, or pass it to the CLI using the -k <YOUR_API_KEY> flag.

For convenience, the CLI will ask you if you want to install the default configuration files, complete with your API key, if they don't already exist. Enter y or yes to create the configuration files.

If the configuration files already exist, you'll have to put the API key into the configuration files manually, but the CLI will print out their locations.

SAML Single Sign On Users

SSO Users do not have a Cloudsmith password and cannot use the cloudsmith logincommand to retrieve their API-Key.

SSO Users should instead use the cloudsmith authcommand and pass their workspace identifier like:
cloudsmith auth -o my-workspace

You will then be prompted to complete the SSO login process via your web browser (if not already signed in), and 2FA if applicable. Once authentication is complete, the CLI is issued an access token for your account.

To authenticate in environments without a web browser, such as a remote terminal session, set the CLOUDSMITH_API_KEY environment variable. You can set it for your current session like this:

bash
📘 export CLOUDSMITH_API_KEY="your-api-key-here"

Configuration / Setup

There are two configuration files used by the CLI:

  • config.ini: For non-credentials configuration.
  • credentials.ini: For credentials (authentication) configuration.

By default, the CLI will look for these in the following locations:

  • The current working directory.
  • A directory called cloudsmith in the OS-defined application directory. For example:

Linux

  • $HOME/.config/cloudsmith
  • $HOME/.cloudsmith

Mac OS

  • $HOME/Library/Application Support/cloudsmith
  • $HOME/.cloudsmith

Windows

  • C:\Users\<user>\AppData\Local\cloudsmith (Win7+, not roaming)
  • C:\Users\<user>\AppData\Roaming\cloudsmith (Win7+, roaming)
  • C:\Documents and Settings\<user>\Application Data\cloudsmith (WinXP, not roaming)
  • C:\Documents and Settings\<user>\Local Settings\Application Data\cloudsmith (WinXP, roaming)

config.ini

You can specify the following configuration options:

api_host: The API host to connect to.
api_proxy: The API proxy to connect through.
api_ssl_verify: Whether or not to use SSL verification for requests.
api_user_agent: The user agent to use for requests.

The default config is:

shell
# Default configuration
[default]
# The API host to connect to (default: api.cloudsmith.io).
api_host=

# The API proxy to connect through (default: None).
api_proxy=

# Whether to verify SSL connection to the API (default: True)
api_ssl_verify=true

# The user agent to use for requests (default: calculated).
api_user_agent=


# Profile-based configuration
# You can set as many additional profiles as you need to provide
# for different configuration environments (e.g. prod vs staging).
# Add your overrides in the sections and then specify one of:
#  * -P your-profile-name (as an argument)
#  * --profile your-profile-name (an an argument)
#  * CLOUDSMITH_PROFILE=your-profile-name (as an env variable)
[profile:your-profile-name]

credentials.ini

You can specify the following configuration options:

api_key: The API key for authenticating with the API.

shell
# Default configuration
[default]
# The API key for authenticating with the API.
api_key=<YOUR_API_KEY>


# Profile-based configuration
# You can set as many additional profiles as you need to provide
# for different configuration environments (e.g. prod vs staging).
# Add your overrides in the sections and then specify one of:
#  * -P your-profile-name (as an argument)
#  * --profile your-profile-name (an an argument)
#  * CLOUDSMITH_PROFILE=your-profile-name (as an env variable)
[profile:your-profile-name]

CLI Scripting

The CLI provides a powerful interface for interacting with your packages and repositories in Cloudsmith. However, some operations require additional scripting to achieve the required result. Please see the examples below:

Copying/Moving Multiple Packages

The CLI supports moving one package at a time. However, it is easy to script a solution for moving multiple packages.

The following command will list all the packages returned by YOUR-QUERY. Extract the relevant metadata and run the copy command for each.

bash
cloudsmith ls pkg YOUR-ACCOUNT/YOUR-REPO -q 'YOUR-QUERY' -F json \
  | jq '.data[] | .namespace + "/" + .repository + "/" + .slug' -r \
  | xargs -Ipackage cloudsmith copy package YOUR-DEST-REPO

Error message

The destination is not qualified by a namespace (YOUR-ACCOUNT). This is because you can only copy/move packages from repositories within the same namespace.

Note

📘 You can remove the query (YOUR-QUERY) to target all packages. The only downside to this approach is that it might require multiple invocations if you have more packages than the page size limit.

It's possible to navigate pages using -p and increase the page size limit to 500 using -l 500

Example

The following moves all Maven packages named cloudsmith-api with version 0.21.* from lskillen/test2 to lskillen/test3 (Permissions permitting obviously).

bash
cloudsmith ls pkg lskillen/test2 -q 'format:maven AND name:cloudsmith-api AND version:^0.21' -F json 
  | jq '.data[] | .namespace + "/" + .repository + "/" + .slug' -r 
  | xargs -Ipackage cloudsmith copy package test3

Waiting for a package to complete synchronizing

The wait_for_package_sync function below will wait for a package matching the provided query to either complete syncing or fail.

For example wait_for_package_sync "name:^foo$ AND version:0.0.1" would wait for a package named foo with version 0.0.1 to either successfully complete synchronization, fail or time out after 180 seconds.

The full list of available search parameters can be found in our documentation on searching and filtering.

bash
get_package_identifier() {
    local query=${1:-""}
    cloudsmith list packages --output-format json --query "$query" "$ORG/$REPOSITORY" 2> /dev/null | jq '.data[0].slug' | sed -e 's/^"//' -e 's/"$//'
}

get_package_status() {
    local identifier=${1:-""}
    cloudsmith status "$ORG/$REPOSITORY/$identifier" 2> /dev/null
}

wait_for_package_sync() {
    local query=${1:-""}
    local total_time_limit=${2:-180}
    local identifier=""
    local package_status=""
    local total_time=0
    local identifier=""
    local package_sync_complete=1
    local package_sync_failed=0
    local sleep_time=10

    while [[ $total_time -lt $total_time_limit ]]; do
        if [[ -z "$identifier" ]] || [[ "$identifier" == "null" ]]; then
            identifier=$(get_package_identifier "$query")
            if [[ -z "$identifier" ]] || [[ "$identifier" == "null" ]]; then
              echo "Waiting for package .. (query: $query)" > /dev/stderr
              total_time=$((total_time+$sleep_time))
              sleep $sleep_time
              continue
            fi
        fi

        package_status=$(get_package_status "$identifier")

        echo "$package_status" | grep --quiet 'Completed'
        package_sync_complete=$?

        echo "$package_status" | grep --quiet 'Failed'
        package_sync_failed=$?

        if [[ $package_sync_complete -eq 0 ]] || [[ $package_sync_failed -eq 0 ]]; then
            break
        fi

        echo "Waiting for package status ... (identifier: $identifier)" > /dev/stderr
        total_time=$((total_time+$sleep_time))
        sleep $sleep_time
    done

    if [[ $total_time -gt $total_time_limit ]]; then
        echo "Timed out after waiting $total_time seconds for package to sync" > /dev/stderr
        exit 1
    fi

    if [[ $package_sync_complete -ne 0 ]]; then
      echo "Package failed to sync after $total_time seconds" > /dev/stderr
      exit 1
    fi

    echo "Package synced successfully after $total_time seconds" > /dev/stderr
}

Autodiscover credentials

Autodiscover OIDC credentials

To enable autodiscovery of OpenID Connect (OIDC) credentials, set the CLOUDSMITH_ORG and CLOUDSMITH_SERVICE_SLUG environment variables. When CLOUDSMITH_ORG and CLOUDSMITH_SERVICE_SLUG are configured, the CLI automatically discovers the CI provider's OIDC token and exchanges it on its first authenticated command:

bash
export CLOUDSMITH_ORG=your-workspace
export CLOUDSMITH_SERVICE_SLUG=your-service-account
cloudsmith whoami

cloudsmith whoami exits with code 0 when authenticated and 1 when anonymous, so you can use it to verify authentication in scripts.

Important

Autodiscovery is skipped unless both CLOUDSMITH_ORG and CLOUDSMITH_SERVICE_SLUG are configured.

The CLI can automatically detect OIDC credentials for the following CI/CD platforms:

PlatformDetector ID
CircleCIcircleci
Azure DevOpsazure_devops
GitHub Actionsgithub
Bitbucket Pipelinesbitbucket
GitLab CIgitlab
Amazon Web Services (AWS)aws
Genericgeneric

Note

Generic autodiscovery is supported for custom CI/CD systems. For example, Jenkins with the credentials binding plugin.

The CLI evaluates each detector in a fixed order (circleci, azure_devops, github, bitbucket, gitlab, aws, generic) and uses the first that matches.

To override the default evaluation order, you can disable a detector or customize the evaluation order.

Disable a detector

To disable a detector:

  • By using an environment variable:

    Set the CLOUDSMITH_OIDC_<DETECTOR>_DISABLED environment variable to true. For example, to skip the AWS detector: CLOUDSMITH_OIDC_AWS_DISABLED=true.

  • By using config.ini:

    Under [default] or a [profile:<name>] section, add the detector ID to oidc_disabled_detectors. For example, to disable the AWS detector: oidc_disabled_detectors = aws

    To disable multiple detectors, provide a comma-separated list of the detectors you want to disable. For example, to disable the AWS and GitLab CI detectors: oidc_disabled_detectors = aws, gitlab.

Customize the detector evaluation order

You can customize the detector evaluation order by providing a comma-separated list of detector IDs to the CLOUDSMITH_OIDC_DETECTOR_ORDER environment variable, the --oidc-detector-order CLI option, or oidc_detector_order in config.ini.

IDs that aren't listed are skipped, and unrecognized IDs are ignored with a warning.

For example, to evaluate only the AWS and generic detectors, evaluating the generic detector first:

  • By using the --oidc-detector-order CLI option:

    --oidc-detector-order=generic,aws

  • By using an environment variable:

    Set CLOUDSMITH_OIDC_DETECTOR_ORDER=generic,aws.

  • By using config.ini:

    Under [default] or a profile section, add oidc_detector_order=generic,aws.

AWS

For AWS environments (ECS, EKS, EC2), install with aws to enable automatic credential discovery:

bash
pip install cloudsmith-cli[aws]

This installs boto3[crt] for AWS credential chain support, STS token generation, and AWS SSO compatibility.

Bitbucket Pipelines

To enable autodiscovery, set oidc: true on the pipeline step. The CLI reads the token from the BITBUCKET_STEP_OIDC_TOKEN variable that Bitbucket populates.

The Cloudsmith OIDC provider must expect the workspace audience that Bitbucket mints (ari:cloud:bitbucket::workspace/<workspace-uuid>):

Example:

yaml
pipelines:
  default:
    - step:
        oidc: true
        script:
          - cloudsmith push ...

For more information about using OIDC credentials with Bitbucket Pipelines, see the Bitbucket Integrate Pipelines with resource servers using OIDC documentation.

CircleCI

The CLI reads the token from the CIRCLE_OIDC_TOKEN_V2 (preferred) or CIRCLE_OIDC_TOKEN environment variable that CircleCI injects into every job.

The Cloudsmith OIDC provider must expect the audience that CircleCI mints, which is your CircleCI organization UUID. For more information about OIDC authentication with CircleCI, see Integrating with CircleCI.

Azure DevOps

The CLI fetches an OIDC token from the SYSTEM_OIDCREQUESTURI endpoint by using the pipeline's SYSTEM_ACCESSTOKEN. Make sure SYSTEM_ACCESSTOKEN is mapped into the step's environment.

The Cloudsmith OIDC provider must expect the api://AzureADTokenExchange audience that Azure DevOps mints (any requested audience is ignored). For more information, see the Cloudsmith Azure DevOps integration guide.

GitHub Actions

The CLI fetches an OIDC token from the Actions runtime when the workflow requests id-token: write permission. See Setup GitHub Actions to authenticate to Cloudsmith using OIDC.

GitLab CI

Configure an id_tokens entry in your .gitlab-ci.yml with an aud of https://api.cloudsmith.io/openid/<your-workspace> and expose it as CLOUDSMITH_OIDC_TOKEN:

yaml
job:
  id_tokens:
    CLOUDSMITH_OIDC_TOKEN:
      aud: https://api.cloudsmith.io/openid/<your-workspace>
  script:
    - cloudsmith push ...

The Cloudsmith CLI will pick it up automatically.

For more information about using GitLab CI/CD with Cloudsmith, see the Cloudsmith GitLab CI/CD integration guide.

Generic OIDC credential autodiscovery

Generic autodiscovery is supported as a fallback for environments without a dedicated detector (for example, Jenkins with the credentials binding plugin, or any custom CI/CD system). This detector runs last by default, so a dedicated environment is always preferred when present.

Set the CLOUDSMITH_OIDC_TOKEN environment variable to an OIDC JSON Web Token (JWT) and the CLI will exchange it for a Cloudsmith access token.

For more information about using OIDC with Jenkins, see Setup Jenkins to Authenticate to Cloudsmith using OIDC.

Autodiscover Docker credentials

v1.19.0 introduced a Docker credential helper which lets Docker discover credentials from the CLI automatically, including for custom registry domains.

Install the Docker credential helper

To install the Docker credential helper, run:

bash
cloudsmith credential-helper install docker

This installs a docker-credential-cloudsmith binary and registers it in ~/.docker/config.json (default path) for Cloudsmith registry domains. By default, custom domains are discovered automatically via the Cloudsmith API and cached.

Useful options:

OptionDescription
--domainAdd one or more extra registry hostnames to configure.

For example: cloudsmith credential-helper install docker --domain my.registry.example.com

The installer always configures the default docker.cloudsmith.io host. Hostnames are written into ~/.docker/config.json under credHelpers.
--no-discoverDisable automatic discovery of custom Cloudsmith Docker domains via the Cloudsmith API.

Discovery of custom domains is enabled by default, and the installer will attempt to find and add custom domains for the workspace.

Note

For more information about the options available for the installation command, run cloudsmith credential-helper install docker --help.

Important

If you're using custom domains, set the CLOUDSMITH_ORG (Cloudsmith workspace slug) environment variable to your Cloudsmith workspace name.

After installing the helper, docker push and docker pull commands against Cloudsmith registries authenticate with the existing CLI credentials.

Uninstall the Docker credential helper

To uninstall the Docker credential helper, run:

bash
cloudsmith credential-helper uninstall docker

Troubleshooting

When upgrading the Cloudsmith CLI, you may also need to update the Cloudsmith API using:

shell
pip install --upgrade cloudsmith-api

If using a proxy with self-signed / internal TLS Certificates, you may need to point to your custom certs with:

export REQUESTS_CA_BUNDLE=/path/to/converted/certificate.pem