Structural request proxy
Validate and rebuild JSON, query parameters, ordinary forms and multipart text fields. Forward only to fixed Unix HTTP sockets or a configured PHP FastCGI front controller.
Guard requests and private uploads at a clear boundary.
Rebuild bounded requests before they reach PHP, or receive authorized uploads into encrypted private staging. Local startup configuration owns the resource limits, backend destinations and storage policy.
Open source under 0BSD.
Validate and rebuild JSON, query parameters, ordinary forms and multipart text fields. Forward only to fixed Unix HTTP sockets or a configured PHP FastCGI front controller.
Receive bounded JSON or opaque binary streams into encrypted staging outside every web root. Separate signed grants bind upload and single use retrieval to a user, purpose and object.
Startup configuration can lower compiled ceilings. Headers and uploaded content cannot raise quotas, select storage paths, change scripts or relax timing limits.
Run proxy and staging modes as separate processes under separate accounts. The proxy account does not need access to the staging spool or its encryption key.
Explicit host, method and format allowlists meet routing at path segment boundaries. FastCGI always uses the locally configured front controller. Requests cannot choose another script or socket.
Validate backend responses before delivery, preserve separate cookies and remove internal file redirect headers. Response bodies, CGI records, stderr and connection lifetimes have explicit limits.
A separate authenticated loopback listener provides health and aggregate Prometheus counters. Read only nginx, Apache and Caddy plans help review deployment without changing a server.
The structural proxy ideas were inspired by Qbix/proxy and implemented independently in Go. Read the adaptation notes and compatibility choices.
Captured output from the built aegis process, a private Unix HTTP backend and an isolated PHP FPM pool. Tests verify Unicode JSON, exact large numbers, rebuilt forms, fixed CGI settings, rejected override headers, private metrics and timing limits.

Choose the boundary that matches your workflow. The README includes complete configuration, setup, ownership and rollback instructions.
Copy the proxy example, configure your host and private PHP socket, and set an exact front controller. Review the local configuration and generated edge plan before explicitly activating your copy.
cp config/aegis.proxy.example.json /tmp/aegis-proxy.json
./build/aegis check --config /tmp/aegis-proxy.json
./build/aegis plan --config /tmp/aegis-proxy.json --server nginx
# Edit the copied config for your backend and set enabled to true.
./build/aegis serve --config /tmp/aegis-proxy.jsonWith a configured backend and the example host, send Unicode JSON. aegis validates and rebuilds it before forwarding:
curl --noproxy '*' http://127.0.0.1:8099/api/profile \
-H 'Host: app.example.com' \
-H 'Content-Type: application/json' \
--data-binary '{ "display_name": "雪", "active": true }'Text fields submitted as multipart become a canonical URL encoded form. File parts are rejected and belong in the separate staging flow.
curl --noproxy '*' http://127.0.0.1:8099/api/preferences \
-H 'Host: app.example.com' \
-F 'display_name=雪' -F 'theme=dark'The PHP reference client issues a short upload grant after application authorization. A client uploads bytes directly to aegis. The application verifies ownership of the registered object ID, then uses a separate read grant to retrieve and validate the bytes once. PHP never needs the spool path or storage key.
See the staging walkthrough and ownership contract for key setup, curl and PHP examples.
Configure a separate loopback monitoring listener and private key. Authenticated GET /healthz and GET /metrics expose health and fixed counters, with no request history, uploaded names or policy writes. These paths are unavailable through the main proxy handler.
Source builds require Go 1.27.3, Make and Python 3. Compilation leaves installed tools untouched. Selftests use temporary state and stop when complete.
git clone https://github.com/Starlit-Digital/aegis.git
cd aegis
make compile
./build/aegis version
./build/aegis selftest
python3 scripts/proxy-smoke.pyThe proxy test uses real PHP FPM when it is installed. make verify runs race tests and Go vet. make build installs the CLI in ~/.local/bin. Installation does not start a service; example configurations require explicit activation.


aegis 0.2.1 is available as a prerelease, with CI built binaries for Linux and macOS on amd64 and arm64. Verify the download against SHA256SUMS before running it. Release binaries do not require Go.
shasum -a 256 aegis-darwin-arm64
# Compare with the matching entry in SHA256SUMS.
chmod 0755 aegis-darwin-arm64
./aegis-darwin-arm64 version
./aegis-darwin-arm64 selftest| Boundary | Ceiling |
|---|---|
| Actual request body | 1 MiB |
| Proxy response body | 4 MiB |
| Concurrent operations | 2 |
| Request deadline | 15 seconds |
| JSON depth | 16 levels |
| Staged objects | 16 total, 2 per user |
| Staged retention | 5 minutes |
Proxy mode rejects ambiguous PHP field names, bracket forms, duplicate keys, malformed UTF 8, unsupported encodings and chunked ingress. Multipart accepts text fields only. Signed raw bodies, large downloads, server events and WebSockets need a separate reviewed boundary.
The Go memory target is soft. The Linux reference service adds an OS memory cap, CPU limits and bounded file descriptors; operators must qualify those limits on the deployment host. Applications still own authentication, CSRF, semantic validation, protected persistence and atomic commits.
aegis reduces exposure through bounded parsing, request rebuilding and upload isolation. It does not repair PHP runtime memory handling. Read the official advisories for CVE-2026-109618, OOM corruption and CVE-2026-109619, stale global state, plus the PHP security release notice and PHP Foundation explanation. Update PHP and restart its workers.
The name comes from the aegis of Greek mythology, associated with Zeus and Athena and often described as a shield or protective covering. Its later meaning of protection inspired this project’s name.
Contribute useful examples, reproducible issues, tests and documentation improvements. Share synthetic examples without private source, credentials, customer data or logs.