OAuth 2.1 server implementation in Rust

Efren Yevale Varela 74cb5b38fa Updated documentation před 4 dny
.cargo bbb5878e7d Cleared RUSTSEC před 1 týdnem
.clusterfuzzlite 923681da88 Changed memory-safety for fuzz před 2 týdny
.config 7f3db91ac6 Hardened test před 3 týdny
.github 74cb5b38fa Updated documentation před 4 dny
.sqlx 35345f1021 Fixed bugs před 2 týdny
.well-known 3e8f4d32d1 Security hardening před 3 týdny
deploy 232be93493 Removed pin-digest před 3 týdny
docs 74cb5b38fa Updated documentation před 4 dny
fuzz 0aad5b36ee Added tests před 1 týdnem
migrations 9478660260 Added optionals před 2 týdny
scripts 74cb5b38fa Updated documentation před 4 dny
src 74cb5b38fa Updated documentation před 4 dny
templates 7c50a23515 Initial commit před 1 měsícem
tests b4b95f18a4 Fixed bugs and tests před 1 týdnem
.dockerignore 81769a4f70 Change cache handling před 3 týdny
.gitignore e56c8c9010 Removed link před 2 týdny
AGENTS.md 74cb5b38fa Updated documentation před 4 dny
Cargo.lock bbb5878e7d Cleared RUSTSEC před 1 týdnem
Cargo.toml 35345f1021 Fixed bugs před 2 týdny
Dockerfile 3ad38f73cc Updated components před 3 týdny
LICENSE.md 7c50a23515 Initial commit před 1 měsícem
README.md 74cb5b38fa Updated documentation před 4 dny
SECURITY.md 3e8f4d32d1 Security hardening před 3 týdny
compose.test.yaml 0d522a39e8 Migrated unit tests from per-test containers to shared test services před 3 týdny
compose.yaml 35d12e87ee Updated database versions před 3 týdny
deny.toml bbb5878e7d Cleared RUSTSEC před 1 týdnem
docker-bake.hcl 4197d93e0b Fixed image publishing před 3 týdny
rust-toolchain.toml 7c50a23515 Initial commit před 1 měsícem
rustfmt.toml 7c50a23515 Initial commit před 1 měsícem

README.md

d-OAuth-Server

An OAuth 2.1-only authorization server written in Rust. It is deliberately not backwards compatible with OAuth 2.0: PKCE is mandatory, the implicit and resource-owner-password grants do not exist, bearer-in-query is rejected, and redirect URIs match exactly (with the RFC 8252 §7.3 loopback exception, which includes the host localhost only when allow_localhost_redirect is set).

It implements the authorization-code, refresh-token, client-credentials, device-code, and token-exchange grants, with DPoP, mTLS, PAR, JAR, dynamic client registration, client ID metadata documents, introspection, and revocation. Tokens are opaque and hashed at rest by default; a global enable switch plus a per-client jwt access-token format mints RFC 9068 at+jwt tokens verified against the AS JWKS. All durable domain state is in PostgreSQL and all ephemeral state is in Redis, so replicas are interchangeable. Administration is CLI plus declarative configuration: there is no HTTP admin API and no default credential.

Run it

A self-contained local stack, from the repository root. compose.yaml generates a throwaway TLS certificate and dev-only key files, applies migrations exactly once, and starts one replica against its own Postgres and Redis:

docker compose -f compose.yaml up --build
docker compose -f compose.yaml port app 8080   # host port of the TLS listener

The listener uses that self-signed certificate, so probe it with -k. The discovery document advertises the configured issuer (https://localhost:8080), independent of the random host port:

curl -sk https://127.0.0.1:<host-port>/.well-known/oauth-authorization-server | jq .

From a checkout, against a Postgres and a Redis of your own, with the development environment exported as in QUICKSTART.md:

cargo build --locked
cargo run --bin d-oauth-server -- config check
cargo run --bin d-oauth-server -- migrate
cargo run --bin d-oauth-server -- admin bootstrap --email admin@example.com
cargo run --bin d-oauth-server -- serve
curl -s http://127.0.0.1:8081/health/live
curl -s http://127.0.0.1:8081/health/ready

That is the short version. The full first-run path, including creating a client and minting an access token with PKCE, is QUICKSTART.md.

Documentation

Comprehensive guides live in docs/, whose index maps every guide by audience and reading order.

I want to... Start with
Run it, end to end, with a token QUICKSTART.md
Look up a configuration key CONFIGURATION.md
Administer a live install OPERATIONS.md, RUNBOOK.md
Deploy it to a cluster DEPLOYMENT.md
Integrate an OAuth client OAUTH.md
Protect an API (resource server) RS-CONTRACT.md
Understand or change the code ARCHITECTURE.md, CONTRIBUTING.md
Review the security properties SECURITY.md
Inspect the schema or the Redis keys DATABASE.md, REDIS.md
See what changed in a release CHANGELOG.md

To report a vulnerability, use the reporting policy, not a guide.

Before production

  • There is no default credential and no HTTP admin API. Provision through the CLI or a migration Job (RUNBOOK.md).
  • The token pepper, TOTP encryption key, and PII field-encryption key are required, must each be at least 32 bytes (WeakKeyMaterial otherwise), and are live secrets: losing the pepper invalidates every opaque token, and losing the PII key makes the sealed directory unreadable. Mount them as files, not environment values (DEPLOYMENT.md).
  • Production requires an https issuer and, unless database.require_verify_full is set false, a database URL with sslmode=verify-full.
  • Redis must run with noeviction and persistence; the server asserts both at startup and refuses to start otherwise (REDIS.md).
  • Security endpoints fail closed: when Postgres or Redis is unavailable they return 503 rather than failing open. CORS is empty by default, so browser clients need an explicit origin allowlist.

The threat model and the full invariant list are in SECURITY.md.

Tests

cargo nextest run --all-targets is the authoritative suite, backed by the shared Postgres and Redis from compose.test.yaml; cargo test --doc covers the doctests. The quality gates, the coverage floors, the fuzzing targets, and the exact commands are in CONTRIBUTING.md, with the measured baseline in TEST-COVERAGE.md.

License

ISC. See LICENSE.md.