RRuna

Security Preset

Compose recover, request id, real ip, logger, bodylimit, timeout, and helmet with one middleware

security is Runa’s official production entry preset. It combines several baseline HTTP middleware into one chain, so new projects can connect basic protection first, then add CORS, session, auth, rate limit, and audit as needed.

Default chain:

recover -> requestid -> realip -> logger -> bodylimit -> timeout -> helmet

Install

go get github.com/duxweb/runa/security

Quick usage

import "github.com/duxweb/runa/security"

route.Default().Use(security.New(security.Production()))

Complete example

package main

import (
    "context"
    "time"

    "github.com/duxweb/runa"
    "github.com/duxweb/runa/route"
    "github.com/duxweb/runa/security"
)

func main() {
    app := runa.New()
    app.Install(route.Provider(route.Addr(":8080")))

    route.Default().Use(security.New(
        security.Production(),
        security.BodyLimit("16MB"),
        security.Timeout(30*time.Second),
        security.TrustedProxies("10.0.0.0/8"),
        security.SkipPaths("/health", "/metrics"),
    ))

    route.Default().Get("/", func(ctx *route.Context) error {
        return ctx.Text("ok")
    })

    if err := app.Run(context.Background()); err != nil {
        panic(err)
    }
}

Development and Production

Development preset:

route.Default().Use(security.New(security.Development()))

Development keeps panic stack output, sets timeout to 120s, and trusts local proxies.

Production preset:

route.Default().Use(security.New(security.Production()))

Production disables panic stack output, uses 30s timeout, and clears trusted proxies. If production runs behind a gateway, configure security.TrustedProxies(...) explicitly.

Common options

Option Description
security.Development() Development-friendly defaults
security.Production() Production-friendly defaults
security.BodyLimit("16MB") Set request body size limit
security.Timeout(30*time.Second) Set request timeout
security.TrustedProxies("10.0.0.0/8") Set trusted proxies
security.SkipPaths("/health") Skip logger for paths
security.Next(fn) Skip the whole security chain
security.Disable("logger") Disable one built-in item

Disable names: recover, requestid, realip, logger, bodylimit, timeout, helmet.

Skip the whole chain

route.Default().Use(security.New(security.Next(func(ctx *route.Context) bool {
    return ctx.Request().URL.Path == "/health"
})))

Next skips the whole security chain. If you only want to skip access logs, prefer security.SkipPaths(...).

Relationship with CORS

security does not include CORS. CORS usually depends on frontend origins, credential strategy, and exposed headers, so configure it explicitly:

route.Default().Use(security.New(security.Production()))
route.Default().Use(cors.New(cors.Config{
    AllowOrigins: []string{"https://admin.example.com"},
    Credentials:  true,
}))

When not to use security

If you need complete control over each middleware’s order and config, compose them manually:

route.Default().Use(
    recover.New(recover.Config{Stack: false}),
    requestid.New(),
    realip.New(realip.Config{TrustedProxies: []string{"10.0.0.0/8"}}),
    logger.New(logger.Config{SkipPaths: []string{"/health"}}),
    bodylimit.New(bodylimit.Config{Limit: 16 << 20}),
    timeout.New(timeout.Config{Timeout: 30 * time.Second}),
    helmet.New(),
)

Common problems

  • security is a middleware chain, not a Provider. It does not need runa.Install.
  • security does not include session, auth, rate, or audit. Those are business capabilities and should be mounted on demand.
  • If you already use security, do not mount recover, requestid, realip, logger, bodylimit, timeout, or helmet again unless you explicitly disabled that item.
Edit this page