Skip to main content

Middleware Pipeline

AuthProxy processes every incoming request through an ordered middleware pipeline. Each middleware handles a specific concern, and the order is critical — requests flow top-to-bottom, responses flow bottom-to-top.

Pipeline Order

Client Request


┌─────────────────────────────┐
│ 1. ApiPathMiddleware │ Route determination & path parsing
├─────────────────────────────┤
│ 2. CorsMiddleware │ Cross-origin request handling
├─────────────────────────────┤
│ 3. ResponseCaching │ HTTP response cache
├─────────────────────────────┤
│ 4. FileCacheMiddleware │ Static file serving (in-memory)
├─────────────────────────────┤
│ 5. ReversProxyMiddleware │ Proxy to backend services
├─────────────────────────────┤
│ 6. MapControllers │ AuthProxy API endpoints
├─────────────────────────────┤
│ 7. MapRazorPages │ Admin panel pages
└─────────────────────────────┘
Implementation detail

Source-level examples and database statements are maintained in the module repositories. This public page describes the operational contract and configuration intent.

Middleware Details

1. ApiPathMiddleware

Purpose: Parses the incoming request path and matches it against the route_map database table.

What it does:

  • Extracts the API path prefix from the URL
  • Looks up matching route in the route_map table
  • Sets route metadata (target service URL, required scopes, flags) on the request context
  • Determines whether the request needs authentication

Short-circuits: No — always passes to next middleware.

2. CorsMiddleware

Purpose: Handles Cross-Origin Resource Sharing (CORS) headers for browser requests.

What it does:

  • Responds to OPTIONS preflight requests with appropriate CORS headers.
  • Adds Access-Control-Allow-Origin, Vary: Origin, Access-Control-Allow-Credentials: true, Access-Control-Allow-Methods: GET, HEAD, POST, OPTIONS and Access-Control-Allow-Headers: Content-Type, X-Device-Guid, X-WalletId on cross-app responses.
  • Enforces the dual-flag CORS gate introduced in 2026-04: the calling user_app must have AppFlag.AppAuthAndCORS set and the matching route_map row must have RouteFlags.AppAuthAndCORS set. If either side is missing, the preflight returns 403.
  • The reflected origin is verified against the calling user_app's registered domain list, not against FIDO2.origins (those are independent allowlists).

Short-circuits: Yes — responds directly to OPTIONS preflight requests.

3. ResponseCaching

Purpose: Standard ASP.NET Core response caching middleware.

What it does:

  • Caches HTTP responses based on Cache-Control headers
  • Serves cached responses for matching subsequent requests
  • Respects Vary headers for cache key differentiation

Short-circuits: Yes — serves cached response when available.

4. FileCacheMiddleware

Purpose: Serves static files (PWA frontends, assets) from an in-memory cache with compression.

What it does:

  • Maintains an in-memory cache of static files from wwwroot/ (full load at startup)
  • Incrementally syncs changed wwwroot files every ~100s via LoadSettingsStaticFileCacheService.SyncChangedFiles() (mtime + size index; does not block request serving)
  • Serves pre-compressed files (Brotli/Gzip) based on Accept-Encoding (Production only)
  • Generates and validates ETag headers for browser caching
  • Sets appropriate Cache-Control headers by file type:
    • Hashed assets (*.js, *.css with hash): max-age=31536000 (1 year)
    • HTML files: no-cache (always revalidate)
    • Images/fonts: max-age=86400 (1 day)
  • Routes SPA navigation requests to index.html (PWA fallback)

Short-circuits: Yes — serves files directly without reaching controllers.

5. ReversProxyMiddleware

Purpose: Forwards authenticated requests to backend services based on route map configuration.

