Skip to content

Zhaba1337228/GuardGo

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

29 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

GuardGo

High-throughput, Redis-backed API protection for Go.

Atomic Lua critical path. Reputation pipeline. Behavioral entropy. Hot-reloadable signatures. Zero-allocation fast path.

CI CodeQL govulncheck codecov Go Reference Go Report Card License Go Version Release

English Β· Русский Β· δΈ­ζ–‡


✨ Highlights

⚑ ~12 ns clean-request fast path Bloom filter short-circuits hot paths with zero allocations
πŸ›‘οΈ Atomic Redis Lua critical path Blacklist + rate-limit decision in a single round-trip
🧠 Reputation pipeline Static rules + score evaluators + DFA signatures + behavioral entropy
πŸ”₯ Hot-reload without restart SIGHUP-driven ruleset swap, no dropped connections
πŸͺœ Dynamic backoff Escalating ban TTLs: 1m β†’ 10m β†’ 24h
🧯 Self-healing limits Auto-tightens under load, decays back when traffic clears
πŸ“Š Observability built-in OpenTelemetry spans, Prometheus sidecar, generic stats hook
🧩 Drop-in middleware net/http, gin, echo, fiber β€” one line each

πŸ“¦ Install

go get github.com/Zhaba1337228/GuardGo

Requires Go 1.25+ Β· Redis 6.2+ / Valkey / KeyDB / Dragonfly


πŸš€ Quick Start

Zero-config

guard := guardgo.New(guardgo.DefaultConfig())
defer guard.Close()

Defaults: Redis at 127.0.0.1:6379, 1000 req/s.

net/http

package main

import (
    "net/http"
    "time"

    guardgo "github.com/Zhaba1337228/GuardGo"
    "github.com/redis/go-redis/v9"
)

func main() {
    rdb := redis.NewClient(&redis.Options{Addr: "127.0.0.1:6379"})

    cfg := guardgo.NewConfig(rdb, 200, 1*time.Second)
    cfg.FailOpen = true
    cfg.Bloom.Enabled = true
    cfg.Reputation.Enabled = true
    cfg.Reputation.WarningLevel = 60
    cfg.Reputation.Threshold = 100

    engine := guardgo.New(cfg)
    defer engine.Close()

    mux := http.NewServeMux()
    mux.HandleFunc("/healthz", func(w http.ResponseWriter, _ *http.Request) {
        w.WriteHeader(http.StatusOK)
    })

    _ = http.ListenAndServe(":8080", engine.Middleware(mux))
}

Framework adapters

router.Use(guardgo.Gin(engine))
e.Use(guardgo.Echo(engine))
app.Use(guardgo.Fiber(engine))

πŸ”¬ How It Works

                β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
  request ───▢  β”‚  Local LRU blacklist cache   β”‚  ─── hit ──▢ block (cached)
                β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                           β”‚ miss
                           β–Ό
                β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                β”‚  Penalty box check           β”‚  ─── strict mode (UA/Referer required)
                β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                           β”‚ pass
                           β–Ό
                β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                β”‚  Bloom filter (negative)     β”‚  ─── definitely-not-banned ──▢ allow
                β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                           β”‚ unknown
                           β–Ό
                β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                β”‚  Redis Lua (atomic):         β”‚
                β”‚   β€’ blacklist set check      β”‚
                β”‚   β€’ rate-limit counter       β”‚
                β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                           β”‚
                           β–Ό
                       allow / block
                           β”‚
                           β–Ό (async, off critical path)
                β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                β”‚  Reputation pipeline:        β”‚
                β”‚   β€’ static Rule checks       β”‚
                β”‚   β€’ Evaluator score          β”‚
                β”‚   β€’ DFA signatures           β”‚
                β”‚   β€’ behavioral entropy       β”‚
                β”‚   ─▢ penalty / blacklist     β”‚
                β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ›‘οΈ Security Model

GuardGo evaluates traffic through a score pipeline:

Score Action
< WarningLevel Normal flow
β‰₯ WarningLevel Penalty mode (strict UA/Referer, tightened limit)
β‰₯ Threshold Blacklist via Redis Lua, escalating ban TTL

Fingerprint: IP + User-Agent + Accept-Language (case-folded, hashed).

Dynamic backoff (per IP, sliding window):

Attempt Default TTL
#1 1m
#2 10m
#3+ 24h

πŸ”₯ Hot Reload

If RulesetFile or DynamicRules is configured, signatures hot-reload on POSIX SIGHUP:

