Skip to content

Commit f18cf5a

Browse files
scotwellsclaude
andcommitted
fix(auth): polish error messages and add machine-account example
Address review feedback: - Join missing-fields error with commas instead of Go's default slice formatting - Add a hint to the OIDC discovery error pointing at --hostname - Clarify the default scope comment about backward compatibility - Add a login example showing --credentials with --hostname Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 302bef3 commit f18cf5a

File tree

2 files changed

+10
-6
lines changed

2 files changed

+10
-6
lines changed

internal/cmd/auth/login.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,11 @@ cannot be derived from the auth hostname (e.g., in self-hosted environments).`,
7474
datumctl auth login --hostname auth.example.com --client-id 123456789
7575
7676
# Log in to a self-hosted environment with explicit API hostname
77-
datumctl auth login --hostname auth.example.com --api-hostname api.example.com --client-id 123456789`,
77+
datumctl auth login --hostname auth.example.com --api-hostname api.example.com --client-id 123456789
78+
79+
# Log in with a machine account credentials file (hostname is required
80+
# to tell datumctl which environment to authenticate against)
81+
datumctl auth login --credentials ./my-key.json --hostname auth.staging.env.datum.net`,
7882
RunE: func(cmd *cobra.Command, args []string) error {
7983
if credentialsFile != "" {
8084
return runMachineAccountLogin(cmd.Context(), credentialsFile, hostname, apiHostname, debugCredentials)

internal/cmd/auth/machine_account_login.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ import (
1414
"go.datum.net/datumctl/internal/keyring"
1515
)
1616

17-
// defaultMachineAccountScope is the scope string used for machine account token exchanges
18-
// when the credentials file does not specify one. It mirrors the scopes requested by the
19-
// interactive login flow.
17+
// defaultMachineAccountScope is used when the credentials file does not
18+
// specify a scope. The file's scope field is still honored for backward
19+
// compatibility; new credentials files should omit it.
2020
const defaultMachineAccountScope = "openid profile email offline_access"
2121

2222
// runMachineAccountLogin handles the --credentials flag path for `datumctl auth login`.
@@ -55,15 +55,15 @@ func runMachineAccountLogin(ctx context.Context, credentialsPath, hostname, apiH
5555
missing = append(missing, "private_key")
5656
}
5757
if len(missing) > 0 {
58-
return fmt.Errorf("credentials file is missing required fields: %v", missing)
58+
return fmt.Errorf("credentials file is missing required fields: %s", strings.Join(missing, ", "))
5959
}
6060

6161
// Discover the token endpoint from the OIDC provider's well-known config.
6262
// This mirrors the pattern used by the interactive login flow in login.go.
6363
providerURL := fmt.Sprintf("https://%s", hostname)
6464
provider, err := oidc.NewProvider(ctx, providerURL)
6565
if err != nil {
66-
return fmt.Errorf("failed to discover OIDC provider at %s: %w", providerURL, err)
66+
return fmt.Errorf("failed to discover OIDC provider at %s: %w (pass --hostname to point datumctl at your Datum Cloud auth server)", providerURL, err)
6767
}
6868
tokenURI := provider.Endpoint().TokenURL
6969

0 commit comments

Comments
 (0)