Skip to content

ServerConfig ​

*di.ServerConfig is the single entry point through which the host injects data, storage, and extension implementations into Wicket. This page lists all of v0.1.4's exported methods (di/server_config.go) grouped by purpose, and explains when each one is read—which determines whether changing it at runtime takes effect.

go
root, err := di.NewRoot()
if err != nil { /* ... */ }
defer root.Close()

cfg := root.ServerConfig()
// ... a series of Set* calls
cfg.Freeze() // wiring complete

Every SetX on ServerConfig has a corresponding getter X(). The getters are for internal use by the container, and the host generally doesn't need to call them, so they aren't listed individually below.

Set and Provider variants ​

Most injection seams offer two forms:

  • SetX(value): pass a value directly. Internally equivalent to SetXProvider(func() T { return value }).
  • SetXProvider(func() T): pass a function for the container to call when it needs the value.

The difference isn't in how you write it, but in when the container calls the function. In v0.1.4 there are three categories:

CategoryMethods involvedWhen the Provider is calledWhat it means in practice
Configuration dataClients, IdentityScopes, ApiResources, ApiScopes, SigningCredentialStores, ValidationKeysStoresEvery time the related service is resolved (transient)The Provider can return the latest data, enabling hot reload without a restart
Storage seamsThe 10 stores other than the authorization parameters message storeCalled once on first use, with the result cached until the process exitsThe Provider is just "deferred construction"; calling SetX again later has no effect
Authorization parameters message storeAuthorizationParametersMessageStoreEvery time it's resolvedReturning nil means no store is used (see below)

The snippet below has been compiled and run:

go
// The client list can be hot-reloaded: this function is called every time ClientStore is resolved
var clients atomic.Pointer[[]*models.Client]
initial := []*models.Client{}
clients.Store(&initial)
cfg.SetClientsProvider(func() []*models.Client { return *clients.Load() })

// Storage seam: called once on first use, and the result is cached
cfg.SetSessionStoreProvider(func() session.Store {
    return session.NewMemoryStore(wallClock{}) // replace with your persistent adapter
})

When hot reloading

