Technology · Platform

NGINX

NGINX fronts the OAuth server and the estate's other web services with TLS and rate limits, ahead of any application code.

Auth and access planeFAFOHiveTLS, rate limits, access control
The layers round the OAuth server
Outbound tunneloutbound only
NGINXTLS 1.2 and 1.3 · HSTS preload · security headers · per-zone rate limits
systemd unitno new privileges · read-only system · system-call filter · memory limit
OAuth server
About a dozen virtual hosts route to separate services through the same layers.

Layering controls in front of the OAuth server

Auth and access plane needed the OAuth server and the estate's other web services protected in a way that does not depend on each application getting security right. I put NGINX in front of them and the service sandbox behind them. Requests arrive through outbound Cloudflare Tunnel connections, which leaves no open inbound port anywhere in the estate.

Behind NGINX, the OAuth server runs under a locked-down systemd unit, so a flaw in the application still runs without new privileges on a read-only system. The OAuth server's proxy configuration lives in version control beside its source, so a proxy change travels with the code it protects. The consent design these controls protect is in The hardening fix that locked everyone out.

One history for both
the OAuth server's source
its NGINX configuration
Illustrative.

Rate limiting at the proxy

In a hardening pass I had an application-layer rate limiter already written in Python, and I chose the proxy anyway.

Within the zone's limit
reaches the application
Over the limit
turned away before parsing
NGINX
The Python limiter would have run after parsing; it stays out of the request path.

I use NGINX as a deliberate security and traffic-shaping layer and put each control where it is cheapest and hardest to bypass.

Closing the social-publishing modules to the outside

FAFOHive serves its in-house social-publishing modules behind NGINX in the same pattern. Each module is a service whose credentials arrive through systemd's credential mechanism, kept out of files in the service's own directory. Each module also has a control surface for operator actions, and NGINX denies every outside request to it, so it is reachable only locally. Webhooks from the platforms arrive on their own route, where the modules check the platform's signature over the untouched request body.

Agent tool routes
proxied
Platform webhooks
own route, signature checked
Outside, to the control surface
denied
NGINX
A routing mistake inside the application cannot expose the control surface.

NGINX is used unmodified; the placement of controls and the hardening around it are mine.