Skip to content

fix(no-ticket): show OIDC credentials as OIDC in whoami --verbose - #521

Open
cloudsmith-iduffy wants to merge 5 commits into
masterfrom
iduffy/whoami-oidc
Open

cloudsmith-iduffy wants to merge 5 commits into
masterfrom
iduffy/whoami-oidc

Conversation

@cloudsmith-iduffy

@cloudsmith-iduffy cloudsmith-iduffy commented Oct 22, 2026 •

Copy link
Copy Markdown
Collaborator

Description

cloudsmith whoami --verbose shows a credential from OIDC auto-discovery as a SAML session. In CI, this hides how the CLI authenticated:

User: circlci (slug: circlci)

Authentication Method: SAML Token (primary)

The cause:

This PR detects an OIDC credential from the credential chain (source_name == "oidc") before it looks at the headers. After the fix:

User: CI service (slug: ci-service)

Authentication Method: OIDC Auto-Discovery
  Source: OIDC via GitHub Actions (org: acme, service: ci-service)

With -F json, auth.active_method is oidc instead of sso_token, and the new auth.oidc object gives configured and source.

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation update
  • Refactoring
  • Other (please describe)

Additional Notes

  • Tests for the label: 3 new tests in cloudsmith_cli/cli/tests/commands/test_whoami.py for the text output, the JSON output, and a SAML session, which still shows as SAML Token (primary). The OIDC tests failed before the fix. The full unit suite and pre-commit pass.
  • JSON consumers: anyone who reads active_method gets oidc instead of sso_token for OIDC credentials. The changelog entry says so.
  • Cached tokens: most commands in a CI job after the first one use the cached token, which showed OIDC [cached] (org: …, service: …) without the CI vendor. The provider reads the cache before it detects the environment. The second commit stores the detector name with the cached token, so the source is now, for example, OIDC via GitHub Actions [cached] (org: …, service: …). A token that an earlier version cached keeps the old source until it expires. Tests: 3 provider tests and a new test_oidc_cache.py for the disk and keyring paths.
  • End-to-end check in GitHub Actions: this run installed the CLI from this branch and ran whoami --verbose twice with GitHub OIDC. The first run printed Authentication Method: OIDC Auto-Discovery and Source: OIDC via GitHub Actions (org: iduffy-demo, service: github-c3xe). The second run, from the cache, printed Source: OIDC via GitHub Actions [cached] (org: iduffy-demo, service: github-c3xe).

🤖 Generated with Claude Code

Since #383, the OIDC provider returns its exchanged token as a bearer
token. whoami treated every bearer token as a SAML session, so it showed
an OIDC credential as "SAML Token (primary)", with the keyring as the only
possible source. The OIDC label and source were no longer reachable.

whoami now detects an OIDC credential from the credential chain before it
looks at the headers. The text output shows "OIDC Auto-Discovery" and the
source, such as "OIDC via GitHub Actions (org: ..., service: ...)". The
JSON output gives active_method "oidc" and the source in auth.oidc.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Copilot AI balanced review requested due to automatic review settings October 22, 2026 17:34

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The focused fix matches the credential-chain contract, includes regression coverage, and has no identified blocking issues.

No open issues 🎉

What changed in this PR

Corrects whoami --verbose so OIDC credentials are identified by their credential-chain source rather than mistaken for SAML bearer tokens.

Changes:

  • Displays OIDC authentication and its source in verbose text and JSON output.
  • Adds regression tests for OIDC output and unchanged SAML labeling.
  • Documents the JSON authentication-field changes in the changelog.
File Description
cloudsmith_cli/​cli/​tests/​commands/​test_whoami.py Adds OIDC text/JSON tests and a SAML regression test.
cloudsmith_cli/​cli/​commands/​whoami.py Detects OIDC credentials and reports their authentication source.
CHANGELOG.md Documents the corrected display and JSON fields.

Review effort: Balanced

The OIDC provider reads the token cache before it detects the CI
environment, so a cached token showed "OIDC [cached]" with no vendor.
Most commands in a CI job after the first one use the cached token.

The cache now stores the name of the detector with the token, and
get_cached_token returns both. The source of a cached token is then, for
example, "OIDC via GitHub Actions [cached] (org: ..., service: ...)". An
entry that an earlier version cached has no vendor name and keeps the
old source until it expires.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@cloudsmith-iduffy
cloudsmith-iduffy marked this pull request as ready for review October 22, 2026 18:08
@cloudsmith-iduffy
cloudsmith-iduffy requested a review from a team as a code owner October 22, 2026 18:08
@coillteoir coillteoir self-assigned this Oct 27, 2026
@cloudsmith-iduffy

Copy link
Copy Markdown
Collaborator Author

@copilot resolve the merge conflicts in this pull request

# Conflicts:
#	CHANGELOG.md
#	cloudsmith_cli/core/tests/test_oidc_provider.py

Co-authored-by: cloudsmith-iduffy <178375997+cloudsmith-iduffy@users.noreply.github.com>

Copilot AI commented Oct 28, 2026

Copy link
Copy Markdown
Contributor

@copilot resolve the merge conflicts in this pull request

Merged master and resolved both conflicts in merge commit c65147b. The merge is pushed; targeted pytest could not run because uv and pytest are unavailable.

* origin/master: (25 commits)
  fix(ENG-15484): accept --color on click versions before 8.2 (#582)
  fix(no-ticket): stop retrying unknown hosts and show backoff retries (#542)
  fix(no-ticket): stop credential helpers from overwriting config files that do not parse (#540)
  fix(no-ticket): remove the pnpm launcher when .npmrc does not exist (#539)
  fix(no-ticket): keep the user's Cargo registry credential provider (#532)
  build(deps): bump pyasn1 (#580)
  build(deps): bump the actions-all group with 4 updates (#577)
  build(deps): bump the uv-all group with 7 updates (#578)
  build(deps): bump alpine from `294b683` to `be26560` (#576)
  fix(no-ticket): keep credentials.ini sections and save missing API keys (#533)
  fix(no-ticket): set a default timeout on each API request (#538)
  fix(no-ticket): print the result count when a list is empty (#545)
  fix(no-ticket): escape the args in the terraformrc block (#543)
  fix(no-ticket): show the dependencies help for list deps (#546)
  fix(no-ticket): show a correct summary for the pnpm credential helper (#547)
  fix(no-ticket): show a clean error when the SAML IdP response is not a JSON object (#559)
  fix(no-ticket): show the API error when mcp cannot load the API schema (#561)
  fix(no-ticket): treat an empty trailing OWNER/REPO part as not given (#550)
  fix(no-ticket): print a skipped API error one time in copy, move and resync (#552)
  fix(no-ticket): save credentials.ini with mode 0600 (#553)
  ...

# Conflicts:
#	CHANGELOG.md

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

There are no active review issues for the OIDC authentication-reporting changes.

No open issues 🎉

Review effort: Balanced

# Conflicts:
#	CHANGELOG.md

Co-authored-by: cloudsmith-iduffy <178375997+cloudsmith-iduffy@users.noreply.github.com>
auto-merge was automatically disabled November 3, 2026 16:04

Head branch was pushed to by a user without write access

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

4 participants