Skip to content
This repository was archived by the owner on Jan 23, 2026. It is now read-only.

Implement token exchange based login (machine to machine)#329

Merged
mangelajo merged 5 commits intomainfrom
token-exchange
Mar 7, 2025
Merged

Implement token exchange based login (machine to machine)#329
mangelajo merged 5 commits intomainfrom
token-exchange

Conversation

@NickCao
Copy link
Copy Markdown
Collaborator

@NickCao NickCao commented Mar 6, 2025

Summary by CodeRabbit

  • New Features

    • Introduced a new command-line option to allow token-based authentication, enabling users to log in with an OIDC token.
    • Added support for specifying a connector ID during login, with token-based access now taking precedence over traditional username/password methods.
    • Enhanced OIDC handling capabilities with a new asynchronous method for token exchange.
    • Introduced a new mock class for testing purposes.
  • Bug Fixes

    • Minor formatting changes in error handling for improved readability.
  • Chores

    • Updated Protobuf Python version across multiple files to ensure compatibility with the latest standards.
    • Enhanced documentation with new command-line options for user login to improve user guidance.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 6, 2025

Walkthrough

The changes add new command-line options --token and connector_id across multiple login functions to enable token-based OIDC authentication. The client and exporter login functions now prioritize the token-based flow by invoking token_exchange_grant when a token is provided, falling back to password-based authentication otherwise. Additionally, a new CLI option and a method for handling token exchange were introduced in the common OIDC module. Minor formatting adjustments and a new mock class for testing in the driver package have also been implemented.

Changes

Files Changes
packages/jumpstarter-cli-client/.../client_login.py
packages/jumpstarter-cli-exporter/.../exporter_login.py
Added new --token option and connector_id parameter; updated authentication logic to prioritize token-based auth by calling oidc.token_exchange_grant.
packages/jumpstarter-cli-common/.../oidc.py Added new CLI option opt_connector_id and a new asynchronous method token_exchange_grant for token exchange.
packages/jumpstarter-driver-opendal/.../client.py Applied minor formatting changes by condensing error messages in the flash and dump methods.
packages/jumpstarter-driver-opendal/.../driver.py Introduced a new class MockStorageMuxFlasher as a mock implementation for testing purposes.
packages/jumpstarter-driver-opendal/.../driver_test.py Inserted blank lines between test functions to improve readability.
packages/jumpstarter-protocol/.../jumpstarter_pb2.py
packages/jumpstarter-protocol/.../kubernetes_pb2.py
packages/jumpstarter-protocol/.../router_pb2.py
Updated Protobuf Python version from 5.29.3 to 6.30.0 and adjusted version validation parameters accordingly.

Sequence Diagram(s)

sequenceDiagram
    participant CLI
    participant LoginFunction
    participant OIDC

    CLI->>LoginFunction: Provide credentials (token or username/password)
    alt Token provided
        LoginFunction->>OIDC: Call token_exchange_grant(token, connector_id)
        OIDC-->>LoginFunction: Return authentication result
    else No token provided
        LoginFunction->>OIDC: Call password_grant(username, password)
        OIDC-->>LoginFunction: Return authentication result
    end
    LoginFunction-->>CLI: Return login response
Loading

Possibly related PRs

  • esp32: introduce esp32 driver jumpstarter#294: The changes in the main PR are related to the modifications in the retrieved PR as both involve the introduction of OIDC token handling in the authentication process, specifically through the addition of command-line options and the use of the token_exchange_grant method.
  • build(deps): bump k8s.io/apimachinery from 0.33.0 to 0.35.2 in /controller jumpstarter#282: The changes in the main PR, which involve modifications to the client_login function to support OIDC token authentication, are directly related to the changes in the retrieved PR, which also implements OIDC login functionality and includes similar command-line options and authentication logic.

Suggested reviewers

  • mangelajo

Poem

I'm a bunny hopping in the code,
New tokens sparkle on each node.
With connector_id in my furry paws,
I exchange tokens without a pause.
Hoppy changes make my heart glow!
🥕✨


🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@netlify
Copy link
Copy Markdown

netlify Bot commented Mar 6, 2025

Deploy Preview for jumpstarter-docs ready!

Name Link
🔨 Latest commit cbb8691
🔍 Latest deploy log https://app.netlify.com/sites/jumpstarter-docs/deploys/67cafe8321ae910008b6ffff
😎 Deploy Preview https://deploy-preview-329--jumpstarter-docs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (2)
packages/jumpstarter-cli-exporter/jumpstarter_cli_exporter/exporter_login.py (1)

25-28: Parameter type inconsistency with client_login.

The connector_id parameter is defined as str here, but as str | None in client_login.py. Consider making these consistent to avoid potential issues.

