Forge Extension
Mount Sentinel into a Forge application as a first-class extension with automatic route registration and migrations.
Sentinel ships a ready-made Forge extension in the extension package. It wires the engine, HTTP API, and lifecycle management into Forge's extension system.
Installation
import "github.com/xraph/sentinel/extension"Registering the extension
package main
import (
"github.com/xraph/forge"
pgstore "github.com/xraph/sentinel/store/postgres"
"github.com/xraph/sentinel/extension"
)
func main() {
app := forge.New()
sentinelExt := extension.New(
extension.WithStore(pgstore.New(bunDB)),
)
app.RegisterExtension(sentinelExt)
app.Run()
}What the extension does
| Lifecycle event | Behaviour |
|---|---|
Register | Creates the engine from the provided options |
Start | Runs store.Migrate (unless disabled) |
RegisterRoutes | Mounts all 32+ Sentinel HTTP endpoints under /sentinel |
Stop | Calls engine.Stop → emits OnShutdown to all extensions |
Extension options
| Option | Description |
|---|---|
extension.WithStore(s) | Sets the composite store (required) |
extension.WithExtension(x) | Registers a Sentinel plugin extension |
extension.WithEngineOption(opt) | Passes an engine option directly |
extension.WithLogger(l) | Sets the structured logger |
Accessing the engine from other extensions
After Register is called by Forge, sentinelExt.Engine() returns the fully initialised engine:
eng := sentinelExt.Engine()
// use eng.CreateSuite, eng.ListRuns, etc. from another extensionTenant middleware
In a Forge app, tenant scope is typically set by middleware. Implement a Forge middleware that calls sentinel.WithTenant and sentinel.WithApp:
func tenantMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
tenantID := r.Header.Get("X-Tenant-ID")
appID := r.Header.Get("X-App-ID")
ctx := sentinel.WithTenant(r.Context(), tenantID)
ctx = sentinel.WithApp(ctx, appID)
next.ServeHTTP(w, r.WithContext(ctx))
})
}
router.Use(tenantMiddleware)Adding metrics
Register the observability extension alongside the Sentinel engine extension:
import "github.com/xraph/sentinel/observability"
metricsExt := observability.NewMetricsExtensionWithFactory(fapp.Metrics())
sentinelExt := extension.New(
extension.WithStore(store),
extension.WithExtension(metricsExt),
)