# How HTTP Proxy Configuration Works for Server-Side Model Requests in pi-web

> Discover how to configure HTTP proxy for server-side model requests in agegr/pi-web. Learn about Edge middleware hostname validation and authentication for Next.js API routes.

- Repository: [Alex Yang/pi-web](https://github.com/agegr/pi-web)
- Tags: how-to-guide
- Published: 2026-07-31

---

**The `agegr/pi-web` application uses an Edge middleware in [`proxy.ts`](https://github.com/agegr/pi-web/blob/main/proxy.ts) to intercept all server-side model requests, validating hostnames against a whitelist and optionally enforcing basic authentication before allowing access to Next.js API routes.**

The HTTP proxy configuration in `pi-web` acts as a security gate for every model API call. Because all model processing occurs server-side through Next.js API routes, the middleware ensures that only requests from trusted origins can reach these endpoints. This architecture prevents DNS rebinding attacks, unauthorized cross-origin requests, and unwanted third-party access to potentially sensitive model endpoints.

## How the Proxy Layer Intercepts Model Requests

All incoming traffic passes through the lightweight Edge middleware defined in **[`proxy.ts`](https://github.com/agegr/pi-web/blob/main/proxy.ts)**. The middleware distinguishes API calls (`/api` or `/api/*`) from standard page requests using route matchers configured in **[`next.config.ts`](https://github.com/agegr/pi-web/blob/main/next.config.ts)**. The configuration exports a matcher pattern of `["/", "/api/:path*"]`, ensuring comprehensive coverage of both the root path and all API sub-routes.

When a request arrives, the middleware performs a sequential validation protocol. If any check fails, the middleware returns an immediate HTTP error response—either **403 Forbidden** or **401 Unauthorized**—preventing the request from reaching the underlying model execution logic in `app/api/models/*`.

## Request Validation Flow

The validation logic follows three distinct stages designed to verify origin trust and optionally enforce credentials.

### Host Whitelist Validation

For every API request, the middleware invokes `isApiRequestAllowed` from **[`lib/request-security.ts`](https://github.com/agegr/pi-web/blob/main/lib/request-security.ts)**. This function extracts the `Host` header and validates it against a whitelist constructed by `configuredHostnamesFromEnvironment`. The whitelist aggregates values from two environment variables:

- **`PI_WEB_HOSTNAME`** – The primary hostname the server accepts.
- **`PI_WEB_ALLOWED_HOSTS`** – A comma-separated list of additional approved hostnames or IP addresses.

The validation automatically permits loopback addresses and IP literals. If the `Host` header does not match the whitelist, `isApiRequestHostAllowed` returns false, triggering an immediate **403 Forbidden** response from the middleware.

### Basic Authentication Protection

When the environment variable `PI_WEB_PASSWORD` is set, the middleware activates an additional security layer. It calls `isValidBasicAuthorization` from **[`lib/web-auth.ts`](https://github.com/agegr/pi-web/blob/main/lib/web-auth.ts)** to parse and verify the request's `Authorization` header.

If the header is missing or contains invalid credentials, the middleware returns a **401 Unauthorized** response that includes the `WWW-Authenticate` header required for browser authentication prompts. The `isWebPasswordEnabled` helper determines whether this protection is active based on the presence of the password variable.

## Configuring the Proxy via Environment Variables

The HTTP proxy behavior is entirely runtime-configurable through environment variables. Adjusting these values changes the proxy’s acceptance rules without requiring code changes or redeployment.

| Variable | Purpose | Example |
|----------|---------|---------|
| `PI_WEB_HOSTNAME` | Primary hostname that the server will accept. | `my-pi.local` |
| `PI_WEB_ALLOWED_HOSTS` | Comma-separated list of additional allowed hostnames or IPs. | `192.168.1.10,backup.local` |
| `PI_WEB_PASSWORD` | Enables basic-auth protection when defined. | `secure-pass-123` |

```bash

# Example environment configuration

export PI_WEB_HOSTNAME=my-pi.local
export PI_WEB_ALLOWED_HOSTS=192.168.1.10,10.0.0.5
export PI_WEB_PASSWORD=complex-secret-key

```

These variables are read dynamically by [`request-security.ts`](https://github.com/agegr/pi-web/blob/main/request-security.ts) and [`web-auth.ts`](https://github.com/agegr/pi-web/blob/main/web-auth.ts), ensuring that changes take effect immediately on the next request.

## Implementation Files and Their Roles

The proxy architecture spans several key files that handle distinct responsibilities:

- **[`proxy.ts`](https://github.com/agegr/pi-web/blob/main/proxy.ts)** – The Edge middleware entry point that orchestrates host validation and authentication checks before calling `NextResponse.next()` to forward requests.
- **[`lib/request-security.ts`](https://github.com/agegr/pi-web/blob/main/lib/request-security.ts)** – Implements `isApiRequestAllowed`, `isApiRequestHostAllowed`, and `configuredHostnamesFromEnvironment` for hostname whitelist logic.
- **[`lib/web-auth.ts`](https://github.com/agegr/pi-web/blob/main/lib/web-auth.ts)** – Provides `isWebPasswordEnabled` and `isValidBasicAuthorization` for optional basic authentication.
- **[`next.config.ts`](https://github.com/agegr/pi-web/blob/main/next.config.ts)** – Registers the middleware configuration with the matcher pattern `["/", "/api/:path*"]`.
- **[`lib/model-discovery.ts`](https://github.com/agegr/pi-web/blob/main/lib/model-discovery.ts)** – Handles the actual server-side model fetches, but only receives traffic that has successfully passed through the proxy validation layer.

## Summary

- The **HTTP proxy configuration** in `agegr/pi-web` uses Edge middleware in [`proxy.ts`](https://github.com/agegr/pi-web/blob/main/proxy.ts) to gate all server-side model requests before they reach API routes.
- **Host validation** is performed by `isApiRequestAllowed` in [`lib/request-security.ts`](https://github.com/agegr/pi-web/blob/main/lib/request-security.ts) against `PI_WEB_HOSTNAME` and `PI_WEB_ALLOWED_HOSTS`.
- **Basic authentication** is optional and enforced by `isValidBasicAuthorization` in [`lib/web-auth.ts`](https://github.com/agegr/pi-web/blob/main/lib/web-auth.ts) when `PI_WEB_PASSWORD` is configured.
- Failed validation returns **403 Forbidden** (invalid host) or **401 Unauthorized** (invalid credentials) immediately at the Edge layer.
- Configuration is runtime-adjustable via environment variables without code deployment, providing flexible security policies for different network environments.

## Frequently Asked Questions

### How do I allow multiple hostnames to access the pi-web API?

Set the `PI_WEB_ALLOWED_HOSTS` environment variable to a comma-separated list of approved hostnames or IP addresses. The `configuredHostnamesFromEnvironment` function in [`lib/request-security.ts`](https://github.com/agegr/pi-web/blob/main/lib/request-security.ts) parses this variable alongside `PI_WEB_HOSTNAME` to build the validation whitelist. Loopback addresses and IP literals are automatically permitted regardless of configuration.

### What happens if I don't set a password via `PI_WEB_PASSWORD`?

When `PI_WEB_PASSWORD` is undefined, the `isWebPasswordEnabled` function returns false, and the middleware skips basic authentication checks entirely. Requests only need to pass hostname validation to reach model endpoints. While this simplifies local development deployments, production instances should configure this variable to prevent unauthorized API access.

### Why am I receiving a 403 Forbidden error on API requests?

A 403 response indicates that the `Host` header in your HTTP request failed the whitelist check performed by `isApiRequestHostAllowed`. Verify that your request's hostname matches the value set in `PI_WEB_HOSTNAME` or appears in the `PI_WEB_ALLOWED_HOSTS` list. The middleware performs this validation in [`proxy.ts`](https://github.com/agegr/pi-web/blob/main/proxy.ts) before any authentication checks, ensuring that only explicitly trusted origins can attempt API access.

### Where does the actual model processing occur after proxy validation?

Once [`proxy.ts`](https://github.com/agegr/pi-web/blob/main/proxy.ts) returns `NextResponse.next()`, the request proceeds to the Next.js API routes under `app/api/models/*`. The [`lib/model-discovery.ts`](https://github.com/agegr/pi-web/blob/main/lib/model-discovery.ts) module then handles the server-side model fetching logic. This architecture ensures that [`lib/model-discovery.ts`](https://github.com/agegr/pi-web/blob/main/lib/model-discovery.ts) never processes requests from untrusted origins or unauthenticated clients, as the Edge middleware filters them out at the network edge.