apiserver

import "github.com/infrapi/kayra/internal/apiserver"

The one thin wiring/transport layer that imports every other package and builds the single gin engine kayra serve runs — so main only has to call Build once.

engine, err := apiserver.Build(appCfg, cfg)
// appCfg: *libconfig.AppConfig (infrapi/lib's INFRAPI_APP_* config)
// cfg:    *config.Config        (Kayra's own YAML config)

In order:

  1. gin.EnableJsonDecoderDisallowUnknownFields() — posting a Role-shaped body to a Group endpoint (or any mismatched resource) fails loudly instead of silently dropping fields it doesn’t have.
  2. Opens the store from cfg.ActiveDatabase().
  3. Builds the oidc.Manager, one authz.Cached per authorizations.<name>, and the PAT keypair.
  4. Builds middleware.Authenticator and middleware.SysadminGate (wrapping that same Authenticator, plus cfg.Sysadmin.Groups — falling back to middleware.SysadminGroupFor(appCfg.AppPlatform) when left empty).
  5. Mounts, via infrapi/lib’s pkg/server: the discovery/metrics/docs endpoints, oidc’s own routes, GET/POST /oauth2/userinfo (both, per OIDC Core §5.3.1: GET MUST be supported, POST MAY be — most real providers accept either), oauth2broker’s three routes (kayra-cli login’s own browser relay), then rbac’s cluster and namespace routes, the catalog’s cluster/namespace/namespace-collection routes, and tokenapi’s route.

catalog.Reconciler deliberately does not run here: it’s its own kayra reconciler process (see the CLI reference), not a goroutine mixed into the API server.