Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
8bd1acb
Automated README update (#159)
github-actions[bot] Dec 25, 2025
2b455e2
Automated README update (#161)
github-actions[bot] Dec 27, 2025
06eb1e1
Automated README update (#164)
github-actions[bot] Jan 2, 2026
6d50fa9
Automated README update (#165)
github-actions[bot] Jan 2, 2026
6519040
.
CodeShellDev Jan 2, 2026
e0dfa89
Automated README update (#166)
github-actions[bot] Jan 2, 2026
92f0abd
Automated README update (#167)
github-actions[bot] Jan 2, 2026
d8398e4
Automated README update (#168)
github-actions[bot] Jan 2, 2026
086982f
feat: Path Auth (#170)
CodeShellDev Jan 2, 2026
7136afb
update PR and issue templates
CodeShellDev Jan 2, 2026
f9f855d
Oops, fixed templates again
CodeShellDev Jan 2, 2026
ce40491
feat: Body auth (#172)
CodeShellDev Jan 2, 2026
61873bc
feat: Port per Token Config (#174)
CodeShellDev Jan 3, 2026
8434b8b
feat: Log Level per Token (#176)
CodeShellDev Jan 3, 2026
57d062b
feat: Rate Limiting (#178)
CodeShellDev Jan 3, 2026
30ac476
default: allow all
CodeShellDev Jan 6, 2026
534e5bb
maybe make INSECURE configurable
CodeShellDev Jan 6, 2026
5ee203c
DEPRECATION: @authorization => @auth (#184)
CodeShellDev Jan 6, 2026
d5182a0
feat: IP Filtering (#181)
CodeShellDev Jan 6, 2026
c376af9
misc: Santa is Dead (#186)
CodeShellDev Jan 6, 2026
973847b
.
CodeShellDev Jan 6, 2026
4e89c7c
DEPRECATION: .token, .tokens, .overrides (#187)
CodeShellDev Jan 6, 2026
7181b9d
feat: Hostnames (#188)
CodeShellDev Jan 7, 2026
d8a753a
update PR template
CodeShellDev Jan 7, 2026
21571e9
feat: Regex in Field Policies (#193)
CodeShellDev Jan 8, 2026
301c358
Merge branch 'main' into v1.5.0
CodeShellDev Jan 8, 2026
08a4b67
update deps
CodeShellDev Jan 9, 2026
fe3b02d
remove old dep versions
CodeShellDev Jan 9, 2026
faa7655
use gotl with separate pkgs
CodeShellDev Jan 9, 2026
4a82a2d
add deprecation messages
CodeShellDev Jan 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 17 additions & 5 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,34 @@ module github.com/codeshelldev/secured-signal-api

go 1.25.5

require github.com/codeshelldev/gotl v0.0.12

require go.uber.org/zap v1.27.1 // indirect
require (
github.com/codeshelldev/gotl/pkg/configutils v0.0.4
github.com/codeshelldev/gotl/pkg/docker v0.0.2
github.com/codeshelldev/gotl/pkg/jsonutils v0.0.2
github.com/codeshelldev/gotl/pkg/logger v0.0.3
github.com/codeshelldev/gotl/pkg/pretty v0.0.8
github.com/codeshelldev/gotl/pkg/query v0.0.3
github.com/codeshelldev/gotl/pkg/request v0.0.3
github.com/codeshelldev/gotl/pkg/stringutils v0.0.3
github.com/codeshelldev/gotl/pkg/templating v0.0.3
github.com/knadh/koanf/parsers/yaml v1.1.0
go.uber.org/zap v1.27.1
golang.org/x/time v0.14.0
)

require (
github.com/clipperhouse/uax29/v2 v2.2.0 // indirect
github.com/fsnotify/fsnotify v1.9.0 // indirect
github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
github.com/knadh/koanf/maps v0.1.2 // indirect
github.com/knadh/koanf/parsers/yaml v1.1.0
github.com/knadh/koanf/providers/confmap v1.0.0 // indirect
github.com/knadh/koanf/providers/env/v2 v2.0.0 // indirect
github.com/knadh/koanf/providers/file v1.2.1 // indirect
github.com/knadh/koanf/v2 v2.3.0 // indirect
github.com/mattn/go-runewidth v0.0.19 // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.yaml.in/yaml/v3 v3.0.4 // indirect
golang.org/x/sys v0.39.0 // indirect
golang.org/x/sys v0.40.0 // indirect
)
34 changes: 28 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,7 +1,25 @@
github.com/codeshelldev/gotl v0.0.9 h1:cdLA6XzPt+f4RIW24Yx3dqBbRAq5JO0obzuwhaOgsEo=
github.com/codeshelldev/gotl v0.0.9/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/clipperhouse/uax29/v2 v2.2.0 h1:ChwIKnQN3kcZteTXMgb1wztSgaU+ZemkgWdohwgs8tY=
github.com/clipperhouse/uax29/v2 v2.2.0/go.mod h1:EFJ2TJMRUaplDxHKj1qAEhCtQPW2tJSwu5BF98AuoVM=
github.com/codeshelldev/gotl/pkg/configutils v0.0.4 h1:AHCCP+8FzFKP8lMtytWo98x0583bCPI7wykbw6z9pTs=
github.com/codeshelldev/gotl/pkg/configutils v0.0.4/go.mod h1:WoWMBB8+84ePRnI2m+kbq1Rw8F/9iCWLHkVBsun3Qjc=
github.com/codeshelldev/gotl/pkg/docker v0.0.2 h1:kpseReocEBoSzWe/tOhUrIrOYeAR/inw3EF2/d+N078=
github.com/codeshelldev/gotl/pkg/docker v0.0.2/go.mod h1:odNnlRw4aO1n2hSkDZIaiuSXIoFoVeatmXtF64Yd33U=
github.com/codeshelldev/gotl/pkg/jsonutils v0.0.2 h1:ERsjkaWVrsyUZoEunCEeNYDXhuaIvoSetB8e/zI4Tqo=
github.com/codeshelldev/gotl/pkg/jsonutils v0.0.2/go.mod h1:oxgKaAoMu6iYVHfgR7AhkK22xbYx4K0KCkyVEfYVoWs=
github.com/codeshelldev/gotl/pkg/logger v0.0.3 h1:M99fsH7SiIFS4jNRCNtu3BJNYdcPD+LbqJ7l5aBQeJ8=
github.com/codeshelldev/gotl/pkg/logger v0.0.3/go.mod h1:pL/I7KYxbGHhyedallZlCkBvoalv9gAWNEYVXbF9BoM=
github.com/codeshelldev/gotl/pkg/pretty v0.0.6 h1:b+1k4Sm6Do7TqUlOFQ5YjybyHJMXYs72GYYBJpSL5JQ=
github.com/codeshelldev/gotl/pkg/pretty v0.0.6/go.mod h1:2Gk6UBrtkIME2RCSNytS/RJ5lHXYL/MDx0rYRpknobM=
github.com/codeshelldev/gotl/pkg/pretty v0.0.8 h1:buLobwNqZRlYGnfyFLi7A7z2m7362Wm9k5Y+Tv0tMsI=
github.com/codeshelldev/gotl/pkg/pretty v0.0.8/go.mod h1:2Gk6UBrtkIME2RCSNytS/RJ5lHXYL/MDx0rYRpknobM=
github.com/codeshelldev/gotl/pkg/query v0.0.3 h1:Zy8k0R5HcJS00OMPRHybgFEiwMg7ceLyv6bA0G7NOfs=
github.com/codeshelldev/gotl/pkg/query v0.0.3/go.mod h1:kKaPOKXluIid3qeS7xzrmfq3NxIa8/PhKYHM6GRbwJw=
github.com/codeshelldev/gotl/pkg/request v0.0.3 h1:maRPHu366NARow8/m1Q8Cw1EU1Uy0pDIn1vlAsOatKM=
github.com/codeshelldev/gotl/pkg/request v0.0.3/go.mod h1:vCXIZ2n/XxvEVInBQv9eIh0kQ2353V+WymL8kZ9yrOU=
github.com/codeshelldev/gotl/pkg/stringutils v0.0.3 h1:7k/HMnX7me8Kchm41I/M6dp3wXI0XORI3oyS87O0Viw=
github.com/codeshelldev/gotl/pkg/stringutils v0.0.3/go.mod h1:/dWlzYoTj23LmpFs+Bpal4tfUDbOVeApIgkLv9gTgUE=
github.com/codeshelldev/gotl/pkg/templating v0.0.3 h1:PAz6VN8yGBuZIdR/sDM+TmW1OFykl+I7/Zwa07uMgYA=
github.com/codeshelldev/gotl/pkg/templating v0.0.3/go.mod h1:D+wxgsPSiq9HShEzv1mhYAjGJyasWgPoIu+nRk4TPqY=
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=
Expand All @@ -24,6 +42,8 @@ github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/mattn/go-runewidth v0.0.19 h1:v++JhqYnZuu5jSKrk9RbgF5v4CGUjqRfBm05byFGLdw=
github.com/mattn/go-runewidth v0.0.19/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs=
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
Expand All @@ -40,8 +60,10 @@ go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc=
go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk=
golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ=
golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI=
golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
Expand Down
27 changes: 15 additions & 12 deletions internals/config/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"strings"

"github.com/codeshelldev/gotl/pkg/configutils"
log "github.com/codeshelldev/gotl/pkg/logger"
"github.com/codeshelldev/gotl/pkg/logger"
"github.com/codeshelldev/gotl/pkg/stringutils"
"github.com/codeshelldev/secured-signal-api/internals/config/structure"

Expand Down Expand Up @@ -63,13 +63,13 @@ func Load() {

InitTokens()

log.Info("Finished Loading Configuration")
logger.Info("Finished Loading Configuration")
}

func Log() {
log.Dev("Loaded Config:", mainConf.Layer.Get(""))
log.Dev("Loaded Token Configs:", tokenConf.Layer.Get(""))
log.Dev("Parsed Configs: ", ENV)
logger.Dev("Loaded Config:", mainConf.Layer.Get(""))
logger.Dev("Loaded Token Configs:", tokenConf.Layer.Get(""))
logger.Dev("Parsed Configs: ", ENV)
}

func Clear() {
Expand Down Expand Up @@ -102,7 +102,7 @@ func Normalize(id string, config *configutils.Config, path string, structure any
old, ok := data.(map[string]any)

if !ok {
log.Warn("Could not load `"+path+"`")
logger.Warn("Could not load `"+path+"`")
return
}

Expand All @@ -111,7 +111,10 @@ func Normalize(id string, config *configutils.Config, path string, structure any
tmpConf.Load(old, "")

// Apply transforms to the new config
tmpConf.ApplyTransformFuncs(id, structure, "", transformFuncs)
tmpConf.ApplyTransformFuncs(id, structure, "", configutils.TransformOptions{
Transforms: transformFuncs,
OnUse: onUseFuncs,
})

// Lowercase actual config
LowercaseKeys(config)
Expand All @@ -124,7 +127,7 @@ func Normalize(id string, config *configutils.Config, path string, structure any

func InitReload() {
reload := func(path string) {
log.Debug(path, " changed, reloading...")
logger.Debug(path, " changed, reloading...")
Load()
Log()
}
Expand All @@ -145,16 +148,16 @@ func InitConfig() {
}

func LoadDefaults() {
log.Debug("Loading defaults ", ENV.DEFAULTS_PATH)
logger.Debug("Loading defaults ", ENV.DEFAULTS_PATH)
_, err := defaultsConf.LoadFile(ENV.DEFAULTS_PATH, yaml.Parser())

if err != nil {
log.Warn("Could not Load Defaults", ENV.DEFAULTS_PATH)
logger.Warn("Could not Load Defaults", ENV.DEFAULTS_PATH)
}
}

func LoadConfig() {
log.Debug("Loading Config ", ENV.CONFIG_PATH)
logger.Debug("Loading Config ", ENV.CONFIG_PATH)
_, err := userConf.LoadFile(ENV.CONFIG_PATH, yaml.Parser())

if err != nil {
Expand All @@ -166,7 +169,7 @@ func LoadConfig() {
return
}

log.Error("Could not Load Config ", ENV.CONFIG_PATH, ": ", err.Error())
logger.Error("Could not Load Config ", ENV.CONFIG_PATH, ": ", err.Error())
}
}

Expand Down
54 changes: 54 additions & 0 deletions internals/config/parser.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
package config

import (
"fmt"
"strings"

"github.com/codeshelldev/gotl/pkg/configutils"
"github.com/codeshelldev/gotl/pkg/pretty"
)

var transformFuncs = map[string]func(string, any) (string, any) {
Expand All @@ -21,4 +25,54 @@ func lowercaseTransform(key string, value any) (string, any) {

func uppercaseTransform(key string, value any) (string, any) {
return strings.ToUpper(key), value
}

var onUseFuncs = map[string]func(source string, target configutils.TransformTarget) {
"deprecated": func(source string, target configutils.TransformTarget) {
box := pretty.NewAutoBox()
box.MinWidth = 50
box.PaddingX = 2
box.PaddingY = 1

box.Border.Style = pretty.BorderStyle{
Color: pretty.Basic(pretty.Yellow),
}

box.AddBlock(pretty.Block{
Align: pretty.AlignCenter,
Style: pretty.Style{},
Segments: []pretty.Segment{
pretty.TextBlockSegment{
Text: "🚨 Deprecation 🚨",
Style: pretty.Style{
Bold: true,
Foreground: pretty.Basic(pretty.Yellow),
},
},
pretty.InlineSegment{},
pretty.TextBlockSegment{
Text: "Please refrain from using",
},
pretty.InlineSegment{},
pretty.TextBlockSegment{
Text: "`" + source + "`",
Style: pretty.Style{
Italic: true,
Bold: true,
Background: pretty.Basic(pretty.Red),
},
},
pretty.InlineSegment{},
pretty.InlineSegment{
Items: []pretty.Inline{
pretty.Span{
Text: "as it has been marked as deprecated",
},
},
},
},
})

fmt.Println(box.Render())
},
}
27 changes: 18 additions & 9 deletions internals/config/structure/structure.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,29 +11,29 @@ type ENV struct {
}

type CONFIG struct {
NAME string `koanf:"name"`
SERVICE SERVICE `koanf:"service"`
API API `koanf:"api"`
//TODO: deprecate overrides for tkconfigs
SETTINGS SETTINGS `koanf:"settings" token>aliases:"overrides"`
SETTINGS SETTINGS `koanf:"settings"`
}

type SERVICE struct {
HOSTNAMES []string `koanf:"hostnames" env>aliases:".hostnames"`
PORT string `koanf:"port" env>aliases:".port"`
LOG_LEVEL string `koanf:"loglevel" env>aliases:".loglevel"`
}

type API struct {
URL string `koanf:"url" env>aliases:".apiurl"`
//TODO: deprecate .token for tkconfigs
TOKENS []string `koanf:"tokens" env>aliases:".apitokens,.apitoken" token>aliases:".tokens,.token" aliases:"token"`
TOKENS []string `koanf:"tokens" env>aliases:".apitokens,.apitoken" aliases:"token"`
}

type SETTINGS struct {
ACCESS ACCESS_SETTINGS `koanf:"access"`
MESSAGE MESSAGE_SETTINGS `koanf:"message"`
ACCESS ACCESS `koanf:"access"`
MESSAGE MESSAGE `koanf:"message"`
}

type MESSAGE_SETTINGS struct {
type MESSAGE struct {
VARIABLES map[string]any `koanf:"variables" childtransform:"upper"`
FIELD_MAPPINGS map[string][]FieldMapping `koanf:"fieldmappings" childtransform:"default"`
TEMPLATE string `koanf:"template"`
Expand All @@ -44,12 +44,21 @@ type FieldMapping struct {
Score int `koanf:"score"`
}

type ACCESS_SETTINGS 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"`
TRUSTED_PROXIES []string `koanf:"trustedproxies"`
}

type FieldPolicy struct {
Value any `koanf:"value"`
Action string `koanf:"action"`
}

type RateLimiting struct {
Limit int `koanf:"limit"`
Period string `koanf:"period"`
}
53 changes: 46 additions & 7 deletions internals/config/tokens.go
Original file line number Diff line number Diff line change
@@ -1,21 +1,24 @@
package config

import (
"path/filepath"
"reflect"
"strconv"
"strings"

"github.com/codeshelldev/gotl/pkg/configutils"
log "github.com/codeshelldev/gotl/pkg/logger"
"github.com/codeshelldev/gotl/pkg/logger"
"github.com/codeshelldev/secured-signal-api/internals/config/structure"
"github.com/knadh/koanf/parsers/yaml"
)

func LoadTokens() {
log.Debug("Loading Configs in ", ENV.TOKENS_DIR)
logger.Debug("Loading Configs in ", ENV.TOKENS_DIR)

err := tokenConf.LoadDir("tokenconfigs", ENV.TOKENS_DIR, ".yml", yaml.Parser(), func(c *configutils.Config, s string) {})
err := tokenConf.LoadDir("tokenconfigs", ENV.TOKENS_DIR, ".yml", yaml.Parser(), setTokenConfigName)

if err != nil {
log.Error("Could not Load Configs in ", ENV.TOKENS_DIR, ": ", err.Error())
logger.Error("Could not Load Configs in ", ENV.TOKENS_DIR, ": ", err.Error())
}

tokenConf.TemplateConfig()
Expand Down Expand Up @@ -57,9 +60,9 @@ func InitTokens() {
}

if len(apiTokens) <= 0 {
log.Warn("No API Tokens provided this is NOT recommended")
logger.Warn("No API Tokens provided this is NOT recommended")

log.Info("Disabling Security Features due to incomplete Congfiguration")
logger.Info("Disabling Security Features due to incomplete Congfiguration")

ENV.INSECURE = true

Expand All @@ -69,7 +72,7 @@ func InitTokens() {
}

if len(apiTokens) > 0 {
log.Debug("Registered " + strconv.Itoa(len(apiTokens)) + " Tokens")
logger.Debug("Registered " + strconv.Itoa(len(apiTokens)) + " Tokens")
}
}

Expand All @@ -84,3 +87,39 @@ func parseTokenConfigs(configArray []structure.CONFIG) map[string]structure.CONF

return configs
}

func getSchemeTagByPointer(config any, tag string, fieldPointer any) string {
v := reflect.ValueOf(config)
if v.Kind() == reflect.Pointer {
v = v.Elem()
}

fieldValue := reflect.ValueOf(fieldPointer).Elem()

for i := 0; i < v.NumField(); i++ {
if v.Field(i).Addr().Interface() == fieldValue.Addr().Interface() {
field := v.Type().Field(i)

return field.Tag.Get(tag)
}
}

return ""
}

func setTokenConfigName(config *configutils.Config, p string) {
schema := structure.CONFIG{
NAME: "",
}

nameField := getSchemeTagByPointer(&schema, "koanf", &schema.NAME)

filename := filepath.Base(p)
filenameWithoutExt := strings.TrimSuffix(filename, filepath.Ext(filename))

name := config.Layer.String(nameField)

if strings.TrimSpace(name) == "" {
config.Layer.Set(nameField, filenameWithoutExt)
}
}
Loading