Production Validation
Development defaults favor a short feedback loop: generated routes are public
until Auth middleware is registered, QueryTimeout is unlimited, and
AutoMigrate is enabled. Before deployment, audit the fully assembled server:
cfg := maniflex.Config{
Strict: true,
DisableAutoMigrate: true,
QueryTimeout: 30 * time.Second,
}
server := maniflex.New(cfg)
server.MustRegister(User{}, Order{})
server.Pipeline.Auth.Register(auth.JWTAuth(publicKey, auth.JWTOptions{}))
if err := server.ValidateProduction(); err != nil {
log.Fatal(err)
}
log.Fatal(server.Start())
Call ValidateProduction after registering models, middleware, actions, global
search, and documentation, but before Start or Handler. It reports every
problem together and changes no runtime behavior.
What it requires
Config.Strictis enabled.Config.QueryTimeoutis positive.Config.MaxConcurrentRequestsis positive, so a burst is refused rather than queued on the database pool.- Every global and per-model effective
QueryLimitsfield remains positively bounded, as does global search’sMaxLimitwhen search is mounted. - AutoMigrate is disabled when models are registered.
- Every generated model operation has matching
Pipeline.Authmiddleware or an explicit public declaration. - Standalone files, custom actions, and global search each have a protected or explicitly public access decision.
It also runs every registry check Start runs, so one call reports the whole
startup posture rather than only the part specific to production:
- Encrypted
uniquefields have a blind-index key, so their uniqueness digests can still be re-derived after a key rotation. - Fields tagged
file_acl:signedhave aFileStoragethat can mint a time-limited URL, rather than degrading to a permanent one. - Every model field has a Go type the OpenAPI generator can describe.
- Relations,
lock_scopedeclarations, andPipelinemiddleware wiring resolve.
Several of those are findings Config.Strict turns fatal, and production
validation requires Strict, so they surface here rather than at the first boot.
Framework outbound calls made through integration.Caller already have bounded
timeout, retry, and response-size defaults. The validator cannot inspect
arbitrary http.Client instances created by application code.
Proxy-header resolution remains off by default, which is safe. TrustedProxies
names the peers whose forwarding headers may be believed, and the validator can
check that the entries parse but not that they describe your actual topology.
TrustProxyHeaders: true with no TrustedProxies is the legacy allowlist-free
mode — the explicit assertion that the service sits behind a proxy which replaces
client-supplied forwarding headers itself. It warns at startup and, because
Config.Strict is required for production validation to pass, fails there.
Declaring public model operations
Server.AllowPublic marks only the scopes you name:
// Public sign-up; every other User operation still needs Auth coverage.
server.AllowPublic(
maniflex.ForModel("User"),
maniflex.ForOperation(maniflex.OpCreate),
)
This is a validation declaration, not middleware. It does not make a protected route public or alter request handling.
Other route types
Standalone files use FilesConfig.BeforeMiddlewares; set
FilesConfig.AllowPublic only when /files is deliberately public.
Custom actions normally inherit matching Pipeline.Auth middleware. If access
is enforced inside ActionConfig.Middleware or the handler, set
ActionConfig.AccessControlled. Set ActionConfig.AllowPublic for an
intentionally public action.
Global search likewise uses Pipeline.Auth for OpSearch, or an explicit
GlobalSearchConfig.AllowPublic.
If a router-level middleware protects every route before dispatch, set
Config.HTTPAccessControlled alongside non-empty Config.HTTPMiddlewares.
This flag is an assertion and does not install authentication.
Generated documentation is already explicit: its zero value mounts nothing,
Documentation.Middleware protects it, and Documentation.Public deliberately
publishes it. Static serving requires an explicit non-empty StaticDir.
The probe endpoints — /live, /ready, and /health — are public by default
and the sweep exempts them, because an orchestrator’s probe is the canonical
unauthenticated request. Config.Probes gates or unmounts them when that is not
what you want; setting it does not change what ValidateProduction asks for.