Add bearer token API authentication

- Auto-generate random 32-char bearer token on first startup, stored in
  secrets.yaml as api.bearerToken
- BearerAuthMiddleware checks Authorization: Bearer <token> on all /api/
  endpoints except /health, /health/reconcile, /events (SSE), and non-API
  paths (frontend static files)
- Development mode (WILD_CENTRAL_ENV=development) skips auth entirely
- Web app ApiClient: add setToken/clearToken/hasToken methods, persist
  token in localStorage, automatically include Authorization header on
  all API requests
- Token can be found in secrets.yaml for CLI/automation use
This commit is contained in:
2026-07-14 12:45:22 +00:00
parent 60f3ca4a3a
commit f5a030fd44
4 changed files with 88 additions and 5 deletions

View File

@@ -256,10 +256,16 @@ func (api *API) StartConvergenceLoop(ctx gocontext.Context, interval time.Durati
slog.Info("convergence loop started", "component", "reconcile", "interval", interval)
}
func (api *API) RegisterRoutes(r *mux.Router) {
func (api *API) RegisterRoutes(r *mux.Router, bearerToken string, devMode bool) {
r.Use(RequestLoggingMiddleware)
// Health
// Bearer token authentication — protects all /api/ routes.
// Dev mode skips auth for ease of development.
if !devMode && bearerToken != "" {
r.Use(BearerAuthMiddleware(bearerToken))
}
// Health (accessible even with auth — middleware exempts /health)
r.HandleFunc("/api/v1/health/reconcile", api.ReconcileHealth).Methods("GET")
// Resource-oriented settings (persisted in state.yaml)