Skip to content

Client helpers: shared device-flow login and OS keychain token cache #162

Open

Description

@schmitch

Part of #44. This is the library every Forge client helper builds on: the forge CLI, docker-credential-forge and nuget-plugin-forge. It depends on the device-flow endpoints from #39.

Device authorization grant (RFC 8628)

  • Find Forge's device and token endpoints from the server URL the client was given, through whichever discovery Client login for every format: Nexus-style logins, UI-minted tokens, browser/OAuth login #39 ships (a /.well-known/ document or fixed paths).
  • Request a device code for the scope the caller needs (repository and actions), and show verification_uri_complete and user_code.
  • Poll the token endpoint at interval, handling authorization_pending, slow_down, expired_token and access_denied.
  • Telling the user the code is a callback, not a println!:
    • the Docker helper can only write to stderr;
    • the NuGet plugin has to send the instructions to NuGet as a Log message.
  • Optionally open the browser when a display is really available. That rules out SSH without X forwarding and PowerShell remote sessions.

Token cache

  • Store tokens, and refresh tokens if the server issues them, in the OS keychain: macOS Keychain, Windows Credential Manager, Secret Service on Linux. The keyring crate covers all three.
  • On headless Linux without Secret Service (CI, containers), fall back to a file under $XDG_CONFIG_HOME/forge/ with mode 0600. Use it only when the keychain is unavailable, and say so in the docs.
  • Key entries by Forge host, so several Forge instances work side by side.
  • Renew silently while the refresh token or the Forge session allows it. Otherwise report "login required" to the caller.
  • Offer a non-interactive mode that never blocks: it returns the cached or renewed token, or fails fast.
  • Never store the user's password.

Where the code lives

Proposed: a new library crate in this workspace (e.g. crates/client), so it shares CI, the release version and the e2e harness with the server. #44 lists this as an open question.

Acceptance criteria

  • Unit tests for the device-flow state machine against a mock server (pending, slow_down, expiry, denial).
  • An integration test against the real device endpoints from Client login for every format: Nexus-style logins, UI-minted tokens, browser/OAuth login #39, approved through the mock IdP e2e harness.
  • A keychain round trip tested on Linux, macOS and Windows CI runners, and the file fallback tested on Linux.
  • A test with a timeout shows that non-interactive mode never blocks.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions