-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Labels
enterpriseEnterprise featureEnterprise featurestoryFeature story linked to epicFeature story linked to epic
Milestone
Description
User Story
As an enterprise developer, I want to authenticate using my organization's SSO provider so that I can use qctl without managing separate credentials.
Design
Command Interface
# Configure SSO provider
qctl auth sso configure --provider okta --issuer https://myorg.okta.com
# Login via SSO
qctl auth sso login
# Check SSO status
qctl auth sso status
# Remove SSO configuration
qctl auth sso removeSSO Configuration Flow
┌─────────────────────────────────────────────────────────────────┐
│ SSO Configuration │
├─────────────────────────────────────────────────────────────────┤
│ │
│ qctl auth sso configure │
│ │ │
│ ▼ │
│ ┌─────────────┐ ┌──────────────┐ ┌──────────────────┐ │
│ │ Detect │────▶│ Fetch OIDC │────▶│ Store Provider │ │
│ │ Provider │ │ Metadata │ │ Config │ │
│ └─────────────┘ └──────────────┘ └──────────────────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌─────────────────────────────────────────────────────────────┐│
│ │ Supported Providers: ││
│ │ - Okta (OIDC) ││
│ │ - Azure AD (OIDC/SAML) ││
│ │ - Google Workspace (OIDC) ││
│ │ - OneLogin (OIDC/SAML) ││
│ │ - Custom OIDC (any compliant provider) ││
│ │ - Custom SAML 2.0 ││
│ └─────────────────────────────────────────────────────────────┘│
│ │
└─────────────────────────────────────────────────────────────────┘
Output Format
$ qctl auth sso configure --provider okta --issuer https://myorg.okta.com
Fetching OIDC discovery metadata...
Provider: Okta
Issuer: https://myorg.okta.com
Authorization: https://myorg.okta.com/oauth2/v1/authorize
Token: https://myorg.okta.com/oauth2/v1/token
SSO configured successfully.
Run 'qctl auth sso login' to authenticate.
$ qctl auth sso login
Opening browser for SSO authentication...
Waiting for callback...
Authentication successful!
User: james.maes@acme.com
Organization: ACME Corp
Roles: developer, admin
Token expires: 2026-01-04 10:30:00 UTC
$ qctl auth sso status
Provider: Okta
Status: Authenticated
User: james.maes@acme.com
Organization: ACME Corp
Token expires in: 7h 23m
SAML Flow
┌──────┐ ┌─────────┐ ┌─────────┐ ┌────────┐
│ qctl │ │ Browser │ │ IdP │ │ Voyage │
└──┬───┘ └────┬────┘ └────┬────┘ └───┬────┘
│ │ │ │
│ Start SAML │ │ │
│──────────────▶ │ │
│ │ AuthnRequest │ │
│ │───────────────▶ │
│ │ │ │
│ │ Login Page │ │
│ │◀──────────────│ │
│ │ │ │
│ │ User Authenticates │
│ │───────────────▶ │
│ │ │ │
│ │ SAMLResponse │ │
│ │◀──────────────│ │
│ │ │ │
│ Callback with assertion │ │
│◀─────────────│ │ │
│ │ │ │
│ Exchange assertion for token │
│─────────────────────────────────────────────▶
│ │ │ │
│ Access Token │ │
│◀─────────────────────────────────────────────
Configuration File
# ~/.config/qctl/sso.yaml
provider: okta
type: oidc
issuer: https://myorg.okta.com
client_id: 0oa1234567890abcdef
scopes:
- openid
- profile
- email
- groups
redirect_uri: http://localhost:8400/callbackFiles to Create/Modify
| File | Action | Description |
|---|---|---|
qctl-core/src/main/java/io/qrun/qctl/core/auth/sso/SSOCommand.java |
Create | SSO subcommand group |
qctl-core/src/main/java/io/qrun/qctl/core/auth/sso/ConfigureCommand.java |
Create | SSO configure command |
qctl-core/src/main/java/io/qrun/qctl/core/auth/sso/SSOLoginCommand.java |
Create | SSO login command |
qctl-core/src/main/java/io/qrun/qctl/core/auth/sso/StatusCommand.java |
Create | SSO status command |
qctl-core/src/main/java/io/qrun/qctl/core/auth/sso/OIDCClient.java |
Create | OIDC protocol implementation |
qctl-core/src/main/java/io/qrun/qctl/core/auth/sso/SAMLClient.java |
Create | SAML 2.0 protocol implementation |
qctl-core/src/main/java/io/qrun/qctl/core/auth/sso/ProviderConfig.java |
Create | SSO provider configuration |
qctl-core/src/main/java/io/qrun/qctl/core/auth/sso/CallbackServer.java |
Create | Local HTTP server for callbacks |
qctl-core/src/main/java/io/qrun/qctl/core/auth/sso/ProviderDetector.java |
Create | Auto-detect provider from issuer |
Implementation Tasks
- Create SSOCommand subcommand group under auth
- Implement OIDC discovery metadata fetching
- Implement OIDC authorization code flow with PKCE
- Implement SAML 2.0 SP-initiated flow
- Create local callback server for browser redirect
- Add provider auto-detection from issuer URL
- Implement token exchange with Voyage API
- Store SSO configuration securely
- Add group/role claim mapping
- Handle token refresh for SSO sessions
- Add timeout and error handling for browser flows
- Write unit tests for protocol implementations
Acceptance Criteria
- Can configure Okta as OIDC provider
- Can configure Azure AD as OIDC/SAML provider
- Browser opens automatically for authentication
- Tokens are securely stored after SSO login
- Group claims are mapped to Voyage roles
- Token refresh works transparently
- Clear error messages for SSO failures
- Works in headless environments with device flow fallback
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
enterpriseEnterprise featureEnterprise featurestoryFeature story linked to epicFeature story linked to epic
Type
Projects
Status
No status