Open source · Apache 2.0 · Rust 🦀

One binary sits
between the world
and your API.

ProxyAuth is an authenticating reverse proxy. It terminates TLS, checks who's asking, rate-limits them, and forwards the request — no separate auth service, no external identity provider, no assembly required.

$ curl -fsSL https://proxyauth.app/sh/install | bash
100k+req / sec
Argon2idpassword hashing
1 binaryno sidecars
root@edge01 — proxyauth
Why ProxyAuth

Fewer moving parts, not fewer guarantees.

Most auth stacks are a proxy, an OAuth sidecar, a session store, and a rate limiter, wired together. ProxyAuth is one process that does all four — so there's one thing to deploy, one thing to patch, one log to read.

01

Accounts you actually own

Users live in your own config — Argon2id-hashed, checked locally. No Okta tenant, no Google Workspace, no dependency on a third party being up before your users can log in.

02

Built in Rust, on purpose

No garbage collector pauses under load, no class of memory-safety bugs to patch later. The same reasons Rust suits a browser engine suit the thing standing in front of every request your API gets.

03

Your identity, on the request

Once a token checks out, ProxyAuth injects x-user and x-user-roles on the way through. Your backend reads a header — it never has to know a token existed.

04

Grows into a cluster

Add instances behind a load balancer, sync revocation over Redis, and share cryptographic identity between them with a GPG-encrypted keystore export. No re-architecture required.

How it works

Every request, checked once, forwarded clean.

A client authenticates once and gets back an encrypted token. Every request after that carries the token; ProxyAuth verifies it, attaches the caller's identity, and forwards the request — your backend never touches a credential.

Client sends a request
ProxyAuth idle
Your backend never sees the token
Client sends credentials

The client sends a username and password to ProxyAuth — the only place credentials are ever checked.

1 / 6
username + password — issued a token token valid — forwarded to backend token invalid or expired — rejected at the gate
Multi-instance

Run more than one instance? They can share a token.

Why should every component have its own session system when the entire infrastructure can share the same token model?

Two independently-built ProxyAuth instances don't compute tokens the same way by default — each has its own random build constants baked in at compile time. proxyauth sync export hands them from one instance to another over a GPG-encrypted file, so a token issued anywhere in the cluster validates everywhere in it.

Client sends a request
Instance A own build constants
Instance B own build constants
Orders API behind Instance A
Billing API behind Instance B
Two independent instances

Instance A and Instance B both run ProxyAuth, but each was compiled separately — each has its own random build-time constants. Right now, a token issued by one would not validate on the other.

1 / 6
GPG-encrypted key export/import (build constants) a request, routed to either instance
Load balancing

Never wait on a broken backend.

A route can point at several backends instead of one, weighted however you like. ProxyAuth sends each request to a backend picked by weighted round-robin — and if that backend doesn't respond, the same request just moves on to the next one in rotation. Zero requests lost, not a separate retry mechanism bolted on.

ProxyAuth routing…
Backend A in rotation
weight 2
Backend B in rotation
weight 1
Backend C in rotation
weight 1
current target — weighted round-robin timeout — the same request retries on another backend, then it's put on cooldown
Rate limiting

Every route gets a speed limit.

Login attempts and proxied API traffic are rate-limited independently — a burst of bad login attempts can't drown out real API traffic, and vice versa. Requests within the limit pass straight through; anything over the burst gets a clean 429, not a dropped connection.

Clients sending requests
ProxyAuth 0 / 10 req/s
within the limit — forwarded over the burst — 429, blocked at the gate
10 req/s limit
+5 burst allowance
500ms block delay before retry
Today, rate limits apply per route type — one shared limit for all /auth traffic, another for all proxied traffic. Finer-grained, per-route rate limiting (different limits for different endpoints behind the same ProxyAuth instance) is a natural improvement planned for a future release.
Observability

See what your traffic is actually doing.

Set log.type: "loki" and ProxyAuth streams its logs to Grafana Loki. From there, Grafana can search, filter and turn raw requests into live operational signals.

ProxyAuth streaming
Loki ingesting logs
Grafana analyzing
Request traffic requests / interval
LIVE
−60s−45s−30s−15snow
Log analysis HTTP status distribution
app=proxyauth
1,248 logs
200 Success72%
303 Redirect11%
401 Unauthorized7%
403 Forbidden5%
503 Unavailable3%
429 Rate limited2%
Live log stream filtered and classified by status
{app="proxyauth"}▸ status
200 successful requests 303 redirects 401/403 auth failures 503 upstream unavailable 429 rate limited
Under the hood

Standard primitives. No home-rolled cipher.

Every cryptographic decision uses a well-studied, widely deployed primitive — chosen for what it's actually good at, not for how it sounds in a pitch.

Passwords
Argon2id
Winner of the Password Hashing Competition. Per-user salt, tuned cost parameters.
Token encryption
XChaCha20-Poly1305
Authenticated encryption with a 192-bit nonce — safe against collisions even at very high token volume.
Key derivation
HKDF-SHA256
Derives the token-encryption key from your configured secret, with domain separation.
Signing / hashing
BLAKE3
Fast, modern hashing — used for token identity and CSRF signatures alike.
Get started

Running in under a minute.

Pick a channel. The installer detects your distro, builds the binary, sets up the proxyauth system user, and registers a service — systemd or OpenRC.

bash
# install the latest stable release
$ curl -fsSL https://proxyauth.app/sh/install | bash

# confirm it's running
$ sudo systemctl status proxyauth
bash
# track the beta channel
$ curl -fsSL https://proxyauth.app/sh/beta-install | bash

# or pin an exact version
$ curl -fsSL https://proxyauth.app/sh/install@0.8.13 | bash
⚠️ Beta and version-pinned installs move fast — check the wiki for what changed before you upgrade a production instance.
bash
# clone the official Docker setup
$ git clone https://git.proxyauth.app/ProxyAuth/Docker ProxyAuth && cd ProxyAuth/latest

# fix ownership (container runs as uid/gid 1000)
$ sudo chown 1000:1000 config/config.json config/routes.yml

# build and start
$ docker compose build && docker compose up -d
Ecosystem

Everything else lives here.

Ready when you are

Put ProxyAuth in front
of something today.

One command. No account required, no external service to configure first.

$ curl -fsSL https://proxyauth.app/sh/install | bash