WebProxy Server is a distributed cache engine for organizational systems. It authenticates users against your own authentication service, groups them into clusters, and relays resource requests and responses only within the matching cluster.
The runtime is intentionally small:
- The frontend WebProxy client opens the websocket endpoint.
- The client sends an authentication token with
/s <token>. - The server calls your authentication service using
AUTHENTICATION_URL. - If the token is valid, the user is cached and added to a cluster, based on the user's organization and network.
- Resource requests are broadcast only to peers in the same cluster.
- Responses are routed back to the requesting user.
All configuration is read from environment variables, centralized in src/webproxy_server/environment.gleam.
| Variable | Required | Default | Description |
|---|---|---|---|
AUTHENTICATION_URL |
Yes | — | Full HTTPS URL of your authentication endpoint. Must start with https://. The server refuses to start without a valid value. See Authentication Service. |
PORT |
No | 8080 |
TCP port the server binds to. Falls back to 8080 when unset or invalid. |
AUTHORIZED_ADMINISTRATOR_IPS |
No | [] |
JSON array of IP addresses allowed to use the /upgrade intervention command. See Administrator IPs. |
USE_NATIVE_CONNECTION_IP |
No | false |
When false (the default, for deployments behind a reverse proxy), the client IP is read from the X-Forwarded-For header, falling back to X-Real-IP. When true, or when neither header is present, the transport-level connection IP is used. Accepts true/1 for true; any other value is false. See Client IP Resolution. |
The server identifies each connecting client by IP, which feeds authorization and the Administrator IPs gate. Because the server usually sits behind a reverse proxy, by default it trusts the X-Forwarded-For header (falling back to X-Real-IP) rather than the raw socket address.
USE_NATIVE_CONNECTION_IPunset orfalse→ useX-Forwarded-For, thenX-Real-IP, then the transport-level connection IP if neither header is present.USE_NATIVE_CONNECTION_IP=true→ always use the transport-level connection IP, ignoring the headers. Use this only when clients connect directly, since forwarded headers can be spoofed when not set by a trusted proxy.
AUTHORIZED_ADMINISTRATOR_IPS is a JSON string holding an array of IP addresses, for example ["10.0.0.5", "10.0.0.6"]. It gates the /upgrade command on top of the existing SysAdmin check, so a SysAdmin must also connect from an authorized IP to enter intervention mode.
- Unset, empty, or malformed → the list is treated as empty and no one is allowed to upgrade.
- Contains
"*"→ any IP address is allowed to upgrade. The server prints a warning at boot because this is potentially dangerous. - Otherwise → only the listed IP addresses are allowed to upgrade.
Set AUTHENTICATION_URL to the full HTTPS URL of your authentication endpoint.
The WebProxy sends a GET request to that URL with these headers:
Authorization: <user token>Accept: application/json
Your service should return a non-2xx response for an invalid token. For a valid token, return a JSON user object with this shape:
{
"id": "string",
"displayName": "string",
"organization_id": "string",
"scopes": ["string"],
"isAdmin": false
}Field details:
id: unique user identifierdisplayName: human-readable username, such as an email addressorganization_id: the user's organization identifierscopes: array of scopes granted to the userisAdmin: whether the user is a trusted internal SysAdmin
VERY IMPORTANT:
- Only trusted internal users should have
isAdmin: true. - The server treats
isAdmin: trueusers as SysAdmins, which unlocks special intervention commands. created_atis added by the server at decode time and is not required from the auth service.
Users are partitioned into clusters using their organization_id and the client network identity captured from the websocket connection.
In practice, the current implementation hashes the pair (organization_id, client IP address) into a cluster id. Users only share cache traffic with peers that resolve to the same cluster id, so data never leaves the organization-and-network boundary that produced that cluster.
If you need a different grouping rule, update the cluster id generation in src/webproxy_server/cluster.gleam.
| Method | Path | What it does |
|---|---|---|
GET |
/health |
Returns 200 with {"status":"UP"} for liveness checks. |
GET |
/ws |
Upgrades the connection to a websocket and starts the WebProxy protocol. |
| Message | Who can send it | What it does |
|---|---|---|
ping |
Any connected client | Returns pong. Useful as a lightweight heartbeat. |
/s <auth_token> |
Unauthenticated client | Authenticates the user, joins the cluster, and replies with subscribed on success. |
/r <resource_name> |
Authenticated client | Requests a resource from peers in the same cluster. The server queues the request and forwards it to connected peers. |
/p <resource_id> <response_json> |
Authenticated client | Provides a response for a previously requested resource. The server routes the response back to the original requester. |
/upgrade |
Authenticated SysAdmin from an authorized IP | Switches the connection into intervention mode. Non-admin users, and SysAdmins connecting from an IP not listed in AUTHORIZED_ADMINISTRATOR_IPS, are rejected. |
/su-drop <table> <value> |
Intervention mode only | Deletes a single value from a table. See Intervention Commands. |
/su-clinfo [<cluster_id> | user <display_name>] |
Intervention mode only | Reports cluster membership. See Intervention Commands. |
/su-invalidate <resource_name> [user <display_name> | cluster <cluster_id>] |
Intervention mode only | Forces connected clients to evict a cached resource. See Intervention Commands. |
| Message | Who receives it | What it does |
|---|---|---|
pong |
The client that sent ping |
Heartbeat response. |
subscribed |
The client that sent /s <auth_token> |
Confirms successful authentication and cluster membership. |
/r {resource request json} |
Peers in the same cluster | Broadcasts a resource petition containing resourceId, scopes, and resourceName. |
/p <resource_name> <response_json> |
The original requester | Delivers the response payload for the pending resource. |
Successfully upgraded. You are now in intervention mode. |
A SysAdmin that sent /upgrade |
Confirms that the connection has been upgraded. |
/d <resource_name> |
Clients targeted by /su-invalidate |
Instructs the client to evict the named resource from its cache. |
Once a SysAdmin connection has entered intervention mode with /upgrade, the following privileged commands become available. They are rejected on any other connection. Each command replies with a short status line.
Deletes a single value from one of the tables. <table> is one of:
users—<value>is the user'sdisplay_name(NOT their id or auth token). Every stored user with that display name is removed.clusters—<value>is a cluster id.pending_resources—<value>is a pending resource id.
Reports each matching cluster's id, ip address, organization, and the display names of its members.
/su-clinfo— reports every cluster./su-clinfo <cluster_id>— reports only that cluster./su-clinfo user <display_name>— reports only the clusters the named user belongs to.
Pushes a /d <resource_name> frame to live connections so they evict the cached resource.
/su-invalidate <resource_name>— targets every connection./su-invalidate <resource_name> user <display_name>— targets only the connections of the named user./su-invalidate <resource_name> cluster <cluster_id>— targets only the connections in that cluster.
The request path is designed for cache sharing between nodes in the same organization and network:
- A client asks for a resource with
/r <resource_name>. - The server stores a pending resource entry.
- The request is broadcast to peers in the same cluster.
- A peer answers with
/p <resource_id> <response_json>. - The server deletes the pending entry and forwards the response to the original requester.
gleam run # Run the project
gleam test # Run the testsBuild the image:
docker build -t webproxy-server .Run the container:
docker run --rm \
-e AUTHENTICATION_URL="https://your-auth-server.example.com/auth" \
-e PORT=8080 \
-e AUTHORIZED_ADMINISTRATOR_IPS='["10.0.0.5"]' \
-p 8080:8080 \
webproxy-serverDocker is the recommended way to run the service in production or in a test environment that should match the release image.
For local development, run the project directly with Gleam:
export AUTHENTICATION_URL="https://your-auth-server.example.com/auth"
export PORT=8080
export AUTHORIZED_ADMINISTRATOR_IPS='["10.0.0.5"]'
gleam runIf PORT is not set, the server falls back to 8080. See Environment Variables for the full list.
This project is licensed under the MIT License. See LICENSE.