From ab0a69d06b56642d48c15f740fe5f3f563aeb8aa Mon Sep 17 00:00:00 2001 From: Tyler Koenig Date: Fri, 12 Jun 2026 14:27:44 -0400 Subject: [PATCH] fix(cluster)!: rename X-Upkeep-Secret header to X-Uptop-Secret MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Last upkeep-era name in the wire protocol. Breaking for mixed-version clusters, but zero installed base exists pre-v0.1.0 — free now, breaking forever after first tag. --- README.md | 2 +- docs/clustering.md | 2 +- internal/cluster/cluster.go | 2 +- internal/cluster/cluster_test.go | 2 +- internal/cluster/probe.go | 6 +++--- internal/server/server.go | 4 ++-- internal/server/server_test.go | 2 +- 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 6e3d604..acdab77 100644 --- a/README.md +++ b/README.md @@ -174,7 +174,7 @@ Export your Kuma backup JSON, then: ```bash curl -X POST http://localhost:8080/api/import/kuma \ - -H "X-Upkeep-Secret: your-secret" \ + -H "X-Uptop-Secret: your-secret" \ -H "Content-Type: application/json" \ -d @kuma-backup.json ``` diff --git a/docs/clustering.md b/docs/clustering.md index 77c3bdd..85b5f63 100644 --- a/docs/clustering.md +++ b/docs/clustering.md @@ -81,5 +81,5 @@ Set via `UPTOP_AGG_STRATEGY` on the leader. ## Security - Set `UPTOP_CLUSTER_SECRET` on all nodes. Without it, cluster API endpoints are unauthenticated. -- Secrets are sent in HTTP headers (`X-Upkeep-Secret`). Use TLS or a reverse proxy for production. +- Secrets are sent in HTTP headers (`X-Uptop-Secret`). Use TLS or a reverse proxy for production. - uptop warns on startup if the cluster secret is missing or if cluster mode is active without TLS. diff --git a/internal/cluster/cluster.go b/internal/cluster/cluster.go index a12eba9..382aad5 100644 --- a/internal/cluster/cluster.go +++ b/internal/cluster/cluster.go @@ -52,7 +52,7 @@ func runFollowerLoop(ctx context.Context, cfg Config, eng *monitor.Engine) { req, _ := http.NewRequest("GET", cfg.PeerURL+"/api/health", nil) if cfg.SharedKey != "" { - req.Header.Set("X-Upkeep-Secret", cfg.SharedKey) + req.Header.Set("X-Uptop-Secret", cfg.SharedKey) } resp, err := client.Do(req) diff --git a/internal/cluster/cluster_test.go b/internal/cluster/cluster_test.go index d5112e3..b383513 100644 --- a/internal/cluster/cluster_test.go +++ b/internal/cluster/cluster_test.go @@ -113,7 +113,7 @@ func TestFollowerLoop_SendsSecret(t *testing.T) { var receivedSecret string srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { mu.Lock() - receivedSecret = r.Header.Get("X-Upkeep-Secret") + receivedSecret = r.Header.Get("X-Uptop-Secret") mu.Unlock() w.WriteHeader(200) w.Write([]byte("OK")) diff --git a/internal/cluster/probe.go b/internal/cluster/probe.go index b5112dc..44a8105 100644 --- a/internal/cluster/probe.go +++ b/internal/cluster/probe.go @@ -90,7 +90,7 @@ func probeRegister(ctx context.Context, client *http.Client, cfg ProbeConfig) er return err } req.Header.Set("Content-Type", "application/json") - req.Header.Set("X-Upkeep-Secret", cfg.SharedKey) + req.Header.Set("X-Uptop-Secret", cfg.SharedKey) resp, err := client.Do(req) if err != nil { return err @@ -108,7 +108,7 @@ func probeFetchAssignments(ctx context.Context, client *http.Client, cfg ProbeCo if err != nil { return nil, err } - req.Header.Set("X-Upkeep-Secret", cfg.SharedKey) + req.Header.Set("X-Uptop-Secret", cfg.SharedKey) resp, err := client.Do(req) if err != nil { return nil, err @@ -180,7 +180,7 @@ func probeReportResults(ctx context.Context, client *http.Client, cfg ProbeConfi return err } req.Header.Set("Content-Type", "application/json") - req.Header.Set("X-Upkeep-Secret", cfg.SharedKey) + req.Header.Set("X-Uptop-Secret", cfg.SharedKey) resp, err := client.Do(req) if err != nil { return err diff --git a/internal/server/server.go b/internal/server/server.go index 8f7cbd8..43026c8 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -127,7 +127,7 @@ func (s *Server) routes() http.Handler { } func (s *Server) requireAuth(r *http.Request) bool { - return s.cfg.ClusterKey != "" && checkSecret(r.Header.Get("X-Upkeep-Secret"), s.cfg.ClusterKey) + return s.cfg.ClusterKey != "" && checkSecret(r.Header.Get("X-Uptop-Secret"), s.cfg.ClusterKey) } func (s *Server) handlePush(w http.ResponseWriter, r *http.Request) { @@ -159,7 +159,7 @@ func (s *Server) handleHealth(w http.ResponseWriter, r *http.Request) { http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) return } - if s.cfg.ClusterKey != "" && !checkSecret(r.Header.Get("X-Upkeep-Secret"), s.cfg.ClusterKey) { + if s.cfg.ClusterKey != "" && !checkSecret(r.Header.Get("X-Uptop-Secret"), s.cfg.ClusterKey) { http.Error(w, "Unauthorized", http.StatusUnauthorized) return } diff --git a/internal/server/server_test.go b/internal/server/server_test.go index db4a3d9..27cbda3 100644 --- a/internal/server/server_test.go +++ b/internal/server/server_test.go @@ -141,7 +141,7 @@ func authReq(method, url, secret string, body []byte) (*http.Response, error) { return nil, err } if secret != "" { - req.Header.Set("X-Upkeep-Secret", secret) + req.Header.Set("X-Uptop-Secret", secret) } return http.DefaultClient.Do(req) } -- 2.52.0