-    connector_id: str,
+    connector_id: str | None,
packages/jumpstarter-cli-client/jumpstarter_cli_client/client_login.py (1)

103-109: Consider adding error handling for token exchange failures.

The token exchange process might fail for various reasons (invalid token, network issues, etc.). Consider adding error handling to provide more detailed error messages to help users diagnose issues.

 if token is not None:
     kwargs = {"connector_id": connector_id} if connector_id is not None else {}
-    tokens = await oidc.token_exchange_grant(token, **kwargs)
+    try:
+        tokens = await oidc.token_exchange_grant(token, **kwargs)
+    except Exception as e:
+        click.echo(f"Token exchange failed: {str(e)}")
+        # Optionally: fall back to other auth methods or exit
+        raise click.Abort()
 elif username is not None and password is not None:
     tokens = await oidc.password_grant(username, password)
 else:
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a43b98d and f4e9891.

📒 Files selected for processing (6)
  • packages/jumpstarter-cli-client/jumpstarter_cli_client/client_login.py (5 hunks)
  • packages/jumpstarter-cli-common/jumpstarter_cli_common/oidc.py (2 hunks)
  • packages/jumpstarter-cli-exporter/jumpstarter_cli_exporter/exporter_login.py (3 hunks)
  • packages/jumpstarter-driver-opendal/jumpstarter_driver_opendal/client.py (3 hunks)
  • packages/jumpstarter-driver-opendal/jumpstarter_driver_opendal/driver.py (1 hunks)
  • packages/jumpstarter-driver-opendal/jumpstarter_driver_opendal/driver_test.py (2 hunks)
✅ Files skipped from review due to trivial changes (2)
  • packages/jumpstarter-driver-opendal/jumpstarter_driver_opendal/driver_test.py
  • packages/jumpstarter-driver-opendal/jumpstarter_driver_opendal/client.py
⏰ Context from checks skipped due to timeout of 90000ms (7)
  • GitHub Check: pytest-matrix (3.13)
  • GitHub Check: e2e
  • GitHub Check: pytest-matrix (3.12)
  • GitHub Check: pytest-matrix (3.11)
  • GitHub Check: build-and-push-image (jumpstarter-dev/jumpstarter-devspace .devfile/Containerfile.client)
  • GitHub Check: build-and-push-image (jumpstarter-dev/jumpstarter-dev .devfile/Containerfile)
  • GitHub Check: build-and-push-image (jumpstarter-dev/jumpstarter Dockerfile)
🔇 Additional comments (12)
packages/jumpstarter-driver-opendal/jumpstarter_driver_opendal/driver.py (1)

281-284: New mock class implementation looks good.

The addition of the MockStorageMuxFlasher class is straightforward and appropriately inherits from both StorageMuxFlasherInterface and MockStorageMux. This implementation follows the pattern of other mock classes in the file and will be useful for testing.

packages/jumpstarter-cli-common/jumpstarter_cli_common/oidc.py (2)

17-20: LGTM: New connector_id option added correctly.

The new command-line option is well documented with a helpful description that specifies it's Dex-specific.


40-54: Token exchange implementation looks good.

The implementation follows the OAuth 2.0 Token Exchange standard (RFC 8693) and maintains a consistent pattern with the existing grant methods. It properly uses run_sync for the token fetching operation.

packages/jumpstarter-cli-exporter/jumpstarter_cli_exporter/exporter_login.py (4)

2-2: Import updated correctly for the new OIDC option.

The import has been updated to include the new opt_connector_id from the common OIDC module.


14-14: Token option added correctly.

The new --token option is well-defined with appropriate help text.


17-17: Connector ID option added correctly.

The opt_connector_id is properly included in the function decorators.


54-56: Token-based authentication logic looks good.

The implementation prioritizes token-based authentication and correctly handles the optional connector_id parameter.

packages/jumpstarter-cli-client/jumpstarter_cli_client/client_login.py (5)

3-3: Import updated correctly for the new OIDC option.

The import has been updated to include the new opt_connector_id from the common OIDC module.


32-32: Token option added correctly.

The new --token option is well-defined with appropriate help text.


49-49: Connector ID option added correctly.

The opt_connector_id is properly included in the function decorators.


58-61: Parameter type is correctly set to optional.

The token and connector_id parameters are properly defined as optional types.


103-105: Token-based authentication logic looks good.

The implementation prioritizes token-based authentication and correctly handles the optional connector_id parameter.

Copy link
Copy Markdown
Member

@mangelajo mangelajo left a comment

Choose a reason for hiding this comment

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

Looks good, but let's document too.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
packages/jumpstarter-cli-exporter/jumpstarter_cli_exporter/exporter_login.py (1)

28-28: Update type annotation for connector_id parameter

The connector_id parameter is typed as str, but at line 55 it's checked for None. The type annotation should be updated to str | None to match how this parameter is used.