What it does:

  • Checks if the route requires authentication (session validation)
  • Validates user scopes against route requirements
  • Enforces HTTPS in production environments
  • Forwards only selected incoming headers:
    • X-Device-Guid — device-bound flows such as anonymous chat and capability mode
    • X-WalletId — wallet context for multi-wallet TrexWallet flows
    • X-Signature — second-factor signature (validated by AuthProxy, replaced with X-SignResult: valid for backend)
    • Browser cookies are not forwarded; backend modules cannot rely on .AspNetCore.Antiforgery.* or any other client cookie. CSRF in admin pages is provided by SameSite session cookie + route-level RouteFlags.ScopeCheck, not by ASP.NET antiforgery tokens.
  • Injects trusted internal headers after AuthProxy checks:
    • X-Project — project identifier
    • X-Crm — user's CRM ID
    • X-KeyType — authentication method used (LoginMethod)
    • X-Scopes — user's access scopes
    • X-AppId / X-MCP-App-Id — validated application context
    • X-Pkey-Crm — CRM ID resolved from public key auth
    • X-Country — GeoIP country code when GeoEnrich is enabled
    • X-SignResult — successful signature verification marker
  • Handles private API routes (IP whitelist + API key validation)
  • Manages rate limiting per session, connection, and API key

Short-circuits: Yes — proxied requests are handled here and don't reach controllers.

6. MapControllers

Purpose: Handles requests to AuthProxy's own API endpoints.

Endpoints served:

  • /auth/v1/* — authentication, keys, identity, files
  • /private/v1/* — internal service API
  • /mcp — Machine Context Protocol (JSON-RPC 2.0)

7. MapRazorPages

Purpose: Serves the admin panel UI.

Pages served:

  • /ProxyAdmin/* — admin dashboard, user management, route configuration, settings

Request Flow Examples

Static file request (PWA)

GET /index.html
→ ApiPathMiddleware (no route match)
→ CorsMiddleware (add headers)
→ ResponseCaching (cache miss)
→ FileCacheMiddleware (serve from memory cache) ✓ SHORT-CIRCUIT

Authenticated API request (proxied to Core)

POST /api/v1/users
→ ApiPathMiddleware (match route_map → core service)
→ CorsMiddleware (add headers)
→ ResponseCaching (skip — POST)
→ FileCacheMiddleware (skip — not a file)
→ ReversProxyMiddleware:
→ Validate session cookie
→ Check user scopes vs route requirements
→ Forward to http://core:80/api/v1/users with X-Crm header ✓ SHORT-CIRCUIT

AuthProxy own API request

POST /auth/v1/login
→ ApiPathMiddleware (internal route)
→ CorsMiddleware (add headers)
→ ResponseCaching (skip — POST)
→ FileCacheMiddleware (skip — not a file)
→ ReversProxyMiddleware (skip — internal route)
→ MapControllers → AuthController.login() ✓

Admin panel request

GET /ProxyAdmin/Users
→ ApiPathMiddleware (no API route)
→ CorsMiddleware (skip — same origin)
→ ResponseCaching (cache miss)
→ FileCacheMiddleware (skip — not in wwwroot)
→ ReversProxyMiddleware (skip — no route)
→ MapControllers (skip — no controller match)
→ MapRazorPages → Users.cshtml ✓

Performance Considerations

  • FileCacheMiddleware keeps all static files in memory — this provides sub-millisecond response times but increases RAM usage proportionally to wwwroot/ size
  • ReversProxyMiddleware performs a database lookup for routes on first access, then caches route mappings.
  • Rate limiting uses in-memory fixed-window counters with RateLimitWindowSeconds configurable per scope (per-session, per-IP, per-app, per-route). See Rate Limiting for the full scope table.
  • The pipeline order ensures that static files are served before reaching the heavier proxy logic

Customization

The middleware pipeline order is fixed and should not be modified. To customize behavior:

  • Add routes: Use the admin panel or route_map table to configure proxy destinations
  • Configure CORS: CORS rules are derived from the route and domain configuration
  • Static files: Add files to wwwroot/ to have them served by FileCacheMiddleware
  • Rate limits: Configure via the settings table or admin panel