kill -HUP <pid>

No process restart. No dropped connections.

Built-in presets

rules.ApplyDefaultSecurityPresets(&cfg)

Bundled signatures: SQLi probes, path traversal, scanner UA fingerprints, common exploit paths.


πŸ“Š Observability

Surface What you get
OpenTelemetry guardgo.process span with decision attributes
Prometheus sidecar cmd/guardgo-agent exposes /metrics
Live dashboard cmd/guardgo-cli β€” terminal UI: top risk, active blocks, DFA stats
Generic hook StatsCollector interface β€” forward to Datadog / OTEL / custom
go run ./cmd/guardgo-agent --redis-addr 127.0.0.1:6379 --prefix guardgo --listen :9090
go run ./cmd/guardgo-cli   --redis-addr 127.0.0.1:6379 --prefix guardgo --ruleset ./rules.yaml

⚑ Benchmarks

12th Gen Intel(R) Core(TM) i5-12400 Β· windows/amd64 Β· 2026-03-08

Case Latency Throughput Allocations
Clean Request (Bloom) 11.8 ns ~84 M ops/s 0 B/op 0 allocs/op
DFA Match (100 rules) 454 ns ~2.2 M ops/s 24 B/op 1 alloc/op
Redis Fallback (parallel, miniredis) 205–225 Β΅s ~4.4 K ops/s/core ~206 KB/op

Reproduce:

go test ./pkg/bloom -run ^$ -bench BenchmarkBloomCleanRequest -benchmem -benchtime=5s -count=5
go test ./pkg/dfa   -run ^$ -bench BenchmarkDFA100RulesMatch  -benchmem -benchtime=5s -count=5
go test ./tests/load -run ^$ -bench BenchmarkEngineCheckParallel -benchmem -benchtime=10s -count=5

# Real Redis fallback (recommended for production profiling)
REDIS_ADDR=127.0.0.1:6379 \
  go test ./tests/load -run ^$ -bench BenchmarkRedisFallbackRealRedis -benchmem -benchtime=10s -count=5

πŸ§ͺ Testing

go test ./...                                          # all unit + integration (miniredis)
go test -race ./tests/integration -count=1             # data races
REDIS_ADDR=127.0.0.1:6379 go test ./tests/load -bench .  # real Redis perf
go test -tags chaos ./tests/chaos -v -count=1          # chaos (requires Docker)

πŸ—‚οΈ Project Layout

.
β”œβ”€β”€ engine*.go           # core decision pipeline (split by concern)
β”œβ”€β”€ decision.go          # Reason / Decision types and headers
β”œβ”€β”€ config.go            # MiddlewareConfig + defaults
β”œβ”€β”€ frameworks.go        # Gin / Echo / Fiber adapters
β”œβ”€β”€ middleware_http.go   # net/http middleware
β”œβ”€β”€ ruleset.go           # YAML/JSON ruleset loader + hot-reload
β”œβ”€β”€ pkg/
β”‚   β”œβ”€β”€ bloom/           # zero-alloc bloom filter
β”‚   └── dfa/             # multi-pattern DFA matcher
β”œβ”€β”€ internal/
β”‚   β”œβ”€β”€ blacklist/       # local LRU
β”‚   └── redislua/        # embedded Lua scripts
β”œβ”€β”€ rules/               # built-in rules and presets
β”œβ”€β”€ cmd/
β”‚   β”œβ”€β”€ guardgo-agent/   # Prometheus sidecar
β”‚   └── guardgo-cli/     # live dashboard
β”œβ”€β”€ examples/            # net/http, gin, presets
└── tests/
    β”œβ”€β”€ integration/     # miniredis-driven
    β”œβ”€β”€ load/            # benchmarks
    └── chaos/           # testcontainers-driven (build tag: chaos)

πŸ“š Documentation


🀝 Contributing

PRs welcome. See CONTRIBUTING.md and CODE_OF_CONDUCT.md.

Conventional commits are required (feat:, fix:, perf:, docs:, test:, ci:, chore:) β€” release-please uses them to drive CHANGELOG.md and version bumps.

πŸ”’ Security

Found a vulnerability? See SECURITY.md. Please do not open public issues with exploit details before a fix is in place.

πŸ“„ License

MIT Β© GuardGo contributors

About

High-performance, adaptive API security middleware for Go. Features Bloom filters, DFA-based signature matching, and adaptive rate-limiting with near-zero memory overhead.

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages