Skip to main content

Authentication and gateway

Authentication in Uxopian AI is handled entirely by uxopian-gateway. The backend (uxopian-ai) does not perform authentication itself. It receives identity information through HTTP headers that the gateway injects after a successful authentication check.

Authentication flow

Figure: Authentication flow from browser through gateway to uxopian-ai.

The AuthProvider interface

The gateway authenticates every request by calling an AuthProvider. An AuthProvider inspects the request and returns an AuthenticatedUser carrying userId, roles, tenantId, and the original token. If authentication fails, the request is rejected at the gateway.

Three built-in providers are included:

ProviderWhen to use
DevProviderLocal development only. Reads identity from X-User-Id, X-User-Roles, X-User-TenantId request headers with no validation.
FlowerDocsProviderFlowerDocs deployments. Validates FlowerDocs JWTs from Authorization: Bearer or SESSION cookie. Caches sessions in Hazelcast.
Fast2ProviderFast2 deployments. Validates Fast2 JWT tokens from Authorization: Bearer.

The active provider is set per route in gateway-application.yaml:

app:
routes:
- id: uxopian-ai
uri: http://uxopian-ai:8080
path: /**
provider: DevProvider

Identity headers

After authentication, the gateway forwards four headers to uxopian-ai:

HeaderContent
X-User-IdUnique user identifier
X-User-TenantIdTenant identifier — drives all data isolation
X-User-RolesComma-separated list of user roles
X-User-TokenOriginal credential token (forwarded for integrations that call back into the source system)

AuthFilter in uxopian-ai

AuthFilter (OncePerRequestFilter) reads these headers on every incoming request. It builds an AuthenticatedUser and opens an AiResourceContext scope using AiContext.builder().withUser(authUser).open(). All downstream services read tenant identity from AiContext rather than receiving it as parameters.

If X-User-TenantId is absent and the dev profile is not active, the request proceeds without a security context. Operations that require tenant data will fail because no tenant is resolvable.

Dev profile

When SPRING_PROFILES_ACTIVE=dev is set on uxopian-ai, AuthFilter injects fallback defaults when headers are missing:

  • userId defaults to User-development
  • tenantId defaults to Tenant-development

This means any request reaches the backend without authentication. Never use the dev profile in a production or publicly accessible environment.

In the Docker Compose quickstart, the gateway uses DevProvider, which reads identity from request headers. Combined with the dev profile on uxopian-ai, this allows browser testing without any credentials.

Public routes

Some paths bypass authentication in the gateway. The default gateway configuration marks the following as public:

  • /assets/**: static web component bundles
  • /actuator/health: health check endpoint
  • /v3/** and /swagger-ui/**: API documentation
  • /ws/**: WebSocket endpoint for streaming

Admin API routes (/api/v1/admin/**) can be restricted by role using the roles field in the gateway security configuration.

Custom auth providers

A custom AuthProvider can be implemented in the gateway by writing a Spring bean that implements the AuthProvider interface (returns Mono<AuthenticatedUser>). The gateway configuration references the provider by its Spring bean name.