Documentation
¶
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func NewRouter ¶
func NewRouter(services interfaces.Services, logger *apilogger.Logger, proxyHandler *handlers.ProxyHandler, config ...RouterConfig) *gin.Engine
NewRouter creates a new Gin router with all routes configured. proxyHandler may be nil — proxy routes are not registered in that case.
Types ¶
type RouterConfig ¶
type RouterConfig struct {
// Debug enables debug mode
Debug bool
// TrustedProxies is the list of trusted proxy IP ranges/CIDRs.
// If nil, trusts nobody (X-Forwarded-For is ignored). This
// prevents IP-spoofing attacks on lockout and rate-limiting (#757).
TrustedProxies []string
// LoggingConfig is the configuration for the logging middleware
LoggingConfig middleware.LoggingConfig
// RateLimitConfig is the configuration for the rate limiting middleware
RateLimitConfig middleware.RateLimitConfig
// PerRouteRateLimitConfig is the configuration for stricter per-route
// rate limits applied on top of the global RateLimitConfig. Covers
// G41 (/secrets/:id/reveal) — endpoints
// that take credentials as direct input and therefore warrant a
// tighter cap than the global 100/min/IP. Defaults to enabled with
// sensible limits; operators can disable by setting Enabled=false.
PerRouteRateLimitConfig middleware.PerRouteRateLimitConfig
// SecurityConfig is the configuration for the security middleware
SecurityConfig middleware.SecurityConfig
// TracingConfig is the configuration for the tracing middleware
TracingConfig middleware.TracingConfig
// SettingsHandler is the optional settings handler for admin/user settings routes
SettingsHandler *handlers.SettingsHandler
// InstanceSettings provides access to instance settings for feature flags
InstanceSettings *settings.InstanceService
// SecretsHandler is the handler for secret management endpoints (optional)
SecretsHandler *handlers.SecretsHandler
// ModelsHandler handles model listing and selection (optional).
// Extracted from SecretsHandler (US-29.5).
ModelsHandler *handlers.ModelsHandler
// WorkspaceEnvHandler is the handler for workspace env-var endpoints (optional).
// Extracted from SecretsHandler (US-29.4).
WorkspaceEnvHandler *handlers.WorkspaceEnvHandler
// AdminProviderCredentialsHandler handles admin credential CRUD (optional)
AdminProviderCredentialsHandler *handlers.AdminProviderCredentialsHandler
// UserProviderCredentialsHandler handles user credential CRUD (optional)
UserProviderCredentialsHandler *handlers.UserProviderCredentialsHandler
// ImageFactoryHandler serves the consumer-facing image-factory endpoints
// (catalog, configs). Optional; nil when image-factory is disabled.
ImageFactoryHandler *handlers.ImageFactoryHandler
// ImageFactoryAdminHandler serves the platform-owner admin endpoints.
ImageFactoryAdminHandler *handlers.ImageFactoryAdminHandler
// UnlockDEKHandler is the soft-unlock endpoint for re-deriving the
// DEK without forcing logout (Epic 56). Optional — when nil the
// /auth/unlock-dek route is not registered, which is appropriate
// for tests that don't exercise key material.
UnlockDEKHandler *handlers.UnlockDEKHandler
// OrgsHandler handles org CRUD routes (optional)
OrgsHandler *handlers.OrgsHandler
// OrgCredentialsHandler handles org credential routes (optional)
OrgCredentialsHandler *handlers.OrgCredentialsHandler
// TerminalHandler is the handler for WebSocket terminal proxy (optional)
TerminalHandler *handlers.TerminalHandler
// DevPreviewHandler is the handler for the authenticated HTTP/WS tunnel
// to in-workspace dev servers (Epic 66, optional). nil when disabled.
DevPreviewHandler *handlers.DevPreviewHandler
// PreviewOriginHandler serves <uuid>-preview.<baseDomain> hosts
// (Epic 66 Phase 1, optional). nil when preview origins are disabled —
// in that case NO engine middleware is registered and the API behaves
// exactly as before. When non-nil, its middleware runs BEFORE the API
// middleware chain: preview hosts bypass API CORS/rate policy and can
// never match /api/* routes (T5).
PreviewOriginHandler *handlers.PreviewOriginHandler
// AgentReloadHandler handles POST /api/v1/workspaces/:id/agent/reload (optional)
AgentReloadHandler *handlers.AgentReloadHandler
// DiskRecoverHandler handles POST /api/v1/workspaces/:id/disk-recover
// (#1601 mechanical disk recovery; optional wiring like reload).
DiskRecoverHandler *handlers.DiskRecoverHandler
// BulkReloadHandler handles POST /api/v1/users/me/agents/reload (optional)
BulkReloadHandler *handlers.BulkReloadHandler
UsageHandler *handlers.UsageHandler
WebhookHandler *handlers.StripeWebhookHandler
InvitationsHandler *handlers.InvitationsHandler
EmailHandler *handlers.EmailHandler
EmailVerifyHandler *handlers.EmailVerifyHandler
PasswordResetHandler *handlers.PasswordResetHandler
PolicyHandler *handlers.PolicyHandler
PromptHandler *handlers.PromptHandler
AgentRoleHandler *handlers.AgentRoleHandler
AuditHandler *handlers.AuditHandler
// RelayAdminHandler handles relay admin setup + status endpoints (optional)
RelayAdminHandler *handlers.RelayAdminHandler
// PlatformInfoHandler serves the admin "Versions" display — running
// component versions read from deployed Deployment image tags. Optional.
PlatformInfoHandler *handlers.PlatformInfoHandler
// AuthorityFlipHandler serves the flip gate's operator endpoints
// (US-69.13): park/unpark with mode_transition + the ledger in-flight
// drain signal (optional).
AuthorityFlipHandler *handlers.AuthorityFlipHandler
// AdminSessionHandler handles admin-only session recovery endpoints (optional).
// US-44.11: force-abort a workspace session stuck in activeSess after the
// workspace pod was deleted/unreachable.
AdminSessionHandler *handlers.AdminSessionHandler
// PlatformAdminHandler handles platform-admin org/user suspension
// endpoints (US-43.19, D19/D20). Mounted behind AuthMiddleware + AdminGuard.
PlatformAdminHandler *handlers.PlatformAdminHandler
// InternalOrgStatusHandler, when non-nil, registers the cluster-internal
// GET /api/v1/internal/orgs/:orgID/status endpoint that the controller
// polls to drive org-suspension of workspaces (D20). It is intentionally
// NOT behind AuthMiddleware; access is gated by a mandatory X-Internal-Token
// shared-secret header (see InternalOrgStatusHandler — the endpoint FAILS
// CLOSED with 403 when LLMSAFESPACES_INTERNAL_TOKEN is unset). An optional
// API NetworkPolicy (chart value networkPolicy.apiIngressRestricted) adds
// L3/L4 defense-in-depth; the token is the load-bearing control.
InternalOrgStatusHandler *handlers.InternalOrgStatusHandler
// InternalLLMProvidersHandler, when non-nil, registers the
// cluster-internal GET
// /api/v1/internal/workspaces/:workspaceID/llm-providers endpoint the
// controller's relay staging polls (US-72.3, design 0058 §4.1 hop 1) to
// obtain decrypted BYO provider credentials for sealing. Same auth
// contract as InternalOrgStatusHandler (mandatory X-Internal-Token,
// fail-closed 403 when unset) — but it returns credential material, so
// it MUST never be ingress-exposed; every reveal is audited
// server-side.
InternalLLMProvidersHandler *handlers.InternalLLMProvidersHandler
// PodBootstrapHandler, when non-nil, registers POST /internal/v1/pod-bootstrap
// — the secretless credential injection endpoint (Epic 35). The workspace
// init container presents a projected SA token; the handler validates it via
// TokenReview and returns decrypted secrets. NOT behind AuthMiddleware (the
// init container has no user identity); auth is the TokenReview itself.
PodBootstrapHandler *handlers.PodBootstrapHandler
// PodWorkspaceRenameHandler, when non-nil, registers
// /internal/v1/workspace-rename — the pod-identity path the agentd
// rename_workspace MCP tool calls. Same TokenReview auth contract as
// PodBootstrapHandler: the SA must be workspace-<id> in the expected
// namespace, so a pod can only rename its own workspace.
PodWorkspaceRenameHandler *handlers.PodWorkspaceRenameHandler
// PodAutomationHandler, when non-nil, registers the pod-identity
// trigger + workflow CRUD surface the agentd automation MCP tools
// call — TokenReview-gated like the rename endpoint, delegating to
// the existing user handlers under the pod's resolved owner.
PodAutomationHandler *handlers.PodAutomationHandler
// PodSessionArchiveHandler, when non-nil, registers the pod-identity
// session archive/delete surface the agentd #1627 MCP tools call —
// TokenReview-gated like the rename endpoint.
PodSessionArchiveHandler *handlers.PodSessionArchiveHandler
// MCPServersHandler handles external MCP server CRUD for all three
// scopes (platform/org/user). Optional — when nil, no MCP routes are
// registered (Epic 53).
AdminMCPServersHandler *handlers.MCPServersHandler
OrgMCPServersHandler *handlers.MCPServersHandler
UserMCPServersHandler *handlers.MCPServersHandler
UserPromptsHandler *handlers.UserPromptsHandler
CookieName string
// CookieDomain (Epic 54, US-54.3): when non-empty, set as the Domain
// attribute on the lsp_session cookie so the session survives root→subdomain
// redirects under wildcard subdomain routing. When empty (default), the
// cookie is host-only — current behavior, single-host deploys.
CookieDomain string
// OrgSubdomainBaseDomain (design 0064, #1669): auth.orgSubdomainRouting.
// baseDomain. When non-empty, GET /auth/config derives an optional
// orgContext {slug, name} from a <slug>.<base> request Host for
// SSO-configured orgs — display-only, fail-soft (omitted on every miss).
OrgSubdomainBaseDomain string
// SSOHandler handles org-admin SSO config CRUD + the public OIDC login flow
// (start/callback) and claimed-domain discovery (US-43.10, D17).
SSOHandler *handlers.SSOHandler
// LoginDiscoveryHandler handles POST /api/v1/auth/lookup — the email-led
// login discovery endpoint (Epic 54, US-54.1). Returns a single redirectUrl
// pointing the browser at the user's org subdomain (or direct SSO start URL
// when subdomain routing is disabled). Enumeration-safe: uniform 200 +
// uniform body shape across all non-validation branches; DB errors masked.
LoginDiscoveryHandler *handlers.LoginDiscoveryHandler
// PasskeyHandler handles WebAuthn passkey registration + login ceremonies
// (Epic 59). Public routes (no auth middleware) — the ceremony itself is
// the authentication. Nil when passkey support is not configured (no RPID).
PasskeyHandler *handlers.PasskeyHandler
// PasskeyDefaultSignup, when true, tells the frontend to default to passkey
// enrollment at registration with "use password" as the explicit opt-in.
PasskeyDefaultSignup bool
// Turnstile, when Enabled is true, gates POST /auth/register with a
// Cloudflare Turnstile CAPTCHA middleware. The middleware fails
// closed: any of {missing token, verify request fails, verify
// response says not-success} → 401. When Enabled is false, the
// route runs without the middleware.
//
// SecretKey must be non-empty when Enabled is true (config.Load
// enforces this at startup, fail-closed). VerifyURL defaults to
// Cloudflare's production siteverify endpoint if empty.
Turnstile TurnstileRouterConfig
// Epic 64: Workflow + trigger handlers (optional — nil when not wired).
UserWorkflowsHandler *handlers.WorkflowsHandler
OrgWorkflowsHandler *handlers.WorkflowsHandler
UserTriggersHandler *handlers.TriggersHandler
OrgTriggersHandler *handlers.TriggersHandler
WebhookReceiverHandler *handlers.WebhookReceiverHandler
// FaultInjectionRules, when non-empty, installs the deterministic
// fault-injection middleware (Epic 70 US-70.0). Populated at app
// wire-up from LLMSAFESPACES_FAULT_INJECTION — a malformed value fails
// startup there. Empty means the feature is absent: no middleware is
// registered and the chain is byte-identical to before.
FaultInjectionRules []middleware.FaultInjectionRule
}
RouterConfig defines configuration for the router
func DefaultRouterConfig ¶
func DefaultRouterConfig() RouterConfig
DefaultRouterConfig returns the default router configuration
type TurnstileRouterConfig ¶ added in v0.2.0
TurnstileRouterConfig is the routing-side view of Cloudflare Turnstile CAPTCHA configuration used by the /register handler. Only the three fields the router needs at wire-up time; registerAuthRoutes constructs the fuller middleware.TurnstileConfig from this by dropping in a production HTTP client and logger.
This is kept separate from middleware.TurnstileConfig (rather than re-using that type here) because middleware.TurnstileConfig contains an *http.Client field that's only meaningful for tests. Exposing that on RouterConfig — and therefore on every app.go call site that builds a router — would invite confusion about whether operators are meant to plug an httptrace-instrumented client, a custom timeout, etc. The separation costs us one mapping step (app.go:911-914); the alternative would cost us a "please just leave this nil unless you're writing a test" caveat at every call site.
When Enabled is true, SecretKey must be non-empty (config.Load enforces this at startup, fail-closed). VerifyURL defaults to Cloudflare's production siteverify endpoint if empty.