Skip to content

Usage

Constructor

func New(engine *guardcore.Engine, opts ...Option) (echo.MiddlewareFunc, error)

New returns an echo.MiddlewareFunc, so the guard composes with e.Use (or group.Use) anywhere in a middleware chain. It rejects a nil engine with an error; invalid option values are silently ignored so a bad flag can never weaken security.

Options

Option Default Purpose
WithMaxBodyBytes(int64) DefaultMaxBodyBytes (262144) Body prefix handed to the engine for inspection
WithLogger(*log.Logger) log.Default() Receive fail-closed diagnostics (prefix guardcore echo: ...)
guard, err := guardecho.New(engine,
    guardecho.WithMaxBodyBytes(64*1024),
    guardecho.WithLogger(log.New(os.Stderr, "guardecho ", log.LstdFlags)),
)

Route IDs

Per-route configuration lives in the engine's RouteRegistry. Attach a route ID to the request context in a middleware registered before the guard: Echo runs middleware in registration order, so a group-level middleware would run after the guard and the engine would never see the ID.

engine.Routes.Register("admin", func(rc *guardcore.RouteConfig) {
    rc.RequiredHeaders = guardcore.RequiredHeaders{
        {Name: "X-Admin-Token", Value: "secret"},
    }
})

routeIDs := map[string]string{
    "/admin/banned": "admin",
    "/admin/ban":    "admin",
    "/admin/unban":  "admin",
}

// Keys are echo route patterns (c.Path()), so parameterized routes map
// cleanly.
router.Use(func(next echolib.HandlerFunc) echolib.HandlerFunc {
    return func(c echolib.Context) error {
        if routeID, ok := routeIDs[c.Path()]; ok {
            c.SetRequest(c.Request().WithContext(guardecho.WithRouteID(c.Request().Context(), routeID)))
        }
        return next(c)
    }
})
router.Use(guard) // the mapper must run before the guard

Verdicts

When the engine returns a block verdict, the middleware writes the verdict status code, headers, and body to c.Response() and returns nil without calling next(c), so no later handler runs:

Situation Status Body
Banned IP 403 IP address banned
Suspicious content 400 Suspicious activity detected
Rate limit exceeded 429 Too many requests

Bodies can be overridden globally through SecurityConfig.CustomErrorResponses.

Fail-closed behavior

If the engine check panics, the middleware recovers, logs through the WithLogger sink, and responds 500 Security check failed rather than letting the request through.