From d3ce298232b95026aeccc4d8682587ba8a471084 Mon Sep 17 00:00:00 2001 From: Rongsong Shen Date: Sat, 10 Oct 2026 08:21:17 +0000 Subject: [PATCH] fix(apiserver): reject auth.yaml without a config_file block (bug-1951) Cause: NewConfigFileProvider read cfg.ConfigFile.Users without checking that the optional config_file block was present, so provider: config_file with no block panicked with a nil-pointer dereference at startup. Fix: return a clear configuration error when the block is missing. Test: TestNewConfigFileProvider_Errors/missing_config_file_block. Co-Authored-By: Claude Opus 5.5 (1M context) --- src/frontend/apiserver/backend/auth/config_file.go | 3 +++ .../apiserver/backend/auth/config_file_test.go | 13 +++++++++++++ 2 files changed, 16 insertions(+) diff --git a/src/frontend/apiserver/backend/auth/config_file.go b/src/frontend/apiserver/backend/auth/config_file.go index 7ce6c90c..2468a1d2 100644 --- a/src/frontend/apiserver/backend/auth/config_file.go +++ b/src/frontend/apiserver/backend/auth/config_file.go @@ -36,6 +36,9 @@ func NewConfigFileProvider(data []byte) (*ConfigFileProvider, error) { return nil, fmt.Errorf("failed to parse auth config: %w", err) } + if cfg.ConfigFile == nil { + return nil, fmt.Errorf("provider config_file requires a config_file block with users in auth config") + } if len(cfg.ConfigFile.Users) == 0 { return nil, fmt.Errorf("no users defined in auth config") } diff --git a/src/frontend/apiserver/backend/auth/config_file_test.go b/src/frontend/apiserver/backend/auth/config_file_test.go index 787aff8a..d0a36a90 100644 --- a/src/frontend/apiserver/backend/auth/config_file_test.go +++ b/src/frontend/apiserver/backend/auth/config_file_test.go @@ -1,6 +1,7 @@ package auth import ( + "strings" "testing" ) @@ -97,6 +98,18 @@ func TestNewConfigFileProvider_Errors(t *testing.T) { } }) + // bug-1951: an auth.yaml without a config_file block must be a clear + // configuration error, not a nil-pointer panic. + t.Run("missing config_file block", func(t *testing.T) { + _, err := NewConfigFileProvider([]byte("provider: config_file\n")) + if err == nil { + t.Fatal("expected error for missing config_file block") + } + if !strings.Contains(err.Error(), "config_file") { + t.Errorf("error %q should name the missing config_file block", err) + } + }) + t.Run("empty username", func(t *testing.T) { _, err := NewConfigFileProvider([]byte("provider: config_file\nconfig_file:\n users:\n - username: ''\n password: x")) if err == nil {