-    connector_id: str,
+    connector_id: str | None,
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 184545c and 9e8c763.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (9)
  • packages/jumpstarter-cli-client/jumpstarter_cli_client/client_login.py (5 hunks)
  • packages/jumpstarter-cli-common/jumpstarter_cli_common/oidc.py (2 hunks)
  • packages/jumpstarter-cli-exporter/jumpstarter_cli_exporter/exporter_login.py (3 hunks)
  • packages/jumpstarter-driver-opendal/jumpstarter_driver_opendal/client.py (3 hunks)
  • packages/jumpstarter-driver-opendal/jumpstarter_driver_opendal/driver.py (1 hunks)
  • packages/jumpstarter-driver-opendal/jumpstarter_driver_opendal/driver_test.py (2 hunks)
  • packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/v1/jumpstarter_pb2.py (2 hunks)
  • packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/v1/kubernetes_pb2.py (2 hunks)
  • packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/v1/router_pb2.py (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (7)
  • packages/jumpstarter-driver-opendal/jumpstarter_driver_opendal/driver.py
  • packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/v1/router_pb2.py
  • packages/jumpstarter-driver-opendal/jumpstarter_driver_opendal/driver_test.py
  • packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/v1/kubernetes_pb2.py
  • packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/v1/jumpstarter_pb2.py
  • packages/jumpstarter-driver-opendal/jumpstarter_driver_opendal/client.py
  • packages/jumpstarter-cli-common/jumpstarter_cli_common/oidc.py
⏰ Context from checks skipped due to timeout of 90000ms (7)
  • GitHub Check: pytest-matrix (3.13)
  • GitHub Check: pytest-matrix (3.11)
  • GitHub Check: pytest-matrix (3.12)
  • GitHub Check: e2e
  • GitHub Check: build-and-push-image (jumpstarter-dev/jumpstarter Dockerfile)
  • GitHub Check: build-and-push-image (jumpstarter-dev/jumpstarter-devspace .devfile/Containerfile.client)
  • GitHub Check: build-and-push-image (jumpstarter-dev/jumpstarter-dev .devfile/Containerfile)
🔇 Additional comments (3)
packages/jumpstarter-cli-exporter/jumpstarter_cli_exporter/exporter_login.py (1)

54-57: LGTM: Authentication flow properly prioritizes token-based auth

The implemented authentication flow correctly prioritizes token-based authentication when a token is provided. This approach aligns well with the PR objective of implementing token exchange based login for machine-to-machine communication, while maintaining fallback options for other authentication methods.

packages/jumpstarter-cli-client/jumpstarter_cli_client/client_login.py (2)

58-61: LGTM: Token and connector_id parameters properly typed

The parameter types are correctly defined with token: str | None and connector_id: str | None, accurately representing that these parameters are optional.


103-106: LGTM: Authentication flow implementation is consistent

The token-based authentication flow is correctly implemented and consistent with the implementation in the exporter login function. The prioritization of token exchange over other authentication methods aligns with the PR objectives.

@NickCao
Copy link
Copy Markdown
Collaborator Author

NickCao commented Mar 7, 2025

Looks good, but let's document too.

Done

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (2)
docs/source/config/oidc.md (2)

50-54: Enhance Clarity in CLI Options for Client Login

The added block clearly demonstrates three separate authentication flows for clients:

  • Default interactive login: without additional options, users are directed to the web-based flow.
  • Non-interactive login: allowing direct specification of username and password.
  • Machine-to-machine authentication: via the newly introduced --token <token> option.

While the content is accurate and aligns with the PR objective for token exchange based login, consider formatting these options as a bullet list or separate sub-sections to improve readability and reduce any potential ambiguity for CLI users.


60-60: Verify Consistency of Exporter Login Documentation

The note on line 60 indicates that jmp exporter login now accepts --username, --password, and --token, mirroring the client login options. This consistency is beneficial; ensure that the actual implementation and CLI help messages reflect this clearly. You might also consider adding an explicit CLI example for exporters using the token option to parallel the client login section.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9e8c763 and cbb8691.

📒 Files selected for processing (1)
  • docs/source/config/oidc.md (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (9)
  • GitHub Check: Redirect rules - jumpstarter-docs
  • GitHub Check: Header rules - jumpstarter-docs
  • GitHub Check: Pages changed - jumpstarter-docs
  • GitHub Check: e2e
  • GitHub Check: pytest-matrix (3.13)
  • GitHub Check: pytest-matrix (3.11)
  • GitHub Check: pytest-matrix (3.12)
  • GitHub Check: build-and-push-image (jumpstarter-dev/jumpstarter-devspace .devfile/Containerfile.client)
  • GitHub Check: build-and-push-image (jumpstarter-dev/jumpstarter Dockerfile)

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants