From 62b975a4d83edc511a1cdc7319d9d0b95be41839 Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Wed, 7 Jan 2026 14:29:09 +0100 Subject: [PATCH 01/25] compile regex => if error use == matching --- internals/proxy/middlewares/policy.go | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/internals/proxy/middlewares/policy.go b/internals/proxy/middlewares/policy.go index 08fbe112..dd7407a8 100644 --- a/internals/proxy/middlewares/policy.go +++ b/internals/proxy/middlewares/policy.go @@ -4,6 +4,7 @@ import ( "errors" "net/http" "reflect" + "regexp" request "github.com/codeshelldev/gotl/pkg/request" "github.com/codeshelldev/secured-signal-api/internals/config/structure" @@ -92,6 +93,12 @@ func doPoliciesApply(body map[string]any, headers map[string][]string, policies case string: policyValue, ok := policy.Value.(string) + re, err := regexp.Compile(policyValue) + + if err == nil { + return re.MatchString(asserted), key + } + if ok && asserted == policyValue { return true, key } @@ -118,7 +125,7 @@ func doPoliciesApply(body map[string]any, headers map[string][]string, policies } func doBlock(body map[string]any, headers map[string][]string, policies map[string]structure.FieldPolicy) (bool, string) { - if len(policies) == 0 { + if len(policies) == 0 || policies == nil { // default: allow all return false, "" } @@ -149,6 +156,6 @@ func doBlock(body map[string]any, headers map[string][]string, policies map[stri return false, cause } - // no match -> default: block all - return true, cause + // default: allow all + return false, cause } From dcd372d72ae02489be5c2425ffab1efd502bdcdc Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Wed, 7 Jan 2026 14:55:24 +0100 Subject: [PATCH 02/25] explicit block > allow --- internals/proxy/middlewares/policy.go | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/internals/proxy/middlewares/policy.go b/internals/proxy/middlewares/policy.go index dd7407a8..fb7cc99d 100644 --- a/internals/proxy/middlewares/policy.go +++ b/internals/proxy/middlewares/policy.go @@ -6,6 +6,7 @@ import ( "reflect" "regexp" + "github.com/codeshelldev/gotl/pkg/logger" request "github.com/codeshelldev/gotl/pkg/request" "github.com/codeshelldev/secured-signal-api/internals/config/structure" "github.com/codeshelldev/secured-signal-api/utils/requestkeys" @@ -132,20 +133,24 @@ func doBlock(body map[string]any, headers map[string][]string, policies map[stri allowed, blocked := getPolicies(policies) + logger.Dev(allowed, blocked) + var cause string isExplicitlyAllowed, cause := doPoliciesApply(body, headers, allowed) isExplicitlyBlocked, cause := doPoliciesApply(body, headers, blocked) - // explicit allow > block - if isExplicitlyAllowed { - return false, cause - } - + logger.Dev(body, headers) + + // explicit block > allow if isExplicitlyBlocked { return true, cause } + if isExplicitlyAllowed { + return false, cause + } + // only allow policies -> block anything not allowed if len(allowed) > 0 && len(blocked) == 0 { return true, cause From 3e7da878b4d5993a941b8607e4bbcf70e8c7d8d9 Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Wed, 7 Jan 2026 14:59:57 +0100 Subject: [PATCH 03/25] return after Bad Body --- internals/proxy/middlewares/mapping.go | 1 + internals/proxy/middlewares/message.go | 1 + internals/proxy/middlewares/policy.go | 1 + internals/proxy/middlewares/template.go | 1 + 4 files changed, 4 insertions(+) diff --git a/internals/proxy/middlewares/mapping.go b/internals/proxy/middlewares/mapping.go index 14418ead..be751495 100644 --- a/internals/proxy/middlewares/mapping.go +++ b/internals/proxy/middlewares/mapping.go @@ -35,6 +35,7 @@ func mappingHandler(next http.Handler) http.Handler { if err != nil { logger.Error("Could not get Request Body: ", err.Error()) http.Error(w, "Bad Request: invalid body", http.StatusBadRequest) + return } var modifiedBody bool diff --git a/internals/proxy/middlewares/message.go b/internals/proxy/middlewares/message.go index 51a1748c..d5da10af 100644 --- a/internals/proxy/middlewares/message.go +++ b/internals/proxy/middlewares/message.go @@ -34,6 +34,7 @@ func messageHandler(next http.Handler) http.Handler { if err != nil { logger.Error("Could not get Request Body: ", err.Error()) http.Error(w, "Bad Request: invalid body", http.StatusBadRequest) + return } bodyData := map[string]any{} diff --git a/internals/proxy/middlewares/policy.go b/internals/proxy/middlewares/policy.go index fb7cc99d..468050ef 100644 --- a/internals/proxy/middlewares/policy.go +++ b/internals/proxy/middlewares/policy.go @@ -34,6 +34,7 @@ func policyHandler(next http.Handler) http.Handler { if err != nil { logger.Error("Could not get Request Body: ", err.Error()) http.Error(w, "Bad Request: invalid body", http.StatusBadRequest) + return } if body.Empty { diff --git a/internals/proxy/middlewares/template.go b/internals/proxy/middlewares/template.go index f2eccb91..af7d1a2e 100644 --- a/internals/proxy/middlewares/template.go +++ b/internals/proxy/middlewares/template.go @@ -36,6 +36,7 @@ func templateHandler(next http.Handler) http.Handler { if err != nil { logger.Error("Could not get Request Body: ", err.Error()) http.Error(w, "Bad Request: invalid body", http.StatusBadRequest) + return } bodyData := map[string]any{} From b0650c2ea02d5f64a573f6096c08bc310f163642 Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Wed, 7 Jan 2026 15:02:14 +0100 Subject: [PATCH 04/25] debug body templating --- internals/proxy/middlewares/template.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/internals/proxy/middlewares/template.go b/internals/proxy/middlewares/template.go index af7d1a2e..cd507fee 100644 --- a/internals/proxy/middlewares/template.go +++ b/internals/proxy/middlewares/template.go @@ -85,6 +85,8 @@ func templateHandler(next http.Handler) http.Handler { } logger.Debug("Applied Body Templating: ", body.Data) + + logger.Dev(request.GetReqBody(req)) } if req.URL.Path != "" { From f848ebad7bd4dd73b01a7f757b8f637a51eb7618 Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Wed, 7 Jan 2026 15:20:49 +0100 Subject: [PATCH 05/25] debug body templating --- go.mod | 2 +- go.sum | 2 ++ internals/proxy/middlewares/template.go | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 495eafa0..5910b3c7 100644 --- a/go.mod +++ b/go.mod @@ -2,7 +2,7 @@ module github.com/codeshelldev/secured-signal-api go 1.25.5 -require github.com/codeshelldev/gotl v0.0.10 +require github.com/codeshelldev/gotl v0.0.11-1 require go.uber.org/zap v1.27.1 diff --git a/go.sum b/go.sum index 1e267259..47a7a2da 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,7 @@ github.com/codeshelldev/gotl v0.0.10 h1:/2HOPXTlG1HplbXvkB1cZG6NQlGHCiZfWR1pMj6X55M= github.com/codeshelldev/gotl v0.0.10/go.mod h1:rDkJma6eQSRfCr7ieX9/esn3/uAWNzjHfpjlr9j6FFk= +github.com/codeshelldev/gotl v0.0.11-1 h1:K+r39cDAsKtZtfEzrtrm9Zedg8/J4Q944AahYGQCgEM= +github.com/codeshelldev/gotl v0.0.11-1/go.mod h1:rDkJma6eQSRfCr7ieX9/esn3/uAWNzjHfpjlr9j6FFk= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= diff --git a/internals/proxy/middlewares/template.go b/internals/proxy/middlewares/template.go index cd507fee..03b2172d 100644 --- a/internals/proxy/middlewares/template.go +++ b/internals/proxy/middlewares/template.go @@ -87,6 +87,7 @@ func templateHandler(next http.Handler) http.Handler { logger.Debug("Applied Body Templating: ", body.Data) logger.Dev(request.GetReqBody(req)) + logger.Dev(body) } if req.URL.Path != "" { From c386e70e4509c6d7292ee8c4b678acc13ecee81d Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Wed, 7 Jan 2026 15:35:49 +0100 Subject: [PATCH 06/25] more debugging --- go.mod | 2 +- go.sum | 2 ++ internals/proxy/middlewares/template.go | 4 +++- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index 5910b3c7..e7ee8c48 100644 --- a/go.mod +++ b/go.mod @@ -2,7 +2,7 @@ module github.com/codeshelldev/secured-signal-api go 1.25.5 -require github.com/codeshelldev/gotl v0.0.11-1 +require github.com/codeshelldev/gotl v0.0.11-2 require go.uber.org/zap v1.27.1 diff --git a/go.sum b/go.sum index 47a7a2da..fd23a073 100644 --- a/go.sum +++ b/go.sum @@ -2,6 +2,8 @@ github.com/codeshelldev/gotl v0.0.10 h1:/2HOPXTlG1HplbXvkB1cZG6NQlGHCiZfWR1pMj6X github.com/codeshelldev/gotl v0.0.10/go.mod h1:rDkJma6eQSRfCr7ieX9/esn3/uAWNzjHfpjlr9j6FFk= github.com/codeshelldev/gotl v0.0.11-1 h1:K+r39cDAsKtZtfEzrtrm9Zedg8/J4Q944AahYGQCgEM= github.com/codeshelldev/gotl v0.0.11-1/go.mod h1:rDkJma6eQSRfCr7ieX9/esn3/uAWNzjHfpjlr9j6FFk= +github.com/codeshelldev/gotl v0.0.11-2 h1:eU+TBB8pasQt3zgbNJQwQ8OwhSQPDYdkZximKtN7pdA= +github.com/codeshelldev/gotl v0.0.11-2/go.mod h1:rDkJma6eQSRfCr7ieX9/esn3/uAWNzjHfpjlr9j6FFk= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= diff --git a/internals/proxy/middlewares/template.go b/internals/proxy/middlewares/template.go index 03b2172d..7cfd8d82 100644 --- a/internals/proxy/middlewares/template.go +++ b/internals/proxy/middlewares/template.go @@ -73,6 +73,8 @@ func templateHandler(next http.Handler) http.Handler { } } + logger.Dev(body, bodyData) + if modifiedBody { body.Data = bodyData @@ -87,7 +89,7 @@ func templateHandler(next http.Handler) http.Handler { logger.Debug("Applied Body Templating: ", body.Data) logger.Dev(request.GetReqBody(req)) - logger.Dev(body) + logger.Dev(body, body.Data) } if req.URL.Path != "" { From e9e7230744482a3d4e35c2a1ffb7ff4f3eaeb041 Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Wed, 7 Jan 2026 15:47:09 +0100 Subject: [PATCH 07/25] bump gotl for bugfix --- go.mod | 2 +- go.sum | 8 ++------ internals/proxy/middlewares/template.go | 5 ----- 3 files changed, 3 insertions(+), 12 deletions(-) diff --git a/go.mod b/go.mod index e7ee8c48..28358cab 100644 --- a/go.mod +++ b/go.mod @@ -2,7 +2,7 @@ module github.com/codeshelldev/secured-signal-api go 1.25.5 -require github.com/codeshelldev/gotl v0.0.11-2 +require github.com/codeshelldev/gotl v0.0.12 require go.uber.org/zap v1.27.1 diff --git a/go.sum b/go.sum index fd23a073..3eff09f2 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,5 @@ -github.com/codeshelldev/gotl v0.0.10 h1:/2HOPXTlG1HplbXvkB1cZG6NQlGHCiZfWR1pMj6X55M= -github.com/codeshelldev/gotl v0.0.10/go.mod h1:rDkJma6eQSRfCr7ieX9/esn3/uAWNzjHfpjlr9j6FFk= -github.com/codeshelldev/gotl v0.0.11-1 h1:K+r39cDAsKtZtfEzrtrm9Zedg8/J4Q944AahYGQCgEM= -github.com/codeshelldev/gotl v0.0.11-1/go.mod h1:rDkJma6eQSRfCr7ieX9/esn3/uAWNzjHfpjlr9j6FFk= -github.com/codeshelldev/gotl v0.0.11-2 h1:eU+TBB8pasQt3zgbNJQwQ8OwhSQPDYdkZximKtN7pdA= -github.com/codeshelldev/gotl v0.0.11-2/go.mod h1:rDkJma6eQSRfCr7ieX9/esn3/uAWNzjHfpjlr9j6FFk= +github.com/codeshelldev/gotl v0.0.12 h1:VM3W6hiEfPgK+cCLT70S004tYAdhQWXD72FtFqCF+2Q= +github.com/codeshelldev/gotl v0.0.12/go.mod h1:rDkJma6eQSRfCr7ieX9/esn3/uAWNzjHfpjlr9j6FFk= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= diff --git a/internals/proxy/middlewares/template.go b/internals/proxy/middlewares/template.go index 7cfd8d82..af7d1a2e 100644 --- a/internals/proxy/middlewares/template.go +++ b/internals/proxy/middlewares/template.go @@ -73,8 +73,6 @@ func templateHandler(next http.Handler) http.Handler { } } - logger.Dev(body, bodyData) - if modifiedBody { body.Data = bodyData @@ -87,9 +85,6 @@ func templateHandler(next http.Handler) http.Handler { } logger.Debug("Applied Body Templating: ", body.Data) - - logger.Dev(request.GetReqBody(req)) - logger.Dev(body, body.Data) } if req.URL.Path != "" { From e543844a2af4965cae04df24a3c2cab5b70010e4 Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Wed, 7 Jan 2026 20:03:40 +0100 Subject: [PATCH 08/25] scope policies under respective field --- internals/config/structure/structure.go | 2 +- internals/proxy/middlewares/policy.go | 65 ++++++++++--------------- 2 files changed, 28 insertions(+), 39 deletions(-) diff --git a/internals/config/structure/structure.go b/internals/config/structure/structure.go index aeed07c0..f8a71921 100644 --- a/internals/config/structure/structure.go +++ b/internals/config/structure/structure.go @@ -46,7 +46,7 @@ type FieldMapping struct { type ACCESS struct { ENDPOINTS []string `koanf:"endpoints"` - FIELD_POLICIES map[string]FieldPolicy `koanf:"fieldpolicies" childtransform:"default"` + FIELD_POLICIES map[string][]FieldPolicy `koanf:"fieldpolicies" childtransform:"default"` RATE_LIMITING RateLimiting `koanf:"ratelimiting"` IP_FILTER []string `koanf:"ipfilter"` TRUSTED_IPS []string `koanf:"trustedips"` diff --git a/internals/proxy/middlewares/policy.go b/internals/proxy/middlewares/policy.go index 468050ef..ad78d498 100644 --- a/internals/proxy/middlewares/policy.go +++ b/internals/proxy/middlewares/policy.go @@ -6,7 +6,6 @@ import ( "reflect" "regexp" - "github.com/codeshelldev/gotl/pkg/logger" request "github.com/codeshelldev/gotl/pkg/request" "github.com/codeshelldev/secured-signal-api/internals/config/structure" "github.com/codeshelldev/secured-signal-api/utils/requestkeys" @@ -55,20 +54,20 @@ func policyHandler(next http.Handler) http.Handler { }) } -func getPolicies(policies map[string]structure.FieldPolicy) (map[string]structure.FieldPolicy, map[string]structure.FieldPolicy) { - blockedFields := map[string]structure.FieldPolicy{} - allowedFields := map[string]structure.FieldPolicy{} +func getPolicies(policies []structure.FieldPolicy) ([]structure.FieldPolicy, []structure.FieldPolicy) { + blocked := []structure.FieldPolicy{} + allowed := []structure.FieldPolicy{} - for field, policy := range policies { + for i, policy := range policies { switch policy.Action { case "block": - blockedFields[field] = policy + blocked[i] = policy case "allow": - allowedFields[field] = policy + allowed[i] = policy } } - return allowedFields, blockedFields + return allowed, blocked } func getField(key string, body map[string]any, headers map[string][]string) (any, error) { @@ -80,17 +79,17 @@ func getField(key string, body map[string]any, headers map[string][]string) (any return value, nil } - return value, errors.New("field not found") + return nil, errors.New("field not found") } -func doPoliciesApply(body map[string]any, headers map[string][]string, policies map[string]structure.FieldPolicy) (bool, string) { - for key, policy := range policies { - value, err := getField(key, body, headers) +func doPoliciesApply(key string, body map[string]any, headers map[string][]string, policies []structure.FieldPolicy) (bool, string) { + value, err := getField(key, body, headers) - if err != nil { - continue - } + if err != nil { + return false, "" + } + for _, policy := range policies { switch asserted := value.(type) { case string: policyValue, ok := policy.Value.(string) @@ -126,40 +125,30 @@ func doPoliciesApply(body map[string]any, headers map[string][]string, policies return false, "" } -func doBlock(body map[string]any, headers map[string][]string, policies map[string]structure.FieldPolicy) (bool, string) { +func doBlock(body map[string]any, headers map[string][]string, policies map[string][]structure.FieldPolicy) (bool, string) { if len(policies) == 0 || policies == nil { // default: allow all return false, "" } - allowed, blocked := getPolicies(policies) - - logger.Dev(allowed, blocked) - var cause string - isExplicitlyAllowed, cause := doPoliciesApply(body, headers, allowed) - isExplicitlyBlocked, cause := doPoliciesApply(body, headers, blocked) - - logger.Dev(body, headers) + for field, policy := range policies { + value, _ := getField(field, body, headers) - // explicit block > allow - if isExplicitlyBlocked { - return true, cause - } + if value == nil { + continue + } - if isExplicitlyAllowed { - return false, cause - } + allowed, blocked := getPolicies(policy) - // only allow policies -> block anything not allowed - if len(allowed) > 0 && len(blocked) == 0 { - return true, cause - } + isExplicitlyAllowed, cause := doPoliciesApply(field, body, headers, allowed) + isExplicitlyBlocked, cause := doPoliciesApply(field, body, headers, blocked) - // only block polcicies -> allow anything not blocked - if len(blocked) > 0 && len(allowed) == 0 { - return false, cause + // block if explicitly blocked and no explicit allow exists + if isExplicitlyBlocked && !isExplicitlyAllowed { + return true, cause + } } // default: allow all From 1c23cc82b62b56dc82af2bee3f4c2e98c322b3a2 Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Wed, 7 Jan 2026 20:07:56 +0100 Subject: [PATCH 09/25] fix index out of range error in getPolicies --- internals/proxy/middlewares/policy.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/internals/proxy/middlewares/policy.go b/internals/proxy/middlewares/policy.go index ad78d498..d17839c3 100644 --- a/internals/proxy/middlewares/policy.go +++ b/internals/proxy/middlewares/policy.go @@ -58,12 +58,12 @@ func getPolicies(policies []structure.FieldPolicy) ([]structure.FieldPolicy, []s blocked := []structure.FieldPolicy{} allowed := []structure.FieldPolicy{} - for i, policy := range policies { + for _, policy := range policies { switch policy.Action { case "block": - blocked[i] = policy + blocked = append(blocked, policy) case "allow": - allowed[i] = policy + allowed = append(allowed, policy) } } From 441ec7828efe6b8779edbabdc7c552e10c6b63ba Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Wed, 7 Jan 2026 20:13:47 +0100 Subject: [PATCH 10/25] debug --- internals/proxy/middlewares/policy.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/internals/proxy/middlewares/policy.go b/internals/proxy/middlewares/policy.go index d17839c3..3e91ccf8 100644 --- a/internals/proxy/middlewares/policy.go +++ b/internals/proxy/middlewares/policy.go @@ -6,6 +6,7 @@ import ( "reflect" "regexp" + "github.com/codeshelldev/gotl/pkg/logger" request "github.com/codeshelldev/gotl/pkg/request" "github.com/codeshelldev/secured-signal-api/internals/config/structure" "github.com/codeshelldev/secured-signal-api/utils/requestkeys" @@ -142,9 +143,15 @@ func doBlock(body map[string]any, headers map[string][]string, policies map[stri allowed, blocked := getPolicies(policy) + logger.Dev(allowed, blocked) + isExplicitlyAllowed, cause := doPoliciesApply(field, body, headers, allowed) isExplicitlyBlocked, cause := doPoliciesApply(field, body, headers, blocked) + logger.Dev(field, isExplicitlyAllowed, isExplicitlyBlocked) + + logger.Dev(policy) + // block if explicitly blocked and no explicit allow exists if isExplicitlyBlocked && !isExplicitlyAllowed { return true, cause From 2e302d58f67e3ab41241c349d2cca83e7c940575 Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Wed, 7 Jan 2026 20:21:16 +0100 Subject: [PATCH 11/25] wait for true, dont return early in doPoliciesApply() --- internals/proxy/middlewares/policy.go | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/internals/proxy/middlewares/policy.go b/internals/proxy/middlewares/policy.go index 3e91ccf8..3db1315e 100644 --- a/internals/proxy/middlewares/policy.go +++ b/internals/proxy/middlewares/policy.go @@ -6,7 +6,6 @@ import ( "reflect" "regexp" - "github.com/codeshelldev/gotl/pkg/logger" request "github.com/codeshelldev/gotl/pkg/request" "github.com/codeshelldev/secured-signal-api/internals/config/structure" "github.com/codeshelldev/secured-signal-api/utils/requestkeys" @@ -43,7 +42,7 @@ func policyHandler(next http.Handler) http.Handler { headerData := request.GetReqHeaders(req) - shouldBlock, field := doBlock(body.Data, headerData, policies) + shouldBlock, field := isBlockedByPolicy(body.Data, headerData, policies) if shouldBlock { logger.Warn("Client tried to use blocked field: ", field) @@ -98,7 +97,9 @@ func doPoliciesApply(key string, body map[string]any, headers map[string][]strin re, err := regexp.Compile(policyValue) if err == nil { - return re.MatchString(asserted), key + if re.MatchString(asserted) { + return true, key + } } if ok && asserted == policyValue { @@ -126,7 +127,7 @@ func doPoliciesApply(key string, body map[string]any, headers map[string][]strin return false, "" } -func doBlock(body map[string]any, headers map[string][]string, policies map[string][]structure.FieldPolicy) (bool, string) { +func isBlockedByPolicy(body map[string]any, headers map[string][]string, policies map[string][]structure.FieldPolicy) (bool, string) { if len(policies) == 0 || policies == nil { // default: allow all return false, "" @@ -143,15 +144,9 @@ func doBlock(body map[string]any, headers map[string][]string, policies map[stri allowed, blocked := getPolicies(policy) - logger.Dev(allowed, blocked) - isExplicitlyAllowed, cause := doPoliciesApply(field, body, headers, allowed) isExplicitlyBlocked, cause := doPoliciesApply(field, body, headers, blocked) - logger.Dev(field, isExplicitlyAllowed, isExplicitlyBlocked) - - logger.Dev(policy) - // block if explicitly blocked and no explicit allow exists if isExplicitlyBlocked && !isExplicitlyAllowed { return true, cause From 4a60d8ef5432985cd604684b6f769742fbaf4baf Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Wed, 7 Jan 2026 20:59:22 +0100 Subject: [PATCH 12/25] typo fix --- internals/proxy/middlewares/policy.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internals/proxy/middlewares/policy.go b/internals/proxy/middlewares/policy.go index 3db1315e..36c2b67a 100644 --- a/internals/proxy/middlewares/policy.go +++ b/internals/proxy/middlewares/policy.go @@ -106,7 +106,7 @@ func doPoliciesApply(key string, body map[string]any, headers map[string][]strin return true, key } case int: - policyValue, ok := policy.Value.(int); + policyValue, ok := policy.Value.(int) if ok && asserted == policyValue { return true, key From e35e9bacbfe38124fb734d76a0ee3e051b9c9808 Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Wed, 7 Jan 2026 21:00:30 +0100 Subject: [PATCH 13/25] debug regex matching for field policies --- internals/proxy/middlewares/policy.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/internals/proxy/middlewares/policy.go b/internals/proxy/middlewares/policy.go index 36c2b67a..a98461d4 100644 --- a/internals/proxy/middlewares/policy.go +++ b/internals/proxy/middlewares/policy.go @@ -6,6 +6,7 @@ import ( "reflect" "regexp" + "github.com/codeshelldev/gotl/pkg/logger" request "github.com/codeshelldev/gotl/pkg/request" "github.com/codeshelldev/secured-signal-api/internals/config/structure" "github.com/codeshelldev/secured-signal-api/utils/requestkeys" @@ -98,8 +99,10 @@ func doPoliciesApply(key string, body map[string]any, headers map[string][]strin if err == nil { if re.MatchString(asserted) { + logger.Dev(asserted) return true, key } + continue } if ok && asserted == policyValue { From d834cb09a8ff53a28a62e94ded725c93b7ab8c36 Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Wed, 7 Jan 2026 21:36:03 +0100 Subject: [PATCH 14/25] refactor blocking behaviours --- internals/proxy/middlewares/endpoints.go | 14 +++++------ internals/proxy/middlewares/ipfilter.go | 8 +++--- internals/proxy/middlewares/policy.go | 31 ++++++++++++++++++------ 3 files changed, 35 insertions(+), 18 deletions(-) diff --git a/internals/proxy/middlewares/endpoints.go b/internals/proxy/middlewares/endpoints.go index c33e45be..c85f2899 100644 --- a/internals/proxy/middlewares/endpoints.go +++ b/internals/proxy/middlewares/endpoints.go @@ -82,16 +82,16 @@ func isEndpointBlocked(endpoint string, endpoints []string) bool { return true } - // only allowed endpoints -> block anything not allowed - if len(allowed) > 0 && len(blocked) == 0 { + // allow rules -> default deny + if len(allowed) > 0 { return true } - - // only blocked endpoints -> allow anything not blocked - if len(blocked) > 0 && len(allowed) == 0 { + + // only block rules -> default allow + if len(blocked) > 0 { return false } - // default: allow all - return false + // safety net -> block + return true } diff --git a/internals/proxy/middlewares/ipfilter.go b/internals/proxy/middlewares/ipfilter.go index b4138e47..f8f1176a 100644 --- a/internals/proxy/middlewares/ipfilter.go +++ b/internals/proxy/middlewares/ipfilter.go @@ -80,16 +80,16 @@ func isIPBlocked(ip net.IP, ipfilter []string) (bool) { return true } - // if any allow rules exist, default is deny + // allow rules -> default deny if len(allowed) > 0 { return true } - // only blocked ips -> allow anything not blocked + // only block rules -> default allow if len(blocked) > 0 { return false } - // default: allow all - return false + // safety net -> block + return true } diff --git a/internals/proxy/middlewares/policy.go b/internals/proxy/middlewares/policy.go index a98461d4..081db03f 100644 --- a/internals/proxy/middlewares/policy.go +++ b/internals/proxy/middlewares/policy.go @@ -6,7 +6,6 @@ import ( "reflect" "regexp" - "github.com/codeshelldev/gotl/pkg/logger" request "github.com/codeshelldev/gotl/pkg/request" "github.com/codeshelldev/secured-signal-api/internals/config/structure" "github.com/codeshelldev/secured-signal-api/utils/requestkeys" @@ -99,7 +98,6 @@ func doPoliciesApply(key string, body map[string]any, headers map[string][]strin if err == nil { if re.MatchString(asserted) { - logger.Dev(asserted) return true, key } continue @@ -136,9 +134,11 @@ func isBlockedByPolicy(body map[string]any, headers map[string][]string, policie return false, "" } - var cause string - for field, policy := range policies { + if len(policy) == 0 || policy == nil { + continue + } + value, _ := getField(field, body, headers) if value == nil { @@ -150,12 +150,29 @@ func isBlockedByPolicy(body map[string]any, headers map[string][]string, policie isExplicitlyAllowed, cause := doPoliciesApply(field, body, headers, allowed) isExplicitlyBlocked, cause := doPoliciesApply(field, body, headers, blocked) - // block if explicitly blocked and no explicit allow exists - if isExplicitlyBlocked && !isExplicitlyAllowed { + // explicit allow > block + if isExplicitlyAllowed { + return false, cause + } + + if isExplicitlyBlocked { return true, cause } + + // allow rules -> default deny + if len(allowed) > 0 { + return true, cause + } + + // only block rules -> default allow + if len(blocked) > 0 { + return false, cause + } + + // safety net -> block + return true, "safety net" } // default: allow all - return false, cause + return false, "" } From 04057b68cc32f3a2ddb2816bae6e49cdc6fbdb31 Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Thu, 8 Jan 2026 20:58:19 +0100 Subject: [PATCH 15/25] . --- internals/proxy/middlewares/auth.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/internals/proxy/middlewares/auth.go b/internals/proxy/middlewares/auth.go index 5946f27f..872ad3c7 100644 --- a/internals/proxy/middlewares/auth.go +++ b/internals/proxy/middlewares/auth.go @@ -92,6 +92,8 @@ var BearerAuth = AuthMethod{ } if strings.ToLower(headerParts[0]) == "bearer" { + logger.Dev(headerParts) + if isValidToken(tokens, headerParts[1]) { return headerParts[1], nil } From 8e5d0485d740c49ba9ccbd4439603156b2397351 Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Thu, 8 Jan 2026 20:59:07 +0100 Subject: [PATCH 16/25] revert --- internals/proxy/middlewares/auth.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/internals/proxy/middlewares/auth.go b/internals/proxy/middlewares/auth.go index 872ad3c7..5946f27f 100644 --- a/internals/proxy/middlewares/auth.go +++ b/internals/proxy/middlewares/auth.go @@ -92,8 +92,6 @@ var BearerAuth = AuthMethod{ } if strings.ToLower(headerParts[0]) == "bearer" { - logger.Dev(headerParts) - if isValidToken(tokens, headerParts[1]) { return headerParts[1], nil } From 9595504132fff2f3298ecc224f6e67389e883c8f Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Thu, 8 Jan 2026 21:08:08 +0100 Subject: [PATCH 17/25] get tokens on each request to enable quick reload --- internals/proxy/middlewares/auth.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/internals/proxy/middlewares/auth.go b/internals/proxy/middlewares/auth.go index 5946f27f..91afc979 100644 --- a/internals/proxy/middlewares/auth.go +++ b/internals/proxy/middlewares/auth.go @@ -23,13 +23,6 @@ const tokenKey contextKey = "token" const isAuthKey contextKey = "isAuthenticated" func authHandler(next http.Handler) http.Handler { - tokenKeys := maps.Keys(config.ENV.CONFIGS) - tokens := slices.Collect(tokenKeys) - - if tokens == nil { - tokens = []string{} - } - var authChain = NewAuthChain(). Use(BearerAuth). Use(BasicAuth). @@ -38,6 +31,13 @@ func authHandler(next http.Handler) http.Handler { Use(PathAuth) return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { + tokenKeys := maps.Keys(config.ENV.CONFIGS) + tokens := slices.Collect(tokenKeys) + + if tokens == nil { + tokens = []string{} + } + if config.ENV.INSECURE || len(tokens) <= 0 { next.ServeHTTP(w, req) return From 3b397576e7b93a6302665f31b36de92d24111e8b Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Thu, 8 Jan 2026 21:09:35 +0100 Subject: [PATCH 18/25] =?UTF-8?q?use=20`IP=5FFILTER`=20instead=20of=20`END?= =?UTF-8?q?POINTS`=20=F0=9F=A4=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internals/proxy/middlewares/ipfilter.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internals/proxy/middlewares/ipfilter.go b/internals/proxy/middlewares/ipfilter.go index f8f1176a..5e118a0f 100644 --- a/internals/proxy/middlewares/ipfilter.go +++ b/internals/proxy/middlewares/ipfilter.go @@ -21,7 +21,7 @@ func ipFilterHandler(next http.Handler) http.Handler { ipFilter := conf.SETTINGS.ACCESS.IP_FILTER if ipFilter == nil { - ipFilter = getConfig("").SETTINGS.ACCESS.ENDPOINTS + ipFilter = getConfig("").SETTINGS.ACCESS.IP_FILTER } ip := getContext[net.IP](req, clientIPKey) From 7496f36fba43e43e58f49e5358d79a3d686362dd Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Thu, 8 Jan 2026 21:22:43 +0100 Subject: [PATCH 19/25] use float64 for json --- internals/proxy/middlewares/policy.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/internals/proxy/middlewares/policy.go b/internals/proxy/middlewares/policy.go index 081db03f..d61afa3e 100644 --- a/internals/proxy/middlewares/policy.go +++ b/internals/proxy/middlewares/policy.go @@ -109,6 +109,12 @@ func doPoliciesApply(key string, body map[string]any, headers map[string][]strin case int: policyValue, ok := policy.Value.(int) + if ok && asserted == policyValue { + return true, key + } + case float64: + policyValue, ok := policy.Value.(float64) + if ok && asserted == policyValue { return true, key } From 6aac76cf89ea98370b92beb637ffe273e0e53f5d Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Thu, 8 Jan 2026 21:33:30 +0100 Subject: [PATCH 20/25] convert into float64 for json --- internals/proxy/middlewares/policy.go | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/internals/proxy/middlewares/policy.go b/internals/proxy/middlewares/policy.go index d61afa3e..687cf18c 100644 --- a/internals/proxy/middlewares/policy.go +++ b/internals/proxy/middlewares/policy.go @@ -113,9 +113,19 @@ func doPoliciesApply(key string, body map[string]any, headers map[string][]strin return true, key } case float64: - policyValue, ok := policy.Value.(float64) + var policyValue float64 + + // needed for json + switch assertedValue := policy.Value.(type) { + case int: + policyValue = float64(assertedValue) + case float64: + policyValue = assertedValue + default: + continue + } - if ok && asserted == policyValue { + if asserted == policyValue { return true, key } case bool: From a3db452484eee477149deeb44176ec9bc274bf5e Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Thu, 8 Jan 2026 22:04:15 +0100 Subject: [PATCH 21/25] debug floats --- internals/proxy/middlewares/policy.go | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/internals/proxy/middlewares/policy.go b/internals/proxy/middlewares/policy.go index 687cf18c..656bde22 100644 --- a/internals/proxy/middlewares/policy.go +++ b/internals/proxy/middlewares/policy.go @@ -6,6 +6,7 @@ import ( "reflect" "regexp" + "github.com/codeshelldev/gotl/pkg/logger" request "github.com/codeshelldev/gotl/pkg/request" "github.com/codeshelldev/secured-signal-api/internals/config/structure" "github.com/codeshelldev/secured-signal-api/utils/requestkeys" @@ -125,13 +126,9 @@ func doPoliciesApply(key string, body map[string]any, headers map[string][]strin continue } - if asserted == policyValue { - return true, key - } - case bool: - policyValue, ok := policy.Value.(bool) + logger.Dev(policyValue, asserted) - if ok && asserted == policyValue { + if asserted == policyValue { return true, key } default: From 16137361c93ac433849e806149d856fbf20c47cc Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Thu, 8 Jan 2026 22:07:36 +0100 Subject: [PATCH 22/25] more debugging --- internals/proxy/middlewares/policy.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/internals/proxy/middlewares/policy.go b/internals/proxy/middlewares/policy.go index 656bde22..edd63a8b 100644 --- a/internals/proxy/middlewares/policy.go +++ b/internals/proxy/middlewares/policy.go @@ -110,12 +110,16 @@ func doPoliciesApply(key string, body map[string]any, headers map[string][]strin case int: policyValue, ok := policy.Value.(int) + logger.Dev("INT:", policyValue) + if ok && asserted == policyValue { return true, key } case float64: var policyValue float64 + logger.Dev(policy.Value) + // needed for json switch assertedValue := policy.Value.(type) { case int: From f6b9b6bcd67aee84f1ad3e5dc040dbbd4bd58f4d Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Thu, 8 Jan 2026 22:12:22 +0100 Subject: [PATCH 23/25] check type --- internals/proxy/middlewares/policy.go | 1 + 1 file changed, 1 insertion(+) diff --git a/internals/proxy/middlewares/policy.go b/internals/proxy/middlewares/policy.go index edd63a8b..6acee162 100644 --- a/internals/proxy/middlewares/policy.go +++ b/internals/proxy/middlewares/policy.go @@ -136,6 +136,7 @@ func doPoliciesApply(key string, body map[string]any, headers map[string][]strin return true, key } default: + logger.Dev(reflect.TypeOf(value)) if reflect.DeepEqual(value, policy.Value) { return true, key } From 3133ad0b0a97d585b6e9f5777842d8b1c0fe889b Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Thu, 8 Jan 2026 22:15:21 +0100 Subject: [PATCH 24/25] debug value type --- internals/proxy/middlewares/policy.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/internals/proxy/middlewares/policy.go b/internals/proxy/middlewares/policy.go index 6acee162..513dfdf8 100644 --- a/internals/proxy/middlewares/policy.go +++ b/internals/proxy/middlewares/policy.go @@ -163,6 +163,8 @@ func isBlockedByPolicy(body map[string]any, headers map[string][]string, policie continue } + logger.Dev(value, reflect.TypeOf(value)) + allowed, blocked := getPolicies(policy) isExplicitlyAllowed, cause := doPoliciesApply(field, body, headers, allowed) From 5891448c1214dd89736c2db8865f71cdf80ec951 Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Thu, 8 Jan 2026 22:23:01 +0100 Subject: [PATCH 25/25] bump gotl version for float support in stringutils --- go.mod | 2 +- go.sum | 2 ++ internals/proxy/middlewares/policy.go | 10 ---------- 3 files changed, 3 insertions(+), 11 deletions(-) diff --git a/go.mod b/go.mod index 28358cab..8d07b1ca 100644 --- a/go.mod +++ b/go.mod @@ -2,7 +2,7 @@ module github.com/codeshelldev/secured-signal-api go 1.25.5 -require github.com/codeshelldev/gotl v0.0.12 +require github.com/codeshelldev/gotl v0.0.13 require go.uber.org/zap v1.27.1 diff --git a/go.sum b/go.sum index 3eff09f2..98f3f320 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,7 @@ github.com/codeshelldev/gotl v0.0.12 h1:VM3W6hiEfPgK+cCLT70S004tYAdhQWXD72FtFqCF+2Q= github.com/codeshelldev/gotl v0.0.12/go.mod h1:rDkJma6eQSRfCr7ieX9/esn3/uAWNzjHfpjlr9j6FFk= +github.com/codeshelldev/gotl v0.0.13 h1:3sittUEi9D02nP06FSSxAduHJggFlfdMrEz3iXaySmU= +github.com/codeshelldev/gotl v0.0.13/go.mod h1:rDkJma6eQSRfCr7ieX9/esn3/uAWNzjHfpjlr9j6FFk= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= diff --git a/internals/proxy/middlewares/policy.go b/internals/proxy/middlewares/policy.go index 513dfdf8..a35d0e2b 100644 --- a/internals/proxy/middlewares/policy.go +++ b/internals/proxy/middlewares/policy.go @@ -6,7 +6,6 @@ import ( "reflect" "regexp" - "github.com/codeshelldev/gotl/pkg/logger" request "github.com/codeshelldev/gotl/pkg/request" "github.com/codeshelldev/secured-signal-api/internals/config/structure" "github.com/codeshelldev/secured-signal-api/utils/requestkeys" @@ -110,16 +109,12 @@ func doPoliciesApply(key string, body map[string]any, headers map[string][]strin case int: policyValue, ok := policy.Value.(int) - logger.Dev("INT:", policyValue) - if ok && asserted == policyValue { return true, key } case float64: var policyValue float64 - logger.Dev(policy.Value) - // needed for json switch assertedValue := policy.Value.(type) { case int: @@ -130,13 +125,10 @@ func doPoliciesApply(key string, body map[string]any, headers map[string][]strin continue } - logger.Dev(policyValue, asserted) - if asserted == policyValue { return true, key } default: - logger.Dev(reflect.TypeOf(value)) if reflect.DeepEqual(value, policy.Value) { return true, key } @@ -163,8 +155,6 @@ func isBlockedByPolicy(body map[string]any, headers map[string][]string, policie continue } - logger.Dev(value, reflect.TypeOf(value)) - allowed, blocked := getPolicies(policy) isExplicitlyAllowed, cause := doPoliciesApply(field, body, headers, allowed)