From ce9ee2481adeef328a57513d243c4df966dc3331 Mon Sep 17 00:00:00 2001 From: rcourtman Date: Wed, 4 Feb 2026 16:11:41 +0000 Subject: [PATCH] Enforce proxy user RBAC via RequirePermission --- internal/api/security_regression_test.go | 40 ++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/internal/api/security_regression_test.go b/internal/api/security_regression_test.go index 8f704be49..844aa99d4 100644 --- a/internal/api/security_regression_test.go +++ b/internal/api/security_regression_test.go @@ -33,6 +33,12 @@ func (d *denyAuthorizer) Authorize(_ context.Context, _ string, _ string) (bool, return false, nil } +type adminOnlyAuthorizer struct{} + +func (a *adminOnlyAuthorizer) Authorize(ctx context.Context, _ string, _ string) (bool, error) { + return auth.GetUser(ctx) == "admin", nil +} + func newTestConfigWithTokens(t *testing.T, records ...config.APITokenRecord) *config.Config { t.Helper() tempDir := t.TempDir() @@ -330,6 +336,40 @@ func TestResetLockoutRequiresAuthInAPIMode(t *testing.T) { } } +func TestRequirePermissionDeniesProxyNonAdminUsers(t *testing.T) { + prevAuthorizer := auth.GetAuthorizer() + auth.SetAuthorizer(&adminOnlyAuthorizer{}) + defer auth.SetAuthorizer(prevAuthorizer) + + cfg := newTestConfigWithTokens(t) + cfg.ProxyAuthSecret = "proxy-secret" + cfg.ProxyAuthUserHeader = "X-Remote-User" + cfg.ProxyAuthRoleHeader = "X-Remote-Roles" + cfg.ProxyAuthAdminRole = "admin" + + router := NewRouter(cfg, nil, nil, nil, nil, "1.0.0") + + req := httptest.NewRequest(http.MethodGet, "/api/security/tokens", nil) + req.Header.Set("X-Proxy-Secret", cfg.ProxyAuthSecret) + req.Header.Set("X-Remote-User", "viewer-user") + req.Header.Set("X-Remote-Roles", "viewer") + rec := httptest.NewRecorder() + router.Handler().ServeHTTP(rec, req) + if rec.Code != http.StatusForbidden { + t.Fatalf("expected 403 for non-admin proxy user, got %d", rec.Code) + } + + req = httptest.NewRequest(http.MethodGet, "/api/security/tokens", nil) + req.Header.Set("X-Proxy-Secret", cfg.ProxyAuthSecret) + req.Header.Set("X-Remote-User", "admin") + req.Header.Set("X-Remote-Roles", "admin") + rec = httptest.NewRecorder() + router.Handler().ServeHTTP(rec, req) + if rec.Code != http.StatusOK { + t.Fatalf("expected 200 for admin proxy user, got %d", rec.Code) + } +} + func TestLicenseFeaturesRequiresAuthInAPIMode(t *testing.T) { record := newTokenRecord(t, "license-token-123.12345678", []string{config.ScopeMonitoringRead}, nil) cfg := newTestConfigWithTokens(t, record)