From 5176716ba155bded32ddb2b0161250fda4a9b606 Mon Sep 17 00:00:00 2001 From: viettranx Date: Sat, 7 Mar 2026 15:13:54 +0700 Subject: [PATCH] fix(mcp): encrypt headers/env on server update MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit UpdateServer type-asserted json.RawMessage but json.Decoder into map[string]interface{} produces map[string]interface{} for nested objects — so the assertion always failed and encryption was silently skipped. Marshal any type to []byte before encrypting. --- internal/store/pg/mcp_servers.go | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/internal/store/pg/mcp_servers.go b/internal/store/pg/mcp_servers.go index 3a52c97c..acd30c6c 100644 --- a/internal/store/pg/mcp_servers.go +++ b/internal/store/pg/mcp_servers.go @@ -160,11 +160,20 @@ func (s *PGMCPServerStore) UpdateServer(ctx context.Context, id uuid.UUID, updat updates["api_key"] = encrypted } } - // Encrypt env/headers JSONB fields + // Encrypt env/headers JSONB fields. + // json.Decoder into map[string]interface{} produces map[string]interface{} + // for nested objects, not json.RawMessage — so we must marshal any type. for _, field := range []string{"env", "headers"} { if v, ok := updates[field]; ok { - if raw, isBytes := v.(json.RawMessage); isBytes { - updates[field] = json.RawMessage(s.encryptJSONB([]byte(raw))) + var raw []byte + switch val := v.(type) { + case json.RawMessage: + raw = []byte(val) + default: + raw, _ = json.Marshal(val) + } + if len(raw) > 0 { + updates[field] = json.RawMessage(s.encryptJSONB(raw)) } } }