Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion cmd/auth_connections.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,14 @@ func (c AuthConnectionCmd) Create(ctx context.Context, in AuthConnectionCreateIn
}
if in.CredentialPath != "" {
params.ManagedAuthCreateRequest.Credential.Path = kernel.Opt(in.CredentialPath)
} else {
// Default to domain auto-lookup when no explicit --credential-path is
// given. This matches the dashboard's UX, where picking a provider
// without a specific item always means "look up by domain". Without
// this default, the server receives { provider } with no path or
// auto flag, which is a valid-but-inert credential reference that
// causes the managed auth session to never fetch credentials.
params.ManagedAuthCreateRequest.Credential.Auto = kernel.Opt(true)
}
if in.CredentialAuto {
params.ManagedAuthCreateRequest.Credential.Auto = kernel.Opt(true)
Expand Down Expand Up @@ -797,7 +805,7 @@ func init() {
authConnectionsCreateCmd.Flags().String("credential-name", "", "Kernel credential name to use")
authConnectionsCreateCmd.Flags().String("credential-provider", "", "External credential provider name")
authConnectionsCreateCmd.Flags().String("credential-path", "", "Provider-specific path (e.g., VaultName/ItemName)")
authConnectionsCreateCmd.Flags().Bool("credential-auto", false, "Lookup by domain from the specified provider")
authConnectionsCreateCmd.Flags().Bool("credential-auto", false, "Lookup by domain from the specified provider (defaults to true when --credential-provider is set without --credential-path)")
authConnectionsCreateCmd.Flags().String("proxy-id", "", "Proxy ID to use")
authConnectionsCreateCmd.Flags().String("proxy-name", "", "Proxy name to use")
authConnectionsCreateCmd.Flags().Bool("no-save-credentials", false, "Disable saving credentials after successful login")
Expand Down
116 changes: 116 additions & 0 deletions cmd/auth_connections_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,122 @@ func TestAuthConnectionsList_JSONOutput_PrintsRawResponse(t *testing.T) {
assert.Contains(t, out, "\"raf-leaseweb\"")
}

// Regression test for the 1Password auto-lookup UX gap: before this fix,
// `kernel auth connections create --credential-provider foo` sent a
// CredentialReference of { provider } with no auto flag, which the API accepted
// as valid-but-inert — the managed auth session would never fetch credentials
// and would prompt the user for manual input. The dashboard already defaults
// to auto: true for this case (see packages/dashboard/src/components/create-managed-auth-dialog.tsx);
// the CLI now matches that UX.
func TestAuthConnectionsCreate_ProviderWithoutPath_DefaultsAutoTrue(t *testing.T) {
var captured kernel.AuthConnectionNewParams
fake := &FakeAuthConnectionService{
NewFunc: func(ctx context.Context, body kernel.AuthConnectionNewParams, opts ...option.RequestOption) (*kernel.ManagedAuth, error) {
captured = body
return &kernel.ManagedAuth{ID: "conn-new"}, nil
},
}

c := AuthConnectionCmd{svc: fake}
err := c.Create(context.Background(), AuthConnectionCreateInput{
Domain: "google.com",
ProfileName: "my-profile",
CredentialProvider: "my-1p",
Output: "json",
})
require.NoError(t, err)

cred := captured.ManagedAuthCreateRequest.Credential
require.True(t, cred.Provider.Valid())
assert.Equal(t, "my-1p", cred.Provider.Value)
assert.False(t, cred.Path.Valid(), "path should not be set when only --credential-provider is given")
require.True(t, cred.Auto.Valid(), "auto should default to true when provider is set without path")
assert.True(t, cred.Auto.Value)
}

// Explicit --credential-path should keep the credential reference as a pinned
// path lookup (no implicit auto).
func TestAuthConnectionsCreate_ProviderWithPath_DoesNotSetAuto(t *testing.T) {
var captured kernel.AuthConnectionNewParams
fake := &FakeAuthConnectionService{
NewFunc: func(ctx context.Context, body kernel.AuthConnectionNewParams, opts ...option.RequestOption) (*kernel.ManagedAuth, error) {
captured = body
return &kernel.ManagedAuth{ID: "conn-new"}, nil
},
}

c := AuthConnectionCmd{svc: fake}
err := c.Create(context.Background(), AuthConnectionCreateInput{
Domain: "google.com",
ProfileName: "my-profile",
CredentialProvider: "my-1p",
CredentialPath: "Employees/Google Workspace",
Output: "json",
})
require.NoError(t, err)

cred := captured.ManagedAuthCreateRequest.Credential
require.True(t, cred.Provider.Valid())
assert.Equal(t, "my-1p", cred.Provider.Value)
require.True(t, cred.Path.Valid())
assert.Equal(t, "Employees/Google Workspace", cred.Path.Value)
assert.False(t, cred.Auto.Valid(), "auto should remain unset when --credential-path is explicit")
}

// --credential-auto should still be honored (it was a no-op redundant flag
// before the default changed, but callers may pass it for clarity).
func TestAuthConnectionsCreate_ProviderWithExplicitAuto_SetsAuto(t *testing.T) {
var captured kernel.AuthConnectionNewParams
fake := &FakeAuthConnectionService{
NewFunc: func(ctx context.Context, body kernel.AuthConnectionNewParams, opts ...option.RequestOption) (*kernel.ManagedAuth, error) {
captured = body
return &kernel.ManagedAuth{ID: "conn-new"}, nil
},
}

c := AuthConnectionCmd{svc: fake}
err := c.Create(context.Background(), AuthConnectionCreateInput{
Domain: "google.com",
ProfileName: "my-profile",
CredentialProvider: "my-1p",
CredentialAuto: true,
Output: "json",
})
require.NoError(t, err)

cred := captured.ManagedAuthCreateRequest.Credential
require.True(t, cred.Auto.Valid())
assert.True(t, cred.Auto.Value)
}

// --credential-name references a Kernel-managed credential and should never
// carry a provider/auto/path — the default-auto logic must not kick in here.
func TestAuthConnectionsCreate_CredentialName_UnaffectedByAutoDefault(t *testing.T) {
var captured kernel.AuthConnectionNewParams
fake := &FakeAuthConnectionService{
NewFunc: func(ctx context.Context, body kernel.AuthConnectionNewParams, opts ...option.RequestOption) (*kernel.ManagedAuth, error) {
captured = body
return &kernel.ManagedAuth{ID: "conn-new"}, nil
},
}

c := AuthConnectionCmd{svc: fake}
err := c.Create(context.Background(), AuthConnectionCreateInput{
Domain: "google.com",
ProfileName: "my-profile",
CredentialName: "my-google-creds",
Output: "json",
})
require.NoError(t, err)

cred := captured.ManagedAuthCreateRequest.Credential
require.True(t, cred.Name.Valid())
assert.Equal(t, "my-google-creds", cred.Name.Value)
assert.False(t, cred.Provider.Valid())
assert.False(t, cred.Auto.Valid())
assert.False(t, cred.Path.Valid())
}

func TestAuthConnectionsUpdate_MapsParams(t *testing.T) {
var captured kernel.AuthConnectionUpdateParams
fake := &FakeAuthConnectionService{
Expand Down
Loading