cloudsmith-cli 1.28.0__tar.gz → 1.30.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (176) hide show
  1. {cloudsmith_cli-1.28.0/cloudsmith_cli.egg-info → cloudsmith_cli-1.30.0}/PKG-INFO +51 -34
  2. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/README.md +41 -27
  3. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/cli/command.py +43 -1
  4. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/cli/commands/auth.py +11 -10
  5. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/cli/commands/check.py +1 -3
  6. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/cli/commands/credential_helper/manage.py +71 -8
  7. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/cli/commands/credential_helper/terraform.py +12 -11
  8. cloudsmith_cli-1.30.0/cloudsmith_cli/cli/commands/domains.py +305 -0
  9. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/cli/commands/download.py +7 -0
  10. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/cli/commands/list_.py +25 -2
  11. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/cli/commands/login.py +76 -6
  12. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/cli/commands/logout.py +7 -7
  13. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/cli/commands/main.py +3 -0
  14. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/cli/commands/metadata.py +9 -3
  15. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/cli/commands/policy/deny.py +2 -1
  16. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/cli/commands/policy/license.py +3 -2
  17. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/cli/commands/policy/vulnerability.py +3 -3
  18. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/cli/commands/push.py +7 -4
  19. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/cli/commands/repos.py +7 -8
  20. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/cli/commands/tokens.py +20 -24
  21. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/cli/commands/update.py +2 -2
  22. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/cli/commands/upstream.py +2 -1
  23. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/cli/commands/whoami.py +7 -7
  24. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/cli/config.py +69 -9
  25. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/cli/decorators.py +122 -32
  26. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/cli/exceptions.py +16 -6
  27. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/cli/saml.py +0 -24
  28. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/cli/utils.py +3 -2
  29. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/cli/validators.py +7 -7
  30. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/cli/webserver.py +5 -4
  31. cloudsmith_cli-1.30.0/cloudsmith_cli/conftest.py +83 -0
  32. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/core/api/exceptions.py +5 -0
  33. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/core/api/files.py +20 -8
  34. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/core/api/init.py +3 -1
  35. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/core/api/metadata.py +37 -93
  36. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/core/api/orgs.py +5 -9
  37. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/core/api/packages.py +2 -0
  38. cloudsmith_cli-1.30.0/cloudsmith_cli/core/api/v2.py +96 -0
  39. cloudsmith_cli-1.30.0/cloudsmith_cli/core/api/workspaces.py +22 -0
  40. cloudsmith_cli-1.30.0/cloudsmith_cli/core/certificate_errors.py +80 -0
  41. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/core/config.py +32 -19
  42. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/core/credentials/models.py +2 -1
  43. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/core/credentials/oidc/detectors/__init__.py +4 -0
  44. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/core/credentials/oidc/detectors/aws.py +20 -2
  45. cloudsmith_cli-1.30.0/cloudsmith_cli/core/credentials/oidc/detectors/buildkite.py +54 -0
  46. cloudsmith_cli-1.30.0/cloudsmith_cli/core/credentials/oidc/detectors/gcp.py +200 -0
  47. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/core/credentials/providers/keyring_provider.py +1 -0
  48. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/core/download.py +1 -1
  49. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/core/keyring.py +8 -10
  50. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/core/mcp/server.py +6 -2
  51. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/core/ratelimits.py +1 -1
  52. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/core/session.py +101 -2
  53. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/core/sso.py +12 -12
  54. cloudsmith_cli-1.30.0/cloudsmith_cli/core/telemetry.py +841 -0
  55. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/core/update_check.py +26 -7
  56. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/core/utils.py +5 -0
  57. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/credential_helpers/cargo/installer.py +26 -27
  58. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/credential_helpers/cargo/runtime.py +4 -11
  59. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/credential_helpers/common.py +27 -3
  60. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/credential_helpers/docker/installer.py +22 -25
  61. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/credential_helpers/docker/runtime.py +3 -10
  62. cloudsmith_cli-1.30.0/cloudsmith_cli/credential_helpers/domains.py +399 -0
  63. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/credential_helpers/generic.py +4 -9
  64. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/credential_helpers/launchers.py +25 -33
  65. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/credential_helpers/pnpm/installer.py +13 -22
  66. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/credential_helpers/pnpm/rc.py +1 -2
  67. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/credential_helpers/pnpm/runtime.py +3 -10
  68. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/credential_helpers/terraform/installer.py +5 -20
  69. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/credential_helpers/terraform/runtime.py +28 -15
  70. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/credential_helpers/terraform/terraformrc.py +1 -1
  71. cloudsmith_cli-1.30.0/cloudsmith_cli/data/VERSION +1 -0
  72. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/data/config.ini +11 -5
  73. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0/cloudsmith_cli.egg-info}/PKG-INFO +51 -34
  74. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli.egg-info/SOURCES.txt +7 -2
  75. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli.egg-info/requires.txt +9 -4
  76. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/pyproject.toml +10 -8
  77. cloudsmith_cli-1.28.0/cloudsmith_cli/cli/commands/domains.py +0 -304
  78. cloudsmith_cli-1.28.0/cloudsmith_cli/conftest.py +0 -16
  79. cloudsmith_cli-1.28.0/cloudsmith_cli/credential_helpers/custom_domains.py +0 -378
  80. cloudsmith_cli-1.28.0/cloudsmith_cli/credential_helpers/default_domains.py +0 -305
  81. cloudsmith_cli-1.28.0/cloudsmith_cli/data/VERSION +0 -1
  82. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/LICENSE +0 -0
  83. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/MANIFEST.in +0 -0
  84. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/__init__.py +0 -0
  85. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/__main__.py +0 -0
  86. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/cli/__init__.py +0 -0
  87. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/cli/commands/__init__.py +0 -0
  88. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/cli/commands/copy.py +0 -0
  89. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/cli/commands/credential_helper/__init__.py +0 -0
  90. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/cli/commands/credential_helper/cargo.py +0 -0
  91. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/cli/commands/credential_helper/docker.py +0 -0
  92. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/cli/commands/credential_helper/generic.py +0 -0
  93. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/cli/commands/credential_helper/pnpm.py +0 -0
  94. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/cli/commands/delete.py +0 -0
  95. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/cli/commands/dependencies.py +0 -0
  96. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/cli/commands/docs.py +0 -0
  97. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/cli/commands/entitlements.py +0 -0
  98. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/cli/commands/help_.py +0 -0
  99. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/cli/commands/mcp.py +0 -0
  100. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/cli/commands/metrics/__init__.py +0 -0
  101. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/cli/commands/metrics/command.py +0 -0
  102. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/cli/commands/metrics/entitlements.py +0 -0
  103. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/cli/commands/metrics/packages.py +0 -0
  104. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/cli/commands/move.py +0 -0
  105. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/cli/commands/policy/__init__.py +0 -0
  106. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/cli/commands/policy/command.py +0 -0
  107. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/cli/commands/quarantine.py +0 -0
  108. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/cli/commands/quota/__init__.py +0 -0
  109. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/cli/commands/quota/command.py +0 -0
  110. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/cli/commands/quota/history.py +0 -0
  111. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/cli/commands/quota/quota.py +0 -0
  112. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/cli/commands/registry.py +0 -0
  113. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/cli/commands/resync.py +0 -0
  114. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/cli/commands/status.py +0 -0
  115. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/cli/commands/tags.py +0 -0
  116. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/cli/commands/vulnerabilities.py +0 -0
  117. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/cli/dsc_parser.py +0 -0
  118. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/cli/metadata_common.py +0 -0
  119. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/cli/table.py +0 -0
  120. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/cli/types.py +0 -0
  121. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/core/__init__.py +0 -0
  122. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/core/api/__init__.py +0 -0
  123. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/core/api/distros.py +0 -0
  124. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/core/api/entitlements.py +0 -0
  125. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/core/api/metrics.py +0 -0
  126. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/core/api/quota.py +0 -0
  127. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/core/api/rates.py +0 -0
  128. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/core/api/repos.py +0 -0
  129. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/core/api/status.py +0 -0
  130. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/core/api/upstreams.py +0 -0
  131. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/core/api/user.py +0 -0
  132. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/core/api/version.py +0 -0
  133. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/core/api/vulnerabilities.py +0 -0
  134. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/core/cache_utils.py +0 -0
  135. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/core/credentials/__init__.py +0 -0
  136. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/core/credentials/chain.py +0 -0
  137. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/core/credentials/oidc/__init__.py +0 -0
  138. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/core/credentials/oidc/cache.py +0 -0
  139. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/core/credentials/oidc/detectors/azure_devops.py +0 -0
  140. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/core/credentials/oidc/detectors/base.py +0 -0
  141. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/core/credentials/oidc/detectors/bitbucket_pipelines.py +0 -0
  142. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/core/credentials/oidc/detectors/circleci.py +0 -0
  143. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/core/credentials/oidc/detectors/generic.py +0 -0
  144. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/core/credentials/oidc/detectors/github_actions.py +0 -0
  145. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/core/credentials/oidc/detectors/gitlab_ci.py +0 -0
  146. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/core/credentials/oidc/exchange.py +0 -0
  147. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/core/credentials/provider.py +0 -0
  148. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/core/credentials/providers/__init__.py +0 -0
  149. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/core/credentials/providers/cli_flag.py +0 -0
  150. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/core/credentials/providers/credentials_file.py +0 -0
  151. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/core/credentials/providers/env_var.py +0 -0
  152. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/core/credentials/providers/oidc_provider.py +0 -0
  153. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/core/installation.py +0 -0
  154. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/core/macos_keychain.py +0 -0
  155. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/core/mcp/__init__.py +0 -0
  156. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/core/mcp/data.py +0 -0
  157. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/core/pagination.py +0 -0
  158. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/core/rest.py +0 -0
  159. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/core/self_update.py +0 -0
  160. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/core/version.py +0 -0
  161. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/credential_helpers/__init__.py +0 -0
  162. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/credential_helpers/backends.py +0 -0
  163. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/credential_helpers/cargo/__init__.py +0 -0
  164. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/credential_helpers/docker/__init__.py +0 -0
  165. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/credential_helpers/pnpm/__init__.py +0 -0
  166. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/credential_helpers/terraform/__init__.py +0 -0
  167. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/data/credentials.ini +0 -0
  168. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/templates/__init__.py +0 -0
  169. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/templates/auth_error.html +0 -0
  170. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/templates/auth_success.html +0 -0
  171. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/templates/auth_two_factor.html +0 -0
  172. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli/wrapper.py +0 -0
  173. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli.egg-info/dependency_links.txt +0 -0
  174. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli.egg-info/entry_points.txt +0 -0
  175. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/cloudsmith_cli.egg-info/top_level.txt +0 -0
  176. {cloudsmith_cli-1.28.0 → cloudsmith_cli-1.30.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cloudsmith-cli
3
- Version: 1.28.0
3
+ Version: 1.30.0
4
4
  Summary: Cloudsmith Command-Line Interface (CLI)
5
5
  Author-email: Cloudsmith Ltd <support@cloudsmith.io>
6
6
  License-Expression: Apache-2.0
@@ -12,7 +12,6 @@ Classifier: Intended Audience :: Developers
12
12
  Classifier: Intended Audience :: System Administrators
13
13
  Classifier: Operating System :: POSIX :: Linux
14
14
  Classifier: Programming Language :: Python
15
- Classifier: Programming Language :: Python :: 3.10
16
15
  Classifier: Programming Language :: Python :: 3.11
17
16
  Classifier: Programming Language :: Python :: 3.12
18
17
  Classifier: Programming Language :: Python :: 3.13
@@ -20,7 +19,7 @@ Classifier: Programming Language :: Python :: 3.14
20
19
  Classifier: Topic :: Internet
21
20
  Classifier: Topic :: System :: Systems Administration
22
21
  Classifier: Topic :: Utilities
23
- Requires-Python: >=3.10.0
22
+ Requires-Python: >=3.11.0
24
23
  Description-Content-Type: text/markdown
25
24
  License-File: LICENSE
26
25
  Requires-Dist: certifi>=2024.7.4
@@ -29,26 +28,30 @@ Requires-Dist: click-configfile>=0.2.3
29
28
  Requires-Dist: click-didyoumean>=0.0.3
30
29
  Requires-Dist: click-spinner>=0.1.7
31
30
  Requires-Dist: json5>=0.9.0
32
- Requires-Dist: cloudsmith-api<3.0,>=2.0.31
31
+ Requires-Dist: cloudsmith-api<3.0,>=2.0.38
33
32
  Requires-Dist: keyring>=25.4.1
34
33
  Requires-Dist: keyrings-alt>=5.0.2
35
34
  Requires-Dist: keyrings-cryptfile>=1.3.9
36
35
  Requires-Dist: cryptography>=50.0.0
37
- Requires-Dist: mcp==2.2.0
36
+ Requires-Dist: mcp==2.3.0
38
37
  Requires-Dist: pydantic-settings>=2.14.2
39
38
  Requires-Dist: PyJWT[crypto]>=2.13.0
40
- Requires-Dist: python-toon==0.1.3
41
- Requires-Dist: requests>=2.18.4
39
+ Requires-Dist: python-toon==0.2.0
40
+ Requires-Dist: requests>=2.32.5
42
41
  Requires-Dist: requests_toolbelt>=1.0.0
43
42
  Requires-Dist: rich>=13.0.0
44
43
  Requires-Dist: semver>=2.7.9
45
44
  Requires-Dist: starlette>=1.3.1
46
45
  Requires-Dist: urllib3>=2.5
47
46
  Requires-Dist: tomlkit>=0.15.0
47
+ Requires-Dist: sentry-sdk<3,>=2
48
48
  Provides-Extra: aws
49
49
  Requires-Dist: boto3[crt]>=1.26.0; extra == "aws"
50
+ Provides-Extra: gcp
51
+ Requires-Dist: google-auth>=2.40.0; extra == "gcp"
50
52
  Provides-Extra: all
51
53
  Requires-Dist: boto3[crt]>=1.26.0; extra == "all"
54
+ Requires-Dist: google-auth>=2.40.0; extra == "all"
52
55
  Dynamic: license-file
53
56
 
54
57
  # Cloudsmith Command Line Interface (CLI)
@@ -100,8 +103,8 @@ The CLI currently supports the following commands (and sub-commands):
100
103
  - `entitlements`|`ents`: List entitlements for a repository.
101
104
  - `packages`: List packages for a repository. (Aliases `repos list`)
102
105
  - `repos`: List repositories for a namespace (owner).
103
- - `login`|`token`: Retrieve your API authentication token/key via login.
104
- - `logout`: Clear stored authentication credentials and SSO tokens (Keyring, API key from credential file and emit warning when `$CLOUDSMITH_API_KEY` is still set).
106
+ - `login`|`token`: [DEPRECATED] Retrieve your API authentication token/key via login.
107
+ - `logout`: Clear stored authentication credentials and SAML tokens (Keyring, API key from credential file and emit warning when `$CLOUDSMITH_API_KEY` is still set).
105
108
  - `metadata`: Manage arbitrary JSON metadata (SBOM, BuildInfo, custom) attached to a package.
106
109
  - `add`: Attach a new metadata entry to a package.
107
110
  - `list`|`ls`: List metadata entries for a package, or fetch a single entry by slug.
@@ -232,6 +235,29 @@ pip install cloudsmith-cli[aws]
232
235
 
233
236
  This installs `boto3[crt]` for AWS credential chain support, STS token generation, and AWS SSO compatibility.
234
237
 
238
+ #### GCP OIDC Support
239
+
240
+ For Google Cloud environments (GCE, Cloud Run, GKE, Cloud Functions, App Engine, Cloud Build), install with the `gcp` extra to enable automatic credential discovery:
241
+
242
+ ```
243
+ pip install cloudsmith-cli[gcp]
244
+ ```
245
+
246
+ This installs `google-auth` for Application Default Credentials (ADC) resolution and OIDC ID token generation. It works with an attached Google Cloud service account, a service-account key supplied through `GOOGLE_APPLICATION_CREDENTIALS`, or service-account impersonation configured locally:
247
+
248
+ ```sh
249
+ gcloud auth application-default login --impersonate-service-account=SERVICE_ACCOUNT_EMAIL
250
+ cloudsmith whoami --workspace=YOUR_WORKSPACE --oidc-service-slug=YOUR_SERVICE --oidc-detector-order=gcp
251
+ ```
252
+
253
+ Configure a Cloudsmith OIDC provider to trust `https://accounts.google.com`, the service account's numeric unique ID as the subject, and audience `cloudsmith` (override with `--oidc-audience` or `CLOUDSMITH_OIDC_AUDIENCE`). Local impersonation requires the Service Account Token Creator role on the target service account and the IAM Service Account Credentials API enabled.
254
+
255
+ On workloads with a metadata identity endpoint, the CLI requests an ID token directly. If that endpoint returns HTTP 404 (as on some Cloud Build environments), it uses IAM `generateIdToken` for the same attached service account. This fallback requires the IAM Service Account Credentials API and `iam.serviceAccounts.getOpenIdToken` on that account; the Service Account OpenID Connect Identity Token Creator role grants this permission. Permission and transport failures are reported, not treated as a missing endpoint.
256
+
257
+ A plain `gcloud auth application-default login` user session cannot mint an ID token for an arbitrary audience. To use it, set `--oidc-audience` to the session's OAuth client ID and configure Cloudsmith to trust that audience and user subject; otherwise use service-account impersonation. `gcloud auth login` alone does not configure ADC. Other ADC types, including direct external-account federation, are skipped rather than incorrectly treated as ID-token-capable credentials.
258
+
259
+ See Google's [Authenticate with auth libraries](https://docs.cloud.google.com/iam/docs/authenticate-with-auth-libraries#authenticate-standard) guide for credential discovery.
260
+
235
261
  #### All Optional Features
236
262
 
237
263
  To install all optional dependencies:
@@ -240,7 +266,7 @@ To install all optional dependencies:
240
266
  pip install cloudsmith-cli[all]
241
267
  ```
242
268
 
243
- **Note:** If you don't install the AWS extra, the AWS OIDC detector will gracefully skip itself with no errors.
269
+ **Note:** If you don't install the AWS or GCP extra, the corresponding OIDC detector will gracefully skip itself with no errors.
244
270
 
245
271
  #### Bitbucket Pipelines OIDC Support
246
272
 
@@ -261,6 +287,10 @@ See the [Bitbucket Pipelines OIDC documentation](https://support.atlassian.com/b
261
287
 
262
288
  In CircleCI, OIDC credential discovery works out of the box with no extra dependencies — 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 CircleCI mints, which is your CircleCI organization UUID. See the [Cloudsmith CircleCI integration guide](https://docs.cloudsmith.com/integrations/integrating-with-circleci).
263
289
 
290
+ #### Buildkite OIDC Support
291
+
292
+ In Buildkite, OIDC credential discovery works out of the box with no extra dependencies — the CLI requests a token for the current job through `buildkite-agent oidc request-token`. By default it requests the `cloudsmith` audience; use `--oidc-audience` or `CLOUDSMITH_OIDC_AUDIENCE` if your Cloudsmith OIDC provider expects a different audience. See the [Buildkite OIDC documentation](https://buildkite.com/docs/pipelines/security/oidc).
293
+
264
294
  #### Azure DevOps OIDC Support
265
295
 
266
296
  In Azure DevOps Pipelines, OIDC credential discovery works out of the box with no extra dependencies — the CLI fetches an OIDC token from the `SYSTEM_OIDCREQUESTURI` endpoint using the pipeline's `SYSTEM_ACCESSTOKEN`. Make sure `SYSTEM_ACCESSTOKEN` is mapped into the step's environment. The Cloudsmith OIDC provider must expect the audience `api://AzureADTokenExchange`, which Azure DevOps always mints (any requested audience is ignored). See the [Cloudsmith Azure DevOps integration guide](https://docs.cloudsmith.com/integrations/integrating-with-azure-devops).
@@ -295,7 +325,7 @@ By default the CLI tries each detector in a fixed priority order and uses the fi
295
325
  - **Disable a detector** — set `CLOUDSMITH_OIDC_<DETECTOR>_DISABLED=true` to skip it entirely. Only the literal value `true` (case-insensitive) disables; anything else leaves the detector enabled. For example, `CLOUDSMITH_OIDC_AWS_DISABLED=true` skips the AWS detector so an explicitly-set `CLOUDSMITH_OIDC_TOKEN` is picked up by the generic detector instead.
296
326
  - **Reorder evaluation** — use `--oidc-detector-order` (or the `CLOUDSMITH_OIDC_DETECTOR_ORDER` environment variable) with a comma-separated list of detector ids to control both which detectors are considered and the order they are tried in (first match wins). Ids not listed are skipped; unrecognised ids are ignored with a warning. For example, `--oidc-detector-order=generic,aws` tries the generic detector first and considers only those two.
297
327
 
298
- When both are set, the order list defines the candidate set and sequence, then the `*_DISABLED` flags are applied on top — so a disabled detector is always skipped even if it appears in the order list. Detector ids are: `aws`, `azure_devops`, `bitbucket`, `circleci`, `generic`, `github`, `gitlab`.
328
+ When both are set, the order list defines the candidate set and sequence, then the `*_DISABLED` flags are applied on top — so a disabled detector is always skipped even if it appears in the order list. Detector ids are: `aws`, `azure_devops`, `bitbucket`, `buildkite`, `circleci`, `gcp`, `generic`, `github`, `gitlab`.
299
329
 
300
330
  Both controls can also be set in `config.ini`, under `[default]` or a profile section:
301
331
 
@@ -338,7 +368,7 @@ Both configuration files use the simple INI format, such as:
338
368
  api_key=1234567890abcdef1234567890abcdef
339
369
  ```
340
370
 
341
- Additionally, the CLI will store SSO access and refresh tokens in the system keyring
371
+ Additionally, the CLI will store SAML access and refresh tokens in the system keyring
342
372
  using the [`keyring`](https://github.com/jaraco/keyring) library.
343
373
 
344
374
 
@@ -349,8 +379,9 @@ See the [default config](https://raw.githubusercontent.com/cloudsmith-io/cloudsm
349
379
  You can specify the following configuration options:
350
380
 
351
381
  - `api_host`: The API host to connect to.
352
- - `api_proxy`: The API proxy to connect through.
353
- - `api_ssl_verify`: Whether or not to use SSL verification for requests.
382
+ - `proxy`: The proxy to connect through for all HTTP requests, including API, SAML, upload, download, MCP, update, credential helper, OIDC, and error report connections. Use `--proxy` or `CLOUDSMITH_PROXY` to set it for one command. The config key `api_proxy`, flag `--api-proxy`, and environment variable `CLOUDSMITH_API_PROXY` remain supported for compatibility. In config and environment variables, the new name takes precedence over the alias. Without `proxy`, the CLI uses the `HTTPS_PROXY`, `HTTP_PROXY`, and `NO_PROXY` environment variables. When `proxy` is set, it takes precedence over them.
383
+ - `ssl_verify`: Whether or not to verify SSL certificates for HTTPS requests, including API, SAML, uploads, downloads, and MCP (default: `true`). Use `CLOUDSMITH_SSL_VERIFY=1` to enable verification or `CLOUDSMITH_SSL_VERIFY=0` / `--without-ssl-verify` to disable it. Disabling verification is dangerous; prefer disabling only strict checks where possible. The config key `api_ssl_verify`, flag `--without-api-ssl-verify` / `-S`, and environment variable `CLOUDSMITH_WITHOUT_API_SSL_VERIFY` remain supported for compatibility. Command-line settings override environment variables, which override config; within the same source, the new spelling takes precedence.
384
+ - `ssl_verify_strict`: Whether or not to apply strict X.509 certificate verification (`VERIFY_X509_STRICT`, enabled by default on Python 3.13+). Set to `false` (or use `--without-ssl-verify-strict` / `CLOUDSMITH_SSL_VERIFY_STRICT=0`) if a TLS-intercepting proxy issues certificates that fail these checks. `CLOUDSMITH_SSL_VERIFY_STRICT=1` keeps strict verification enabled (the default). Certificates are still verified.
354
385
  - `api_user_agent`: The user agent to use for requests.
355
386
 
356
387
  ### Credentials (credentials.ini)
@@ -389,29 +420,15 @@ cloudsmith auth --owner example --no-browser
389
420
 
390
421
  #### Getting Your API Key
391
422
 
392
- You can retrieve your API key using the `cloudsmith login` command:
393
-
394
- ```
395
- cloudsmith login
396
- Login: you@example.com
397
- Password:
398
- Repeat for confirmation:
399
- ```
400
-
401
- *Note:* Please ensure you use your email for the 'Login' prompt and not your user slug/identifier.
402
-
403
- The resulting output looks something like:
404
-
405
- ```
406
- Retrieving API token for 'you@example.com' ... OK
407
- Your API token is: 1234567890abcdef1234567890abcdef
408
- ```
423
+ Get your API key from the Cloudsmith web app: click your user icon in the top right corner, then click **Personal API Keys**. See [API Key](https://docs.cloudsmith.com/accounts-and-teams/api-key) for more information. If you authenticated with `cloudsmith auth`, you can also use `cloudsmith tokens create` to create an API key.
409
424
 
410
- Once you have your API key you can then put this into your `credentials.ini`, use it as an environment variable `export CLOUDSMITH_API_KEY=your_key_here` or pass it to the CLI using the `-k your_key_here` flag.
425
+ Give your API key to the CLI in one of these ways:
411
426
 
412
- 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. Say 'y' or 'yes' to create the configuration files.
427
+ - Set the `CLOUDSMITH_API_KEY` environment variable: `export CLOUDSMITH_API_KEY=your_key_here`.
428
+ - Put the key into your `credentials.ini` file.
429
+ - Pass the key to the CLI with the `-k your_key_here` flag.
413
430
 
414
- If the configuration files already exist, you'll have to manually put the API key into the configuration files, but the CLI will print out their locations.
431
+ *Note:* The `cloudsmith login` command and its `cloudsmith token` alias are deprecated. They retrieve your API key with your email address and password, and they will stop working on November 20, 2026, when Cloudsmith disables username and password login. See the [Cloudsmith changelog](https://cloudsmith.com/changelog). After that, both commands fail with a message that explains how to get an API key instead.
415
432
 
416
433
 
417
434
  ## Uploading Packages
@@ -47,8 +47,8 @@ The CLI currently supports the following commands (and sub-commands):
47
47
  - `entitlements`|`ents`: List entitlements for a repository.
48
48
  - `packages`: List packages for a repository. (Aliases `repos list`)
49
49
  - `repos`: List repositories for a namespace (owner).
50
- - `login`|`token`: Retrieve your API authentication token/key via login.
51
- - `logout`: Clear stored authentication credentials and SSO tokens (Keyring, API key from credential file and emit warning when `$CLOUDSMITH_API_KEY` is still set).
50
+ - `login`|`token`: [DEPRECATED] Retrieve your API authentication token/key via login.
51
+ - `logout`: Clear stored authentication credentials and SAML tokens (Keyring, API key from credential file and emit warning when `$CLOUDSMITH_API_KEY` is still set).
52
52
  - `metadata`: Manage arbitrary JSON metadata (SBOM, BuildInfo, custom) attached to a package.
53
53
  - `add`: Attach a new metadata entry to a package.
54
54
  - `list`|`ls`: List metadata entries for a package, or fetch a single entry by slug.
@@ -179,6 +179,29 @@ pip install cloudsmith-cli[aws]
179
179
 
180
180
  This installs `boto3[crt]` for AWS credential chain support, STS token generation, and AWS SSO compatibility.
181
181
 
182
+ #### GCP OIDC Support
183
+
184
+ For Google Cloud environments (GCE, Cloud Run, GKE, Cloud Functions, App Engine, Cloud Build), install with the `gcp` extra to enable automatic credential discovery:
185
+
186
+ ```
187
+ pip install cloudsmith-cli[gcp]
188
+ ```
189
+
190
+ This installs `google-auth` for Application Default Credentials (ADC) resolution and OIDC ID token generation. It works with an attached Google Cloud service account, a service-account key supplied through `GOOGLE_APPLICATION_CREDENTIALS`, or service-account impersonation configured locally:
191
+
192
+ ```sh
193
+ gcloud auth application-default login --impersonate-service-account=SERVICE_ACCOUNT_EMAIL
194
+ cloudsmith whoami --workspace=YOUR_WORKSPACE --oidc-service-slug=YOUR_SERVICE --oidc-detector-order=gcp
195
+ ```
196
+
197
+ Configure a Cloudsmith OIDC provider to trust `https://accounts.google.com`, the service account's numeric unique ID as the subject, and audience `cloudsmith` (override with `--oidc-audience` or `CLOUDSMITH_OIDC_AUDIENCE`). Local impersonation requires the Service Account Token Creator role on the target service account and the IAM Service Account Credentials API enabled.
198
+
199
+ On workloads with a metadata identity endpoint, the CLI requests an ID token directly. If that endpoint returns HTTP 404 (as on some Cloud Build environments), it uses IAM `generateIdToken` for the same attached service account. This fallback requires the IAM Service Account Credentials API and `iam.serviceAccounts.getOpenIdToken` on that account; the Service Account OpenID Connect Identity Token Creator role grants this permission. Permission and transport failures are reported, not treated as a missing endpoint.
200
+
201
+ A plain `gcloud auth application-default login` user session cannot mint an ID token for an arbitrary audience. To use it, set `--oidc-audience` to the session's OAuth client ID and configure Cloudsmith to trust that audience and user subject; otherwise use service-account impersonation. `gcloud auth login` alone does not configure ADC. Other ADC types, including direct external-account federation, are skipped rather than incorrectly treated as ID-token-capable credentials.
202
+
203
+ See Google's [Authenticate with auth libraries](https://docs.cloud.google.com/iam/docs/authenticate-with-auth-libraries#authenticate-standard) guide for credential discovery.
204
+
182
205
  #### All Optional Features
183
206
 
184
207
  To install all optional dependencies:
@@ -187,7 +210,7 @@ To install all optional dependencies:
187
210
  pip install cloudsmith-cli[all]
188
211
  ```
189
212
 
190
- **Note:** If you don't install the AWS extra, the AWS OIDC detector will gracefully skip itself with no errors.
213
+ **Note:** If you don't install the AWS or GCP extra, the corresponding OIDC detector will gracefully skip itself with no errors.
191
214
 
192
215
  #### Bitbucket Pipelines OIDC Support
193
216
 
@@ -208,6 +231,10 @@ See the [Bitbucket Pipelines OIDC documentation](https://support.atlassian.com/b
208
231
 
209
232
  In CircleCI, OIDC credential discovery works out of the box with no extra dependencies — 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 CircleCI mints, which is your CircleCI organization UUID. See the [Cloudsmith CircleCI integration guide](https://docs.cloudsmith.com/integrations/integrating-with-circleci).
210
233
 
234
+ #### Buildkite OIDC Support
235
+
236
+ In Buildkite, OIDC credential discovery works out of the box with no extra dependencies — the CLI requests a token for the current job through `buildkite-agent oidc request-token`. By default it requests the `cloudsmith` audience; use `--oidc-audience` or `CLOUDSMITH_OIDC_AUDIENCE` if your Cloudsmith OIDC provider expects a different audience. See the [Buildkite OIDC documentation](https://buildkite.com/docs/pipelines/security/oidc).
237
+
211
238
  #### Azure DevOps OIDC Support
212
239
 
213
240
  In Azure DevOps Pipelines, OIDC credential discovery works out of the box with no extra dependencies — the CLI fetches an OIDC token from the `SYSTEM_OIDCREQUESTURI` endpoint using the pipeline's `SYSTEM_ACCESSTOKEN`. Make sure `SYSTEM_ACCESSTOKEN` is mapped into the step's environment. The Cloudsmith OIDC provider must expect the audience `api://AzureADTokenExchange`, which Azure DevOps always mints (any requested audience is ignored). See the [Cloudsmith Azure DevOps integration guide](https://docs.cloudsmith.com/integrations/integrating-with-azure-devops).
@@ -242,7 +269,7 @@ By default the CLI tries each detector in a fixed priority order and uses the fi
242
269
  - **Disable a detector** — set `CLOUDSMITH_OIDC_<DETECTOR>_DISABLED=true` to skip it entirely. Only the literal value `true` (case-insensitive) disables; anything else leaves the detector enabled. For example, `CLOUDSMITH_OIDC_AWS_DISABLED=true` skips the AWS detector so an explicitly-set `CLOUDSMITH_OIDC_TOKEN` is picked up by the generic detector instead.
243
270
  - **Reorder evaluation** — use `--oidc-detector-order` (or the `CLOUDSMITH_OIDC_DETECTOR_ORDER` environment variable) with a comma-separated list of detector ids to control both which detectors are considered and the order they are tried in (first match wins). Ids not listed are skipped; unrecognised ids are ignored with a warning. For example, `--oidc-detector-order=generic,aws` tries the generic detector first and considers only those two.
244
271
 
245
- When both are set, the order list defines the candidate set and sequence, then the `*_DISABLED` flags are applied on top — so a disabled detector is always skipped even if it appears in the order list. Detector ids are: `aws`, `azure_devops`, `bitbucket`, `circleci`, `generic`, `github`, `gitlab`.
272
+ When both are set, the order list defines the candidate set and sequence, then the `*_DISABLED` flags are applied on top — so a disabled detector is always skipped even if it appears in the order list. Detector ids are: `aws`, `azure_devops`, `bitbucket`, `buildkite`, `circleci`, `gcp`, `generic`, `github`, `gitlab`.
246
273
 
247
274
  Both controls can also be set in `config.ini`, under `[default]` or a profile section:
248
275
 
@@ -285,7 +312,7 @@ Both configuration files use the simple INI format, such as:
285
312
  api_key=1234567890abcdef1234567890abcdef
286
313
  ```
287
314
 
288
- Additionally, the CLI will store SSO access and refresh tokens in the system keyring
315
+ Additionally, the CLI will store SAML access and refresh tokens in the system keyring
289
316
  using the [`keyring`](https://github.com/jaraco/keyring) library.
290
317
 
291
318
 
@@ -296,8 +323,9 @@ See the [default config](https://raw.githubusercontent.com/cloudsmith-io/cloudsm
296
323
  You can specify the following configuration options:
297
324
 
298
325
  - `api_host`: The API host to connect to.
299
- - `api_proxy`: The API proxy to connect through.
300
- - `api_ssl_verify`: Whether or not to use SSL verification for requests.
326
+ - `proxy`: The proxy to connect through for all HTTP requests, including API, SAML, upload, download, MCP, update, credential helper, OIDC, and error report connections. Use `--proxy` or `CLOUDSMITH_PROXY` to set it for one command. The config key `api_proxy`, flag `--api-proxy`, and environment variable `CLOUDSMITH_API_PROXY` remain supported for compatibility. In config and environment variables, the new name takes precedence over the alias. Without `proxy`, the CLI uses the `HTTPS_PROXY`, `HTTP_PROXY`, and `NO_PROXY` environment variables. When `proxy` is set, it takes precedence over them.
327
+ - `ssl_verify`: Whether or not to verify SSL certificates for HTTPS requests, including API, SAML, uploads, downloads, and MCP (default: `true`). Use `CLOUDSMITH_SSL_VERIFY=1` to enable verification or `CLOUDSMITH_SSL_VERIFY=0` / `--without-ssl-verify` to disable it. Disabling verification is dangerous; prefer disabling only strict checks where possible. The config key `api_ssl_verify`, flag `--without-api-ssl-verify` / `-S`, and environment variable `CLOUDSMITH_WITHOUT_API_SSL_VERIFY` remain supported for compatibility. Command-line settings override environment variables, which override config; within the same source, the new spelling takes precedence.
328
+ - `ssl_verify_strict`: Whether or not to apply strict X.509 certificate verification (`VERIFY_X509_STRICT`, enabled by default on Python 3.13+). Set to `false` (or use `--without-ssl-verify-strict` / `CLOUDSMITH_SSL_VERIFY_STRICT=0`) if a TLS-intercepting proxy issues certificates that fail these checks. `CLOUDSMITH_SSL_VERIFY_STRICT=1` keeps strict verification enabled (the default). Certificates are still verified.
301
329
  - `api_user_agent`: The user agent to use for requests.
302
330
 
303
331
  ### Credentials (credentials.ini)
@@ -336,29 +364,15 @@ cloudsmith auth --owner example --no-browser
336
364
 
337
365
  #### Getting Your API Key
338
366
 
339
- You can retrieve your API key using the `cloudsmith login` command:
340
-
341
- ```
342
- cloudsmith login
343
- Login: you@example.com
344
- Password:
345
- Repeat for confirmation:
346
- ```
347
-
348
- *Note:* Please ensure you use your email for the 'Login' prompt and not your user slug/identifier.
349
-
350
- The resulting output looks something like:
351
-
352
- ```
353
- Retrieving API token for 'you@example.com' ... OK
354
- Your API token is: 1234567890abcdef1234567890abcdef
355
- ```
367
+ Get your API key from the Cloudsmith web app: click your user icon in the top right corner, then click **Personal API Keys**. See [API Key](https://docs.cloudsmith.com/accounts-and-teams/api-key) for more information. If you authenticated with `cloudsmith auth`, you can also use `cloudsmith tokens create` to create an API key.
356
368
 
357
- Once you have your API key you can then put this into your `credentials.ini`, use it as an environment variable `export CLOUDSMITH_API_KEY=your_key_here` or pass it to the CLI using the `-k your_key_here` flag.
369
+ Give your API key to the CLI in one of these ways:
358
370
 
359
- 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. Say 'y' or 'yes' to create the configuration files.
371
+ - Set the `CLOUDSMITH_API_KEY` environment variable: `export CLOUDSMITH_API_KEY=your_key_here`.
372
+ - Put the key into your `credentials.ini` file.
373
+ - Pass the key to the CLI with the `-k your_key_here` flag.
360
374
 
361
- If the configuration files already exist, you'll have to manually put the API key into the configuration files, but the CLI will print out their locations.
375
+ *Note:* The `cloudsmith login` command and its `cloudsmith token` alias are deprecated. They retrieve your API key with your email address and password, and they will stop working on November 20, 2026, when Cloudsmith disables username and password login. See the [Cloudsmith changelog](https://cloudsmith.com/changelog). After that, both commands fail with a message that explains how to get an API key instead.
362
376
 
363
377
 
364
378
  ## Uploading Packages
@@ -6,6 +6,8 @@ from collections import OrderedDict
6
6
  import click.exceptions
7
7
  from click_didyoumean import DYMGroup
8
8
 
9
+ from ..core.certificate_errors import describe_certificate_error
10
+
9
11
 
10
12
  def _is_json_output_requested(exception):
11
13
  """Determine if JSON output was requested, checking context and argv."""
@@ -35,6 +37,19 @@ def _is_json_output_requested(exception):
35
37
  return False
36
38
 
37
39
 
40
+ def _is_debug_requested(args=None):
41
+ """Determine if --debug was passed (the click context is gone by now).
42
+
43
+ ``args`` are the arguments given to ``main``; click falls back to
44
+ ``sys.argv`` when they are ``None``, so we do the same.
45
+ """
46
+ import sys
47
+
48
+ if args is None:
49
+ args = sys.argv[1:]
50
+ return any(arg in ("-d", "--debug") for arg in args)
51
+
52
+
38
53
  def _format_click_exception_as_json(exception):
39
54
  """Format a ClickException as a JSON error dict."""
40
55
  return {
@@ -45,11 +60,19 @@ def _format_click_exception_as_json(exception):
45
60
  },
46
61
  "help": {
47
62
  "context": "Invalid usage",
48
- "hint": "Check your command arguments/flags.",
63
+ "hint": describe_certificate_error(exception)
64
+ or "Check your command arguments/flags.",
49
65
  },
50
66
  }
51
67
 
52
68
 
69
+ def _echo_certificate_hint(exception):
70
+ """Explain a TLS certificate failure behind ``exception`` on stderr."""
71
+ hint = describe_certificate_error(exception)
72
+ if hint:
73
+ click.echo(f"Hint: {click.style(hint, fg='yellow')}", err=True)
74
+
75
+
53
76
  class AliasGroup(DYMGroup):
54
77
  """A command group with DYM, alias and lazy-subcommand support.
55
78
 
@@ -177,4 +200,23 @@ class AliasGroup(DYMGroup):
177
200
  if not original_standalone_mode:
178
201
  raise
179
202
  e.show()
203
+ _echo_certificate_hint(e)
180
204
  sys.exit(e.exit_code)
205
+ except Exception as e: # pylint: disable=broad-exception-caught
206
+ # Anything reaching here is unexpected: click's own errors and
207
+ # handled API errors (which exit via ctx.exit) are dealt with
208
+ # above or never get this far.
209
+ if not original_standalone_mode:
210
+ raise
211
+ main_args = kwargs.get("args", args[0] if args else None)
212
+ if _is_debug_requested(main_args):
213
+ import traceback
214
+
215
+ click.echo(traceback.format_exc(), err=True, nl=False)
216
+ from ..core import telemetry
217
+
218
+ # Reporting is silent: the user sees the same line either way.
219
+ telemetry.report_exception(e)
220
+ click.echo(f"Error: {telemetry.format_exception_summary(e)}", err=True)
221
+ _echo_certificate_hint(e)
222
+ sys.exit(1)
@@ -12,7 +12,7 @@ from ...core.sso import (
12
12
  )
13
13
  from .. import decorators, utils, validators
14
14
  from ..exceptions import handle_api_exceptions
15
- from ..saml import create_configured_session, get_idp_url
15
+ from ..saml import get_idp_url
16
16
  from ..webserver import AuthenticationWebRequestHandler, AuthenticationWebServer
17
17
  from .main import main
18
18
  from .tokens import create, request_api_key
@@ -53,7 +53,7 @@ def _create_auth_server(opts, owner, session, enable_token_creation, profile):
53
53
 
54
54
 
55
55
  def _renew_existing_sso_session(opts, profile):
56
- """Return a usable existing SSO session, or fall back to browser auth."""
56
+ """Return a usable existing SAML session, or fall back to browser auth."""
57
57
  renewal = renew_sso_session(opts.api_config.host, opts.session, profile=profile)
58
58
  if renewal.status in (
59
59
  SsoRenewalStatus.RENEWED,
@@ -64,14 +64,15 @@ def _renew_existing_sso_session(opts, profile):
64
64
  renewal.error, requests.RequestException
65
65
  ):
66
66
  raise click.ClickException(
67
- "The SSO session has expired and Cloudsmith could not be reached. "
67
+ "The SAML session has expired and Cloudsmith could not be reached: "
68
+ f"{renewal.error}\n"
68
69
  "Check your connection, then run 'cloudsmith auth' again."
69
70
  ) from renewal.error
70
71
  return None
71
72
 
72
73
 
73
74
  def _report_active_sso_session(opts, renewal, use_stderr=False):
74
- """Report the usable SSO session without exposing its access token."""
75
+ """Report the usable SAML session without exposing its access token."""
75
76
  expires_at = get_access_token_expiry(renewal.access_token)
76
77
  data = {
77
78
  "authenticated": True,
@@ -84,16 +85,16 @@ def _report_active_sso_session(opts, renewal, use_stderr=False):
84
85
  return
85
86
 
86
87
  if renewal.status == SsoRenewalStatus.RENEWED:
87
- click.secho("SSO session renewed.", fg="green", err=use_stderr)
88
+ click.secho("SAML session renewed.", fg="green", err=use_stderr)
88
89
  elif renewal.error:
89
90
  click.secho(
90
- "The SSO session could not be renewed; the existing access token "
91
+ "The SAML session could not be renewed; the existing access token "
91
92
  "remains active.",
92
93
  fg="yellow",
93
94
  err=use_stderr,
94
95
  )
95
96
  else:
96
- click.secho("SSO session is active.", fg="green", err=use_stderr)
97
+ click.secho("SAML session is active.", fg="green", err=use_stderr)
97
98
  if expires_at:
98
99
  click.echo(
99
100
  f"Access token expires at {utils.fmt_datetime(expires_at)}.",
@@ -110,7 +111,7 @@ def _perform_saml_authentication(
110
111
  profile=None,
111
112
  ):
112
113
  """Perform SAML authentication via web browser and local web server."""
113
- session = create_configured_session(opts)
114
+ session = opts.session
114
115
  api_host = opts.api_config.host
115
116
 
116
117
  auth_server, port = _create_auth_server(
@@ -270,10 +271,10 @@ def authenticate(
270
271
  err=use_stderr,
271
272
  )
272
273
 
273
- # Determine if we need to refresh API after SSO (required for token operations)
274
+ # Determine if we need to refresh API after SAML (required for token operations)
274
275
  enable_token_creation = token or request_api_key_flag
275
276
 
276
- context_message = "Failed to authenticate via SSO!"
277
+ context_message = "Failed to authenticate via SAML!"
277
278
  with handle_api_exceptions(ctx, opts=opts, context_msg=context_message):
278
279
  _perform_saml_authentication(
279
280
  opts,
@@ -127,6 +127,4 @@ def service(ctx, opts):
127
127
  click.secho("(up-to-date)", fg="green")
128
128
 
129
129
  click.echo()
130
- click.secho(
131
- "The API library used by this CLI tool seems to be up-to-date.", fg="green"
132
- )
130
+ click.secho("The API library used by this CLI tool is up-to-date.", fg="green")
@@ -9,6 +9,7 @@ Provides ``credential-helper install``, ``credential-helper uninstall``, and
9
9
  from __future__ import annotations
10
10
 
11
11
  import sys
12
+ from urllib.parse import urlsplit
12
13
 
13
14
  import click
14
15
 
@@ -78,10 +79,14 @@ def _get_installer(name: str):
78
79
  def _terraform_helper_args(ctx, opts, repo: str | None = None) -> tuple[str, ...]:
79
80
  """Build the terraformrc ``args`` list from the resolved config.
80
81
 
81
- Baking ``--org``/``-r``/``-P`` into the block means ``terraform init`` works
82
+ Baking ``-w``/``-r``/``-P`` into the block means ``terraform init`` works
82
83
  with no environment variables and no hand-edited config. Only values
83
- actually supplied are written, so an install without ``--org``/``--repo``/
84
- ``-P`` leaves ``args = []``.
84
+ actually supplied are written, so an install without ``-w``/``--repo``/
85
+ ``-P`` leaves ``args = []``. The API host and proxy are baked in too, so
86
+ the helper looks up domains on the same API host, through the same proxy,
87
+ as the install. A proxy URL with credentials is never baked in: Terraform
88
+ passes ``args`` on the helper's command line, where any local user can read
89
+ them.
85
90
 
86
91
  A non-default ``--config-file``/``--credentials-file`` is also baked in: the
87
92
  helper is later invoked by ``terraform init`` in a fresh process with none
@@ -91,7 +96,7 @@ def _terraform_helper_args(ctx, opts, repo: str | None = None) -> tuple[str, ...
91
96
  """
92
97
  args: list[str] = []
93
98
  if opts.org:
94
- args.extend(["--org", opts.org])
99
+ args.extend(["-w", opts.org])
95
100
  if repo:
96
101
  args.extend(["-r", repo])
97
102
  profile = ctx.meta.get("profile")
@@ -103,9 +108,32 @@ def _terraform_helper_args(ctx, opts, repo: str | None = None) -> tuple[str, ...
103
108
  creds_file = ctx.meta.get("creds_file")
104
109
  if creds_file:
105
110
  args.extend(["--credentials-file", creds_file])
111
+ if opts.api_host:
112
+ args.extend(["--api-host", opts.api_host])
113
+ if opts.proxy and not _proxy_has_credentials(opts.proxy):
114
+ args.extend(["--proxy", opts.proxy])
106
115
  return tuple(args)
107
116
 
108
117
 
118
+ def _proxy_has_credentials(proxy: str) -> bool:
119
+ """Return True if the proxy URL carries a username or password."""
120
+ parsed = urlsplit(proxy if "://" in proxy else f"//{proxy}")
121
+ return parsed.username is not None or parsed.password is not None
122
+
123
+
124
+ def _terraform_proxy_next_steps(opts) -> list[str]:
125
+ """Return the post-install guidance when the proxy was not baked in."""
126
+ if not opts.proxy or not _proxy_has_credentials(opts.proxy):
127
+ return []
128
+ return [
129
+ (
130
+ "Next steps: the proxy URL contains credentials, so it was not"
131
+ " written to the Terraform config. export CLOUDSMITH_PROXY=<proxy-url>"
132
+ " in the environment that runs `terraform init`."
133
+ ),
134
+ ]
135
+
136
+
109
137
  _REPO_FLAGS = ("-r", "--repo", "--repository")
110
138
 
111
139
 
@@ -141,6 +169,31 @@ def _terraform_next_steps(helper_args: tuple[str, ...]) -> list[str]:
141
169
  ]
142
170
 
143
171
 
172
+ def _terraform_workspace_next_steps(helper_args: tuple[str, ...]) -> list[str]:
173
+ """Return the post-install guidance when no Workspace is baked in.
174
+
175
+ The helper needs a Workspace to match custom domains and to scope the
176
+ token for a Cloudsmith-owned host.
177
+ """
178
+ if "-w" in helper_args:
179
+ return []
180
+ rc_path = _terraformrc_path()
181
+ return [
182
+ (
183
+ "Next steps: the Terraform helper needs a Workspace to match custom"
184
+ " domains and to scope tokens. Provide it in one of these ways:"
185
+ ),
186
+ (
187
+ " - export CLOUDSMITH_WORKSPACE=<your-workspace> in the environment"
188
+ " that runs `terraform init`, or"
189
+ ),
190
+ (
191
+ f" - add it to the args in {rc_path}, e.g."
192
+ ' args = ["-w", "<your-workspace>", ...].'
193
+ ),
194
+ ]
195
+
196
+
144
197
  # ---------------------------------------------------------------------------
145
198
  # install
146
199
  # ---------------------------------------------------------------------------
@@ -149,7 +202,10 @@ def _terraform_next_steps(helper_args: tuple[str, ...]) -> list[str]:
149
202
  @click.command("install")
150
203
  @click.argument("helper")
151
204
  @click.option(
152
- "--bin-dir", default=None, help="Directory to install the launcher binary."
205
+ "--bin-dir",
206
+ default=None,
207
+ help="Directory to install the launcher binary. "
208
+ "[default: ~/.cloudsmith/bin, or Terraform's plugin directory]",
153
209
  )
154
210
  @click.option(
155
211
  "--domain",
@@ -231,7 +287,7 @@ def install_cmd(
231
287
  \b
232
288
  # Terraform: bake the repository into the terraformrc args so
233
289
  # `terraform init` needs no CLOUDSMITH_REPO env var
234
- $ cloudsmith credential-helper install terraform --org acme --repo my-repo
290
+ $ cloudsmith credential-helper install terraform -w acme --repo my-repo
235
291
  """
236
292
  installer = _get_installer(helper)
237
293
 
@@ -278,7 +334,11 @@ def install_cmd(
278
334
 
279
335
  next_steps: list[str] = []
280
336
  if helper == "terraform":
281
- next_steps = _terraform_next_steps(helper_args)
337
+ next_steps = (
338
+ _terraform_workspace_next_steps(helper_args)
339
+ + _terraform_next_steps(helper_args)
340
+ + _terraform_proxy_next_steps(opts)
341
+ )
282
342
 
283
343
  data = {
284
344
  "helper": helper,
@@ -309,7 +369,10 @@ def install_cmd(
309
369
  @click.command("uninstall")
310
370
  @click.argument("helper")
311
371
  @click.option(
312
- "--bin-dir", default=None, help="Directory where the launcher binary was installed."
372
+ "--bin-dir",
373
+ default=None,
374
+ help="Directory where the launcher binary was installed. "
375
+ "[default: ~/.cloudsmith/bin, or Terraform's plugin directory]",
313
376
  )
314
377
  @click.option(
315
378
  "--dry-run",