← back to Cli Printing Press
fix(cli): stop credential status overclaims (#779)
2ff069e0335b4057b480a057a95ca839c20ccb30 · 2026-05-09 09:55:26 -0700 · Trevin Chow
Files touched
A internal/generator/auth_status_test.goM internal/generator/generator_test.goM internal/generator/templates/auth.go.tmplM internal/generator/templates/auth_client_credentials.go.tmplM internal/generator/templates/auth_simple.go.tmplM internal/generator/templates/doctor.go.tmplM testdata/golden/expected/generate-golden-api-oauth2-cc/printing-press-oauth2-cc/internal/cli/auth.goM testdata/golden/expected/generate-golden-api-rich-auth/printing-press-rich-auth/internal/cli/auth.goM testdata/golden/expected/generate-golden-api-rich-auth/printing-press-rich-auth/internal/cli/doctor.goM testdata/golden/expected/generate-golden-api/printing-press-golden/internal/cli/auth.goM testdata/golden/expected/generate-golden-api/printing-press-golden/internal/cli/doctor.goM testdata/golden/expected/generate-tier-routing-api/tier-routing-golden/internal/cli/doctor.go
Diff
commit 2ff069e0335b4057b480a057a95ca839c20ccb30
Author: Trevin Chow <trevin@trevinchow.com>
Date: Sat May 9 09:55:26 2026 -0700
fix(cli): stop credential status overclaims (#779)
---
internal/generator/auth_status_test.go | 69 ++++++++++++++++++++++
internal/generator/generator_test.go | 26 ++++----
internal/generator/templates/auth.go.tmpl | 7 ++-
.../templates/auth_client_credentials.go.tmpl | 5 +-
internal/generator/templates/auth_simple.go.tmpl | 5 +-
internal/generator/templates/doctor.go.tmpl | 23 +-------
.../printing-press-oauth2-cc/internal/cli/auth.go | 5 +-
.../printing-press-rich-auth/internal/cli/auth.go | 5 +-
.../internal/cli/doctor.go | 35 +----------
.../printing-press-golden/internal/cli/auth.go | 5 +-
.../printing-press-golden/internal/cli/doctor.go | 36 +----------
.../tier-routing-golden/internal/cli/doctor.go | 35 +----------
12 files changed, 104 insertions(+), 152 deletions(-)
diff --git a/internal/generator/auth_status_test.go b/internal/generator/auth_status_test.go
new file mode 100644
index 00000000..26006a48
--- /dev/null
+++ b/internal/generator/auth_status_test.go
@@ -0,0 +1,69 @@
+package generator
+
+import (
+ "os"
+ "path/filepath"
+ "testing"
+
+ "github.com/stretchr/testify/require"
+)
+
+func TestDoctorWithoutVerifyPathDoesNotClaimCredentialsValid(t *testing.T) {
+ t.Parallel()
+
+ apiSpec := minimalSpec("doctor-no-verify")
+
+ outputDir := filepath.Join(t.TempDir(), "doctor-no-verify-pp-cli")
+ require.NoError(t, New(apiSpec, outputDir).Generate())
+
+ doctorSrc, err := os.ReadFile(filepath.Join(outputDir, "internal", "cli", "doctor.go"))
+ require.NoError(t, err)
+ src := string(doctorSrc)
+
+ require.Contains(t, src, `report["credentials"] = "present (not verified — set auth.verify_path in spec for an API acceptance check)"`,
+ "doctor must not report API credential validity from a bare base URL probe")
+ require.NotContains(t, src, `report["credentials"] = "valid"`,
+ "without auth.verify_path, a 2xx base URL response does not prove the API accepted the credentials")
+ require.NotContains(t, src, "but auth was accepted",
+ "without auth.verify_path, non-auth HTTP statuses do not prove the API accepted the credentials")
+}
+
+func TestDoctorWithVerifyPathCanClaimCredentialsValid(t *testing.T) {
+ t.Parallel()
+
+ apiSpec := minimalSpec("doctor-verify")
+ apiSpec.Auth.VerifyPath = "/account"
+
+ outputDir := filepath.Join(t.TempDir(), "doctor-verify-pp-cli")
+ require.NoError(t, New(apiSpec, outputDir).Generate())
+
+ doctorSrc, err := os.ReadFile(filepath.Join(outputDir, "internal", "cli", "doctor.go"))
+ require.NoError(t, err)
+ src := string(doctorSrc)
+
+ require.Contains(t, src, `verifyPath := "/account"`)
+ require.Contains(t, src, `report["credentials"] = "valid"`,
+ "doctor may report valid credentials after a configured authenticated verification probe succeeds")
+ require.Contains(t, src, "but auth was accepted",
+ "non-auth HTTP statuses only imply accepted auth when they come from the configured verification path")
+
+ runGoCommand(t, outputDir, "mod", "tidy")
+ runGoCommand(t, outputDir, "build", "./...")
+}
+
+func TestAuthStatusReportsCredentialsPresentNotVerified(t *testing.T) {
+ t.Parallel()
+
+ apiSpec := minimalSpec("auth-status")
+
+ outputDir := filepath.Join(t.TempDir(), "auth-status-pp-cli")
+ require.NoError(t, New(apiSpec, outputDir).Generate())
+
+ authSrc, err := os.ReadFile(filepath.Join(outputDir, "internal", "cli", "auth.go"))
+ require.NoError(t, err)
+ src := string(authSrc)
+
+ require.Contains(t, src, "Credentials present (not verified)")
+ require.Contains(t, src, `"verified": false`)
+ require.NotContains(t, src, `fmt.Fprintln(w, green("Authenticated"))`)
+}
diff --git a/internal/generator/generator_test.go b/internal/generator/generator_test.go
index 9db7f1cb..69e76148 100644
--- a/internal/generator/generator_test.go
+++ b/internal/generator/generator_test.go
@@ -4535,13 +4535,11 @@ func TestGeneratedDoctor_InterstitialMarkersAreTitleAnchored(t *testing.T) {
"DataDome marker should require a context word (blocked/captcha/challenge) alongside the vendor name")
}
-func TestGeneratedDoctor_NoVerifyPathSoftens401(t *testing.T) {
+func TestGeneratedDoctor_NoVerifyPathReportsCredentialsPresent(t *testing.T) {
t.Parallel()
- // Without auth.verify_path, the doctor probe falls back to the bare base
- // URL. 401/403 from the base URL must be reported as "inconclusive", not
- // "invalid", because many APIs return 401 from un-routed roots regardless
- // of token validity.
+ // Without auth.verify_path, doctor still checks API reachability, but it
+ // must not turn any bare base URL response into a credential-validity claim.
apiSpec := &spec.APISpec{
Name: "softdoc",
Version: "0.1.0",
@@ -4573,19 +4571,14 @@ func TestGeneratedDoctor_NoVerifyPathSoftens401(t *testing.T) {
require.NoError(t, err)
content := string(doctorGo)
- // Without spec verify_path, the doctor probes "/" via the configured
- // client. The client is the same Surf-aware *client.Client used by
- // regular commands -- not a fresh stdlib http.Client.
- assert.Contains(t, content, `verifyPath := "/"`)
- assert.Contains(t, content, `c.GetWithHeaders(verifyPath`)
+ // Without spec verify_path, doctor reports local credential presence
+ // without pretending the API accepted the key.
+ assert.NotContains(t, content, `verifyPath := "/"`)
+ assert.NotContains(t, content, `c.GetWithHeaders(verifyPath`)
assert.NotContains(t, content, `&http.Client{`)
- // 401/403 fallback must be the soft "inconclusive" verdict
- assert.Contains(t, content, `"inconclusive (HTTP %d from base URL — set auth.verify_path in spec for a definitive probe)"`)
- // And must NOT use the strict "invalid" wording
+ assert.Contains(t, content, `"present (not verified — set auth.verify_path in spec for an API acceptance check)"`)
+ assert.NotContains(t, content, `"inconclusive (HTTP %d from base URL — set auth.verify_path in spec for a definitive probe)"`)
assert.NotContains(t, content, `"invalid (HTTP %d) — check your credentials"`)
- // Renderer must classify "inconclusive" as WARN before the FAIL clause
- assert.Contains(t, content, `case strings.HasPrefix(s, "inconclusive"):`)
- assert.Contains(t, content, `indicator = yellow("WARN")`)
}
func TestGeneratedDoctor_NoAuthShowsNotRequired(t *testing.T) {
@@ -4797,6 +4790,7 @@ func TestGenerateRequiredUserAgentHeaderBeatsDefaultUserAgent(t *testing.T) {
{Name: "User-Agent", Value: "Mozilla/5.0 Browser Sniff"},
{Name: "Referer", Value: "https://www.example.com/"},
}
+ apiSpec.Auth.VerifyPath = "/items"
outputDir := filepath.Join(t.TempDir(), "browserheaders-pp-cli")
require.NoError(t, New(apiSpec, outputDir).Generate())
diff --git a/internal/generator/templates/auth.go.tmpl b/internal/generator/templates/auth.go.tmpl
index 5b25b5ce..e9d9e09d 100644
--- a/internal/generator/templates/auth.go.tmpl
+++ b/internal/generator/templates/auth.go.tmpl
@@ -193,10 +193,11 @@ func newAuthStatusCmd(flags *rootFlags) *cobra.Command {
w := cmd.OutOrStdout()
authed := cfg.AccessToken != ""
- // JSON envelope: {authenticated, source, config}.
+ // JSON envelope: {authenticated, verified, source, config}.
if flags.asJSON {
out := map[string]any{
"authenticated": authed,
+ "verified": false,
"source": cfg.AuthSource,
"config": cfg.Path,
}
@@ -209,9 +210,9 @@ func newAuthStatusCmd(flags *rootFlags) *cobra.Command {
}
if cfg.TokenExpiry.IsZero() {
- fmt.Fprintf(w, " %s Authenticated (no expiry info)\n", green("OK"))
+ fmt.Fprintf(w, " %s Credentials present (not verified; no expiry info)\n", green("OK"))
} else if time.Now().Before(cfg.TokenExpiry) {
- fmt.Fprintf(w, " %s Authenticated (expires %s)\n", green("OK"), cfg.TokenExpiry.Format(time.RFC3339))
+ fmt.Fprintf(w, " %s Credentials present (not verified; expires %s)\n", green("OK"), cfg.TokenExpiry.Format(time.RFC3339))
} else {
if cfg.RefreshToken != "" {
fmt.Fprintf(w, " %s Token expired (will auto-refresh on next request)\n", yellow("WARN"))
diff --git a/internal/generator/templates/auth_client_credentials.go.tmpl b/internal/generator/templates/auth_client_credentials.go.tmpl
index 89b3ffcd..65335dc5 100644
--- a/internal/generator/templates/auth_client_credentials.go.tmpl
+++ b/internal/generator/templates/auth_client_credentials.go.tmpl
@@ -173,12 +173,13 @@ func newAuthStatusCmd(flags *rootFlags) *cobra.Command {
w := cmd.OutOrStdout()
header := cfg.AuthHeader()
authed := header != ""
- // JSON envelope: {authenticated, source, config}. When not
+ // JSON envelope: {authenticated, verified, source, config}. When not
// authenticated, write the envelope first then return authErr
// so exit code carries the auth-failure signal.
if flags.asJSON {
out := map[string]any{
"authenticated": authed,
+ "verified": false,
"source": cfg.AuthSource,
"config": cfg.Path,
}
@@ -204,7 +205,7 @@ func newAuthStatusCmd(flags *rootFlags) *cobra.Command {
return authErr(fmt.Errorf("no credentials configured"))
}
- fmt.Fprintln(w, green("Authenticated"))
+ fmt.Fprintln(w, green("Credentials present (not verified)"))
fmt.Fprintf(w, " Source: %s\n", cfg.AuthSource)
fmt.Fprintf(w, " Config: %s\n", cfg.Path)
if !cfg.TokenExpiry.IsZero() {
diff --git a/internal/generator/templates/auth_simple.go.tmpl b/internal/generator/templates/auth_simple.go.tmpl
index 7bb49314..db6109ee 100644
--- a/internal/generator/templates/auth_simple.go.tmpl
+++ b/internal/generator/templates/auth_simple.go.tmpl
@@ -40,12 +40,13 @@ func newAuthStatusCmd(flags *rootFlags) *cobra.Command {
w := cmd.OutOrStdout()
header := cfg.AuthHeader()
authed := header != ""
- // JSON envelope: {authenticated, source, config}. When not
+ // JSON envelope: {authenticated, verified, source, config}. When not
// authenticated, write the envelope first then return authErr
// so exit code carries the auth-failure signal.
if flags.asJSON {
out := map[string]any{
"authenticated": authed,
+ "verified": false,
"source": cfg.AuthSource,
"config": cfg.Path,
}
@@ -76,7 +77,7 @@ func newAuthStatusCmd(flags *rootFlags) *cobra.Command {
return authErr(fmt.Errorf("no credentials configured"))
}
- fmt.Fprintln(w, green("Authenticated"))
+ fmt.Fprintln(w, green("Credentials present (not verified)"))
fmt.Fprintf(w, " Source: %s\n", cfg.AuthSource)
fmt.Fprintf(w, " Config: %s\n", cfg.Path)
return nil
diff --git a/internal/generator/templates/doctor.go.tmpl b/internal/generator/templates/doctor.go.tmpl
index 9d403d58..47ac975d 100644
--- a/internal/generator/templates/doctor.go.tmpl
+++ b/internal/generator/templates/doctor.go.tmpl
@@ -391,9 +391,6 @@ func newDoctorCmd(flags *rootFlags) *cobra.Command {
if !strings.HasPrefix(verifyPath, "/") {
verifyPath = "/" + verifyPath
}
-{{- else}}
- verifyPath := "/"
-{{- end}}
authParams := map[string]string{}
authHeaders := map[string]string{}
{{- if and .Auth .Auth.In (eq .Auth.In "query")}}
@@ -415,18 +412,7 @@ func newDoctorCmd(flags *rootFlags) *cobra.Command {
case errors.As(authErr, &authAPIErr):
switch {
case authAPIErr.StatusCode == 401 || authAPIErr.StatusCode == 403:
-{{- if .Auth.VerifyPath}}
report["credentials"] = fmt.Sprintf("invalid (HTTP %d) — check your credentials", authAPIErr.StatusCode)
-{{- else}}
- // The probe hit the bare base URL because no auth.verify_path
- // is configured in the spec. Many APIs return 401/403 from a
- // bare versioned root regardless of token validity (the path
- // isn't routed but the gateway still demands credentials).
- // Don't claim invalid without certainty — set verify_path to
- // a known-good authenticated GET (e.g. /me, /v1/account, /user)
- // for a definitive verdict.
- report["credentials"] = fmt.Sprintf("inconclusive (HTTP %d from base URL — set auth.verify_path in spec for a definitive probe)", authAPIErr.StatusCode)
-{{- end}}
default:
// Non-auth HTTP error (404, 500, etc.) — don't blame credentials
report["credentials"] = fmt.Sprintf("ok (HTTP %d from %s, but auth was accepted)", authAPIErr.StatusCode, verifyPath)
@@ -434,6 +420,9 @@ func newDoctorCmd(flags *rootFlags) *cobra.Command {
default:
report["credentials"] = fmt.Sprintf("error: %s", authErr)
}
+{{- else}}
+ report["credentials"] = "present (not verified — set auth.verify_path in spec for an API acceptance check)"
+{{- end}}
{{- end}}
}
}
@@ -485,12 +474,6 @@ func newDoctorCmd(flags *rootFlags) *cobra.Command {
case strings.HasPrefix(s, "optional"):
// Optional-auth CLI with no key set — informational, not a failure.
indicator = yellow("INFO")
- case strings.HasPrefix(s, "inconclusive"):
- // The credential probe could not produce a definitive verdict
- // (typically because the bare base URL returns 401/403 even for
- // valid tokens). Surface as WARN, not FAIL — the user's actual
- // commands will reveal a real auth failure if one exists.
- indicator = yellow("WARN")
case strings.Contains(s, "error") || strings.Contains(s, "not configured") || strings.Contains(s, "unreachable") || strings.Contains(s, "invalid") || strings.Contains(s, "missing"):
indicator = red("FAIL")
case s == "not required":
diff --git a/testdata/golden/expected/generate-golden-api-oauth2-cc/printing-press-oauth2-cc/internal/cli/auth.go b/testdata/golden/expected/generate-golden-api-oauth2-cc/printing-press-oauth2-cc/internal/cli/auth.go
index 0fdeac71..9c60c980 100644
--- a/testdata/golden/expected/generate-golden-api-oauth2-cc/printing-press-oauth2-cc/internal/cli/auth.go
+++ b/testdata/golden/expected/generate-golden-api-oauth2-cc/printing-press-oauth2-cc/internal/cli/auth.go
@@ -155,12 +155,13 @@ func newAuthStatusCmd(flags *rootFlags) *cobra.Command {
w := cmd.OutOrStdout()
header := cfg.AuthHeader()
authed := header != ""
- // JSON envelope: {authenticated, source, config}. When not
+ // JSON envelope: {authenticated, verified, source, config}. When not
// authenticated, write the envelope first then return authErr
// so exit code carries the auth-failure signal.
if flags.asJSON {
out := map[string]any{
"authenticated": authed,
+ "verified": false,
"source": cfg.AuthSource,
"config": cfg.Path,
}
@@ -182,7 +183,7 @@ func newAuthStatusCmd(flags *rootFlags) *cobra.Command {
return authErr(fmt.Errorf("no credentials configured"))
}
- fmt.Fprintln(w, green("Authenticated"))
+ fmt.Fprintln(w, green("Credentials present (not verified)"))
fmt.Fprintf(w, " Source: %s\n", cfg.AuthSource)
fmt.Fprintf(w, " Config: %s\n", cfg.Path)
if !cfg.TokenExpiry.IsZero() {
diff --git a/testdata/golden/expected/generate-golden-api-rich-auth/printing-press-rich-auth/internal/cli/auth.go b/testdata/golden/expected/generate-golden-api-rich-auth/printing-press-rich-auth/internal/cli/auth.go
index baeb813d..7cbab816 100644
--- a/testdata/golden/expected/generate-golden-api-rich-auth/printing-press-rich-auth/internal/cli/auth.go
+++ b/testdata/golden/expected/generate-golden-api-rich-auth/printing-press-rich-auth/internal/cli/auth.go
@@ -38,12 +38,13 @@ func newAuthStatusCmd(flags *rootFlags) *cobra.Command {
w := cmd.OutOrStdout()
header := cfg.AuthHeader()
authed := header != ""
- // JSON envelope: {authenticated, source, config}. When not
+ // JSON envelope: {authenticated, verified, source, config}. When not
// authenticated, write the envelope first then return authErr
// so exit code carries the auth-failure signal.
if flags.asJSON {
out := map[string]any{
"authenticated": authed,
+ "verified": false,
"source": cfg.AuthSource,
"config": cfg.Path,
}
@@ -67,7 +68,7 @@ func newAuthStatusCmd(flags *rootFlags) *cobra.Command {
return authErr(fmt.Errorf("no credentials configured"))
}
- fmt.Fprintln(w, green("Authenticated"))
+ fmt.Fprintln(w, green("Credentials present (not verified)"))
fmt.Fprintf(w, " Source: %s\n", cfg.AuthSource)
fmt.Fprintf(w, " Config: %s\n", cfg.Path)
return nil
diff --git a/testdata/golden/expected/generate-golden-api-rich-auth/printing-press-rich-auth/internal/cli/doctor.go b/testdata/golden/expected/generate-golden-api-rich-auth/printing-press-rich-auth/internal/cli/doctor.go
index e39aa22f..6fb0f8e5 100644
--- a/testdata/golden/expected/generate-golden-api-rich-auth/printing-press-rich-auth/internal/cli/doctor.go
+++ b/testdata/golden/expected/generate-golden-api-rich-auth/printing-press-rich-auth/internal/cli/doctor.go
@@ -224,34 +224,7 @@ func newDoctorCmd(flags *rootFlags) *cobra.Command {
} else if reachErr != nil && !errors.As(reachErr, &reachAPIErr) {
report["credentials"] = "skipped (API unreachable)"
} else {
- verifyPath := "/"
- authParams := map[string]string{}
- authHeaders := map[string]string{}
- authHeaders["Authorization"] = authHeader
- authHeaders["User-Agent"] = "printing-press-rich-pp-cli"
- _, authErr := c.GetWithHeaders(verifyPath, authParams, authHeaders)
- var authAPIErr *client.APIError
- switch {
- case authErr == nil:
- report["credentials"] = "valid"
- case errors.As(authErr, &authAPIErr):
- switch {
- case authAPIErr.StatusCode == 401 || authAPIErr.StatusCode == 403:
- // The probe hit the bare base URL because no auth.verify_path
- // is configured in the spec. Many APIs return 401/403 from a
- // bare versioned root regardless of token validity (the path
- // isn't routed but the gateway still demands credentials).
- // Don't claim invalid without certainty — set verify_path to
- // a known-good authenticated GET (e.g. /me, /v1/account, /user)
- // for a definitive verdict.
- report["credentials"] = fmt.Sprintf("inconclusive (HTTP %d from base URL — set auth.verify_path in spec for a definitive probe)", authAPIErr.StatusCode)
- default:
- // Non-auth HTTP error (404, 500, etc.) — don't blame credentials
- report["credentials"] = fmt.Sprintf("ok (HTTP %d from %s, but auth was accepted)", authAPIErr.StatusCode, verifyPath)
- }
- default:
- report["credentials"] = fmt.Sprintf("error: %s", authErr)
- }
+ report["credentials"] = "present (not verified — set auth.verify_path in spec for an API acceptance check)"
}
}
} else if cfg != nil && cfg.BaseURL == "" {
@@ -296,12 +269,6 @@ func newDoctorCmd(flags *rootFlags) *cobra.Command {
case strings.HasPrefix(s, "optional"):
// Optional-auth CLI with no key set — informational, not a failure.
indicator = yellow("INFO")
- case strings.HasPrefix(s, "inconclusive"):
- // The credential probe could not produce a definitive verdict
- // (typically because the bare base URL returns 401/403 even for
- // valid tokens). Surface as WARN, not FAIL — the user's actual
- // commands will reveal a real auth failure if one exists.
- indicator = yellow("WARN")
case strings.Contains(s, "error") || strings.Contains(s, "not configured") || strings.Contains(s, "unreachable") || strings.Contains(s, "invalid") || strings.Contains(s, "missing"):
indicator = red("FAIL")
case s == "not required":
diff --git a/testdata/golden/expected/generate-golden-api/printing-press-golden/internal/cli/auth.go b/testdata/golden/expected/generate-golden-api/printing-press-golden/internal/cli/auth.go
index 5b90a744..7bb622d5 100644
--- a/testdata/golden/expected/generate-golden-api/printing-press-golden/internal/cli/auth.go
+++ b/testdata/golden/expected/generate-golden-api/printing-press-golden/internal/cli/auth.go
@@ -38,12 +38,13 @@ func newAuthStatusCmd(flags *rootFlags) *cobra.Command {
w := cmd.OutOrStdout()
header := cfg.AuthHeader()
authed := header != ""
- // JSON envelope: {authenticated, source, config}. When not
+ // JSON envelope: {authenticated, verified, source, config}. When not
// authenticated, write the envelope first then return authErr
// so exit code carries the auth-failure signal.
if flags.asJSON {
out := map[string]any{
"authenticated": authed,
+ "verified": false,
"source": cfg.AuthSource,
"config": cfg.Path,
}
@@ -64,7 +65,7 @@ func newAuthStatusCmd(flags *rootFlags) *cobra.Command {
return authErr(fmt.Errorf("no credentials configured"))
}
- fmt.Fprintln(w, green("Authenticated"))
+ fmt.Fprintln(w, green("Credentials present (not verified)"))
fmt.Fprintf(w, " Source: %s\n", cfg.AuthSource)
fmt.Fprintf(w, " Config: %s\n", cfg.Path)
return nil
diff --git a/testdata/golden/expected/generate-golden-api/printing-press-golden/internal/cli/doctor.go b/testdata/golden/expected/generate-golden-api/printing-press-golden/internal/cli/doctor.go
index 158362ac..09b86a28 100644
--- a/testdata/golden/expected/generate-golden-api/printing-press-golden/internal/cli/doctor.go
+++ b/testdata/golden/expected/generate-golden-api/printing-press-golden/internal/cli/doctor.go
@@ -172,35 +172,7 @@ func newDoctorCmd(flags *rootFlags) *cobra.Command {
} else if reachErr != nil && !errors.As(reachErr, &reachAPIErr) {
report["credentials"] = "skipped (API unreachable)"
} else {
- verifyPath := "/"
- authParams := map[string]string{}
- authHeaders := map[string]string{}
- authHeaders["X-API-Key"] = authHeader
- authHeaders["X-Api-Version"] = "2026-04-01"
- authHeaders["User-Agent"] = "printing-press-golden-pp-cli"
- _, authErr := c.GetWithHeaders(verifyPath, authParams, authHeaders)
- var authAPIErr *client.APIError
- switch {
- case authErr == nil:
- report["credentials"] = "valid"
- case errors.As(authErr, &authAPIErr):
- switch {
- case authAPIErr.StatusCode == 401 || authAPIErr.StatusCode == 403:
- // The probe hit the bare base URL because no auth.verify_path
- // is configured in the spec. Many APIs return 401/403 from a
- // bare versioned root regardless of token validity (the path
- // isn't routed but the gateway still demands credentials).
- // Don't claim invalid without certainty — set verify_path to
- // a known-good authenticated GET (e.g. /me, /v1/account, /user)
- // for a definitive verdict.
- report["credentials"] = fmt.Sprintf("inconclusive (HTTP %d from base URL — set auth.verify_path in spec for a definitive probe)", authAPIErr.StatusCode)
- default:
- // Non-auth HTTP error (404, 500, etc.) — don't blame credentials
- report["credentials"] = fmt.Sprintf("ok (HTTP %d from %s, but auth was accepted)", authAPIErr.StatusCode, verifyPath)
- }
- default:
- report["credentials"] = fmt.Sprintf("error: %s", authErr)
- }
+ report["credentials"] = "present (not verified — set auth.verify_path in spec for an API acceptance check)"
}
}
} else if cfg != nil && cfg.BaseURL == "" {
@@ -245,12 +217,6 @@ func newDoctorCmd(flags *rootFlags) *cobra.Command {
case strings.HasPrefix(s, "optional"):
// Optional-auth CLI with no key set — informational, not a failure.
indicator = yellow("INFO")
- case strings.HasPrefix(s, "inconclusive"):
- // The credential probe could not produce a definitive verdict
- // (typically because the bare base URL returns 401/403 even for
- // valid tokens). Surface as WARN, not FAIL — the user's actual
- // commands will reveal a real auth failure if one exists.
- indicator = yellow("WARN")
case strings.Contains(s, "error") || strings.Contains(s, "not configured") || strings.Contains(s, "unreachable") || strings.Contains(s, "invalid") || strings.Contains(s, "missing"):
indicator = red("FAIL")
case s == "not required":
diff --git a/testdata/golden/expected/generate-tier-routing-api/tier-routing-golden/internal/cli/doctor.go b/testdata/golden/expected/generate-tier-routing-api/tier-routing-golden/internal/cli/doctor.go
index e5d70b24..65c4ec8c 100644
--- a/testdata/golden/expected/generate-tier-routing-api/tier-routing-golden/internal/cli/doctor.go
+++ b/testdata/golden/expected/generate-tier-routing-api/tier-routing-golden/internal/cli/doctor.go
@@ -194,34 +194,7 @@ func newDoctorCmd(flags *rootFlags) *cobra.Command {
} else if reachErr != nil && !errors.As(reachErr, &reachAPIErr) {
report["credentials"] = "skipped (API unreachable)"
} else {
- verifyPath := "/"
- authParams := map[string]string{}
- authHeaders := map[string]string{}
- authHeaders["Authorization"] = authHeader
- authHeaders["User-Agent"] = "tier-routing-golden-pp-cli"
- _, authErr := c.GetWithHeaders(verifyPath, authParams, authHeaders)
- var authAPIErr *client.APIError
- switch {
- case authErr == nil:
- report["credentials"] = "valid"
- case errors.As(authErr, &authAPIErr):
- switch {
- case authAPIErr.StatusCode == 401 || authAPIErr.StatusCode == 403:
- // The probe hit the bare base URL because no auth.verify_path
- // is configured in the spec. Many APIs return 401/403 from a
- // bare versioned root regardless of token validity (the path
- // isn't routed but the gateway still demands credentials).
- // Don't claim invalid without certainty — set verify_path to
- // a known-good authenticated GET (e.g. /me, /v1/account, /user)
- // for a definitive verdict.
- report["credentials"] = fmt.Sprintf("inconclusive (HTTP %d from base URL — set auth.verify_path in spec for a definitive probe)", authAPIErr.StatusCode)
- default:
- // Non-auth HTTP error (404, 500, etc.) — don't blame credentials
- report["credentials"] = fmt.Sprintf("ok (HTTP %d from %s, but auth was accepted)", authAPIErr.StatusCode, verifyPath)
- }
- default:
- report["credentials"] = fmt.Sprintf("error: %s", authErr)
- }
+ report["credentials"] = "present (not verified — set auth.verify_path in spec for an API acceptance check)"
}
}
} else if cfg != nil && cfg.BaseURL == "" {
@@ -266,12 +239,6 @@ func newDoctorCmd(flags *rootFlags) *cobra.Command {
case strings.HasPrefix(s, "optional"):
// Optional-auth CLI with no key set — informational, not a failure.
indicator = yellow("INFO")
- case strings.HasPrefix(s, "inconclusive"):
- // The credential probe could not produce a definitive verdict
- // (typically because the bare base URL returns 401/403 even for
- // valid tokens). Surface as WARN, not FAIL — the user's actual
- // commands will reveal a real auth failure if one exists.
- indicator = yellow("WARN")
case strings.Contains(s, "error") || strings.Contains(s, "not configured") || strings.Contains(s, "unreachable") || strings.Contains(s, "invalid") || strings.Contains(s, "missing"):
indicator = red("FAIL")
case s == "not required":
← 3b929c6e chore(main): release 4.2.0 (#772)
·
back to Cli Printing Press
·
fix(cli): handle Windows shipcheck paths (#783) d0086ffe →