As a developer, I want to authenticate with qctl using my browser so I can securely access Voyage APIs without managing passwords in the CLI.
# Start login flow qctl auth login # Login to specific provider qctl auth login --provider voyage # Check authentication status qctl auth status # Logout (clear tokens) qctl auth logout # Refresh token manually qctl auth refresh
Logging in to Voyage... Please visit: https://voyage.qrun.io/device Enter code: ABCD-1234 Waiting for authorization... (press Ctrl+C to cancel) [Browser opens automatically] Authenticated as: james.maes@example.com Organization: acme-corp Token stored in: macOS Keychain Login successful!
# ~/.qctl/qctl.yaml auth: provider: voyage providers: voyage: issuer: https://auth.qrun.io client_id: qctl-cli scopes: - openid - profile - qctl:read - qctl:write device_auth_endpoint: /oauth/device/code token_endpoint: /oauth/token
# Tokens stored in OS keychain with entries: qctl:voyage:access_token qctl:voyage:refresh_token qctl:voyage:id_token qctl:voyage:expires_at
qctl-core/src/main/java/io/qrun/qctl/core/auth/AuthCommand.java
qctl-core/src/main/java/io/qrun/qctl/core/auth/LoginCommand.java
qctl-core/src/main/java/io/qrun/qctl/core/auth/LogoutCommand.java
qctl-core/src/main/java/io/qrun/qctl/core/auth/StatusCommand.java
qctl-core/src/main/java/io/qrun/qctl/core/auth/DeviceFlow.java
qctl-core/src/main/java/io/qrun/qctl/core/auth/TokenManager.java
qctl-core/src/main/java/io/qrun/qctl/core/auth/OIDCClient.java
qctl-core/src/main/java/io/qrun/qctl/core/auth/model/DeviceCode.java
qctl-core/src/main/java/io/qrun/qctl/core/auth/model/TokenResponse.java
qctl auth login
qctl auth status
qctl auth logout
No dependencies set.
The note is not visible to the blocked user.
User Story
As a developer, I want to authenticate with qctl using my browser so I can securely access Voyage APIs without managing passwords in the CLI.
Design
Command Interface
Device Flow Output
OIDC Configuration
Token Storage
Files to Create/Modify
qctl-core/src/main/java/io/qrun/qctl/core/auth/AuthCommand.javaqctl-core/src/main/java/io/qrun/qctl/core/auth/LoginCommand.javaqctl-core/src/main/java/io/qrun/qctl/core/auth/LogoutCommand.javaqctl-core/src/main/java/io/qrun/qctl/core/auth/StatusCommand.javaqctl-core/src/main/java/io/qrun/qctl/core/auth/DeviceFlow.javaqctl-core/src/main/java/io/qrun/qctl/core/auth/TokenManager.javaqctl-core/src/main/java/io/qrun/qctl/core/auth/OIDCClient.javaqctl-core/src/main/java/io/qrun/qctl/core/auth/model/DeviceCode.javaqctl-core/src/main/java/io/qrun/qctl/core/auth/model/TokenResponse.javaImplementation Tasks
Acceptance Criteria
qctl auth loginstarts device authorization flowqctl auth statusshows current auth stateqctl auth logoutclears stored tokens