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.

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

Ships straight into the stack you already run.

Set log.type: "loki" and every log line ProxyAuth writes streams to Grafana Loki instead of just stdout — labeled app=proxyauth, ready to search, filter, and build statistics from in Grafana.

ProxyAuth
Loki
Grafana
one example stat, built from filtered logs in Grafana — requests/min by status: 200s · 403/429s · 401s
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