Configuration data Providers are called frequently on the request path (ClientStore rebuilds its index and checks for duplicate ids every time it's resolved), so the function itself must be fast and concurrency-safe. Don't query the database inside it; refresh a snapshot in the background and have the Provider only read the snapshot.

Logging ​

MethodDescription
SetLogger(*slog.Logger)Sets the logger used by the container's internal components

Known issue in v0.1.4: SetLogger has no effect on internal components

The container's internal *slog.Logger is fixed when di.NewRoot() runs. Since ServerConfig is created by NewRoot(), the host can't possibly call SetLogger before that, so internal components always use the default logger: JSON format, Debug level, with source locations, written to standard output. server.WithLogger(...) affects only a small number of the Server's own log entries.

Observed: the Quick start example sets a text-format logger, but internal logs such as endpoint routing and client validation still appear on stdout as JSON. The host currently can't adjust the level of these logs. Some v0.1.4 log entries may contain sensitive request parameters. In production, feed stdout into your logging system, filter by level and remove sensitive fields at the collection side, and avoid sending raw logs to untrusted systems. See Logging and observability.

Clients and resources ​

MethodTypeDescription
SetClients / SetClientsProvider[]*models.ClientThe client registry. Wrapped internally with validation and used as the ClientStore
SetIdentityScopes / SetIdentityScopesProvider[]*models.IdentityResourceIdentity resources (openid, profile, etc.)
SetApiResources / SetApiResourcesProvider[]*models.ApiResourceAPI resources; the introspection endpoint uses their names and ApiSecrets to authenticate callers
SetApiScopes / SetApiScopesProvider[]*models.ApiScopeAPI scopes

In v0.1.4, clients and resources can be injected only through these methods; there's no replaceable ClientStore / ResourceStore seam. To load them from a database, use the Provider variants to return a snapshot. For field meanings, see Clients and resources.

Signing and validation keys ​

MethodTypeDescription
SetSigningCredentialStores / SetSigningCredentialStoresProvider[]storage.SigningCredentialStoreSources of signing credentials
SetValidationKeysStores / SetValidationKeysStoresProvider[]storage.ValidationKeysStoreSources of validation public keys, merged and published to the JWKS
SetRecordStore / SetRecordStoreProviderkeymgmt.RecordStoreWhere key records are persisted when automatic key management is on (opts.KeyManagement.Enabled, on by default)

Note that the method is named SetRecordStore, not SetKeyRecordStore. For how to choose between the two key sources, see Signing keys.

Storage seams ​

Method (all have a *Provider variant)InterfaceWhen not injected and fallback is allowed
SetAuthorizationCodeStorestorage.AuthorizationCodeStoreIn-memory implementation + warning log
SetRefreshTokenStorestorage.RefreshTokenStoreSame as above
SetReferenceTokenStorestorage.ReferenceTokenStoreSame as above
SetUserConsentStorestorage.UserConsentStoreSame as above
SetPersistedGrantStorestorage.PersistedGrantStoreSame as above
SetDeviceFlowStorestorage.DeviceFlowStoreSame as above
SetBackchannelAuthenticationRequestStorestorage.BackchannelAuthenticationRequestStoreSame as above
SetSessionStoresession.StoreSame as above
SetDistributedCacheservices.DistributedCacheSame as above
SetRecordStorekeymgmt.RecordStoreSame as above
SetAuthorizationParametersMessageStorestorage.AuthorizationParametersMessageStoreNo fallback: no store is used, and authorization parameters go directly into the callback URL's query string

All 11 items above count toward the completeness check in Freeze(). For interface methods and contracts, see Storage ports.

Releasing resources: root.Close() closes the stores that were actually used, in reverse order of construction; if your adapter implements io.Closer, its Close() is called. Stores that were never used are neither constructed nor closed. The authorization parameters message store is the exception—it isn't wrapped by the container, and the host is responsible for closing it.

Extension points ​

MethodPurposeWhen not set
SetProfileProvider(func() services.ProfileService)Provides user profile data: claims in tokens and userinfo (GetProfileData), and whether the user is still active (IsActive). Called on every resolution; returning nil uses the default implementationThe default implementation adds no claims at all, and IsActive is always true. You must inject one if you need user claims such as name and email
SetResourceOwnerValidator(validators.ResourceOwnerPasswordValidator)Enables the password grant and validates username and passwordAlways rejects (NotSupportedResourceOwnerPasswordValidator), and the discovery document doesn't advertise password
SetBackchannelAuthenticationUserValidator(validators.BackchannelAuthenticationUserValidator)Locates the user in a CIBA request from login_hint and the likeThe default implementation is for development and integration testing only and doesn't parse or verify user hints—in production you must inject your own implementation
SetAuthenticationHandlerProvider(scheme, func(godi.Provider) auth.Handler)Provides a handler factory for an authentication scheme name, overriding the built-in registrationUses the built-in handler; see Identity integration overview
SetExternalFailurePath(string)Redirect path when external login failsEmpty string (no redirect)
SetBackChannelLogoutHttpClient(*http.Client)HTTP client used for backchannel logout notificationsnil
SetBackchannelAuthenticationNotificationHttpClient(*http.Client)HTTP client used for CIBA notificationshttp.DefaultClient (no timeout)

Backchannel logout notifications aren't sent in v0.1.4

BackchannelLogoutService.SendLogoutNotificationsAsync, which is responsible for sending notifications, is currently a no-op that returns nil directly, so SetBackChannelLogoutHttpClient has no observable effect for now—even though the discovery document declares backchannel_logout_supported: true. RPs that depend on backchannel logout need to handle it some other way; see Sessions and logout.

The CIBA notification client defaults to http.DefaultClient, which has no timeout; inject an *http.Client with a timeout set.

Lifecycle ​

MethodDescription
AllowInMemoryFallback()Declares that "stores that aren't injected may fall back to in-memory implementations". For local development and testing only
Freeze()Marks wiring as complete. If AllowInMemoryFallback() hasn't been called, checks each of the 11 storage seams in the table above, and panics if any isn't injected
Frozen() boolWhether Freeze() has been called

Observed panic message when AllowInMemoryFallback() isn't called:

text
panic: store seam "authorization parameters message store" not injected by host and in-memory fallback not declared

A few notes:

  • Production wiring should not call AllowInMemoryFallback(), so missing injections surface at startup. In a multi-replica deployment, any store left in process memory causes cross-node requests to fail at random.
  • The frozen check is also performed again when each store is first used; but if Freeze() was never called, that check doesn't fire, and stores that weren't injected silently fall back to memory. So always call Freeze().
  • Freeze() doesn't lock the Set* methods—calling them afterwards doesn't raise an error, but once a storage seam has been used it isn't read again. Do all injection before Freeze() and before you start serving.

Released under the Apache License 2.0 · Documentation © 2026 Wicket authors