Skip to content

qauth-labs/qauth

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

410 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation



QAuth Logo



Open-source identity for the agent era.
OAuth 2.1 Β· OIDC 1.0 Β· MCP & AI-agent authorization Β· federation-ready Β· post-quantum ready.

QAuth is an open-source OAuth 2.1 / OIDC 1.0 identity server built for three horizons at once:

  • Agent era (today) β€” a working authorization server for MCP servers and AI agents: email/password auth, authorization_code (PKCE) and client_credentials grants, per-client audience (aud) binding, and agent-native, on-behalf-of delegation with scope modes and step-up (ADR-007).
  • Federation (by design) β€” a federation hub from day one: wallet-based upstreams (EUDI Wallets via OID4VC / OID4VP) and external OIDC providers slot in behind the CredentialProvider interface (ADR-003, ADR-004), so downstream applications integrate against QAuth's OIDC layer once and never change.
  • Post-quantum (for the long haul) β€” crypto-agile by construction: JWTs sign behind algorithm-agnostic interfaces today, with a clear hybrid ML-DSA-65 + Ed25519 transition path (ADR-005, ADR-006) that never touches application business logic.

The near-term focus is MCP / AI-agent authorization; wallet federation and post-quantum signing are the resequenced long-term platform. One server, one integration, across all three.

πŸ‡ͺπŸ‡Ί Made in Europe Β· πŸ‡ͺπŸ‡ͺ Made in Estonia Β· πŸ‡ΉπŸ‡· Made in TΓΌrkiye

πŸŽ‰ June 2026 milestone β€” MVP complete, agent-native authorization shipped, and production hardening (T3) done. Agent client type, RFC 8693 on-behalf-of token exchange, scope modes (ReadOnly / Admin / Exec), step-up, and per-agent audit are all live and documented (ADR-007 Β§2 Β· agent guide). The T3 hardening track and the T5 environment-aware authorization posture (ADR-008) also shipped end-to-end. The near-term roadmap is complete; remaining work is the long-term platform (wallet federation + post-quantum signing, T4).

Status: Core OAuth 2.1 / OIDC and the MCP / agent-native authorization layer work end-to-end β€” discovery, dynamic client registration, resource-indicator audience binding, consent, and on-behalf-of agent delegation (the self-hostable OAuth 2.1 authorization server for MCP servers and AI agents; see ADR-007). Wallet federation and post-quantum signing remain the long-term platform. See Current Status. Production hardening (T3) is complete β€” security headers, CSRF, secure cookies, OIDC ID token/nonce/claims, and observability all ship; deploy with the documented production configuration. The environment-aware authorization posture (T5, ADR-008) is also complete β€” environment selects a fail-safe policy profile, and the near-term roadmap is finished. Remaining work is the long-term platform (wallet federation + post-quantum signing, T4).

⚠️ AI-Assisted Development & Security Notice

This project is developed with extensive AI assistance. Every change goes through human review before it is merged; even so, at this stage we cannot yet promise a high level of security assurance β€” use it with care and run your own evaluation before trusting it in sensitive or production deployments. Our long-term goal is enterprise-grade security with the lightest possible processing footprint: to that end, we are rewriting QAuth module by module in Rust.

🎯 How to Use QAuth

1. 🏠 Self-hosted (today)

The self-hostable auth server is what ships today. Run it locally with Docker Compose in a few minutes:

# Clone and start the stack (auth-server + Postgres 18 + Redis 7)
git clone https://github.com/qauth-labs/qauth.git
cd qauth
cp .env.docker.example .env   # then add your JWT keys β€” see Quick Start below
docker compose up -d

# Verify
curl http://localhost:3000/health

You can then drive it directly via the standard OAuth 2.1 / OIDC endpoints:

# Token endpoint β€” authorization code + PKCE (user-context)
curl -X POST http://localhost:3000/oauth/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=authorization_code&code=...&code_verifier=...&client_id=..."

# Token endpoint β€” client_credentials (service-to-service, RFC 6749 4.4)
# Client auth via HTTP Basic (client_secret_basic, RFC 6749 2.3.1)
curl -X POST http://localhost:3000/oauth/token \
  -u "CLIENT_ID:CLIENT_SECRET" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials&scope=read:foo"

Interactive API docs (OpenAPI / Swagger UI) are served at /docs on the running instance.

Good fit for:

  • Data sovereignty and GDPR requirements
  • Self-hosted OAuth 2.1 / OIDC without the Keycloak footprint
  • Organisations planning for eIDAS 2.0 wallet login as it lands (Phase 4)

2. ⚑ Auth as a Service (planned)

πŸ“‹ Planned β€” Phase 3+. The hosted QAuth backend and @qauth-labs/core SDK described in the examples below are not available yet. The self-hosted path above is the supported deployment today.

// πŸ“‹ Planned SDK surface β€” not yet published
import { QAuth } from '@qauth-labs/core';

const auth = new QAuth({
  domain: 'auth.yourapp.com',
  mode: 'headless',
});

Target audience when available:

  • Applications that need eIDAS 2.0 EUDI Wallet login without rewriting their auth layer
  • Teams that want a headless API-first backend with custom branding
  • Startups that want to skip identity infrastructure entirely

πŸ” Post-Quantum Cryptography

QAuth's PQC strategy is documented in ADR-005. The post-quantum hybrid layer is design-stage today, but the crypto-agile foundation is live now: Phase 1 β€” current and shipping β€” signs JWTs with Ed25519 behind algorithm-agnostic interfaces. The ML-DSA hybrid transition is planned for Phase 5.

Primary standard (target)

  • ML-DSA-65 (NIST FIPS 204) β€” Digital signatures for JWT tokens. Level 3 (192-bit security), the minimum floor recommended by BSI (Germany) and ANSSI (France).

Hybrid strategy (target)

Defense in depth via composite dual-signing β€” tokens will carry both an ML-DSA-65 and an Ed25519 signature, following the IETF LAMPS composite signatures model (draft-ietf-lamps-pq-composite-sigs). Both classical and post-quantum verifiers can validate without coordination.

// βš™οΈ Planned API β€” Phase 5 (2027 target, per ADR-005).
// @qauth-labs/crypto is not yet published. The interface below is a design
// sketch; ML-DSA JOSE key/alg identifiers follow RFC 9964.
import { signHybrid } from '@qauth-labs/crypto';

const token = await signHybrid(payload, { mlDsaKey, ed25519Key });

Planned implementation:

@qauth-labs/crypto will be a native Node.js binding (napi-rs) wrapping aws-lc-rs (AWS-LC, a production-hardened BoringSSL fork with FIPS 140-3 validation in progress). This follows the same pattern as @node-rs/argon2 β€” prebuilt binaries per platform, no build tooling required for consumers. @noble/post-quantum (pure TypeScript, audited) is planned as the fallback for development environments and CI.

ADR-005 specifies a libs/core/crypto abstraction that will expose algorithm-agnostic sign / verify / generateKeyPair interfaces so that business logic is never coupled to a specific implementation. Swapping the underlying library will require no changes to the auth server.

Token size considerations:

ML-DSA-65 signatures are 3,309 bytes vs. Ed25519's 64 bytes. QAuth's architecture is being designed to default to reference tokens with introspection (RFC 7662) rather than large self-contained JWTs β€” mitigating HTTP header limits and cookie size constraints during the PQC transition period.

Migration timeline:

  • Phase 1 (current / live now): Ed25519 / EdDSA for JWT signatures, plus crypto-agile interfaces
  • Phase 5 (2027 target): Hybrid composite ML-DSA-65 + Ed25519 (JOSE WG draft adopted Jan 2026)
  • Future: FN-DSA (NIST FIPS 206, pending) evaluation β€” compact signatures (~666 B) may make self-contained PQC JWTs practical

🎯 Vision

An identity hub for the next generation of the internet β€” humans, agents, and wallets on one server:

  • Agent-native β€” first-class authorization for MCP servers and AI agents: an agent client type, RFC 8693 on-behalf-of delegation, scope modes, and step-up, so agents act for users under least privilege and full audit
  • Federation-first β€” a single federation-core layer will normalise upstream identity (Verifiable Credential wallets, email/password, external OIDC providers, W3C DIDs) into a common internal model; downstream applications see standard OIDC tokens regardless of source
  • Wallet-agnostic β€” any standards-compliant VC wallet (OID4VC / OID4VP) will be a valid upstream; EUDI Wallet under eIDAS 2.0 is one concrete deployment target, not the only one
  • Post-quantum ready β€” crypto-agile architecture with a clear ML-DSA-65 hybrid transition path, designed so algorithm upgrades never touch application business logic
  • Headless-first β€” API-first, bring your own branded UI
  • Standards compliant β€” OAuth 2.1 (RFC 9700), OIDC 1.0, OID4VC, OID4VP, W3C DID, NIST FIPS 204
  • Open and self-hostable β€” Apache 2.0, no telemetry, runs anywhere

πŸ“ Current Status (June 2026)

πŸŽ‰ Milestone reached. The MVP is complete, the agent-native authorization track (ADR-007 Β§2) shipped, and the T3 production-hardening track is now done β€” QAuth does OAuth 2.1 / OIDC, MCP authorization, full on-behalf-of agent delegation, and the security/observability hardening, end to end and documented.

QAuth is feature-complete for MCP / agent authentication, with the production-hardening track (T3) complete. An honest snapshot.

Phase 1 core OAuth 2.1 / OIDC, the MCP and agent-native authorization layers, the T3 production-hardening track (CSRF, security headers, secure cookies, OIDC ID token/nonce/claims, structured logging + /metrics, failed-login lockout), and the T5 environment-aware authorization posture (ADR-008 β€” environment as a fail-safe policy dimension + environment-gated developer API keys) are all complete and live-tested end-to-end. The near-term roadmap is finished; remaining work is the long-term platform (wallet federation + post-quantum signing, T4).

Near-term focus β€” MCP / AI-agent auth. Building OAuth 2.1 properly produced a working authorization server for MCP servers and AI agents, validated end-to-end with Claude Code against a live MCP server. That is now the near-term direction; wallet federation and post-quantum signing are the long-term platform, sequenced after. See ADR-007.

βœ… Working today

  • OAuth 2.1 authorization code flow with mandatory PKCE, including public clients (none + PKCE)
  • client_credentials and refresh_token grants β€” rotation + family-based replay detection (RFC 9700)
  • Resource Indicators (RFC 8707) β€” audience-bound tokens across authorize β†’ code β†’ token β†’ refresh
  • Dynamic Client Registration (RFC 7591, open mode) + Authorization Server Metadata / OIDC discovery / JWKS
  • Token introspection (RFC 7662), OIDC userinfo, consent screen + grant revocation
  • Email/password registration + verification (Argon2id; Resend / SMTP / Mock), multi-tenancy via Realms
  • Developer portal: registration / login / verify + dashboard shell (server-side __Host- session)
  • PostgreSQL 18 + Redis 7 with Docker Compose; OpenAPI / Swagger UI at /docs
  • Client-management API + developer-portal UI β€” full /api/clients CRUD with one-time secrets
  • Agent-native authorization (ADR-007 Β§2) β€” agent client type, RFC 8693 on-behalf-of token exchange (act claim), scope modes (ReadOnly / Admin / Exec), step-up before dangerous operations, and per-agent audit
  • Documentation β€” MCP quickstart, OAuth 2.1 flow, API reference, and the agent-authorization guide
  • @qauth-labs/mcp-guard β€” resource-server SDK: RFC 9728 protected-resource metadata + 401 challenge + token validation
  • Client ID Metadata Documents (CIMD) as the primary client-registration path (MCP 2025-11-25); RFC 7591 dynamic registration kept as the documented fallback
  • Trust floor: real-DB (testcontainers) repository tests + logout endpoint test + CI typecheck/coverage gate
  • Security hardening (T3) β€” @fastify/helmet security headers (nonce-based CSP, HSTS, X-Frame-Options, X-Content-Type-Options), CSRF double-submit protection, __Host- secure cookies, and XSS-safe HTML output
  • OIDC conformance (T3) β€” ID token issuance (EdDSA) with nonce, and aligned sub / email / email_verified / name claims across ID token, userinfo, and discovery
  • Observability (T3) β€” structured pino logging with secret redaction, X-Request-Id propagation, Prometheus /metrics (login + token counters), and Redis-backed failed-login tracking with lockout
  • developer-portal production Docker image + Docker Compose service
  • Environment-aware authorization (T5, ADR-008) β€” environment (development / staging / production) as a fail-safe, operator-set policy dimension on clients/realms; a single resolveEnvironmentPolicy resolver drives token TTLs, PKCE, localhost redirects, rate-limit tier, agent step-up, and the T3 security bundle; plus environment-gated static developer API keys (backend + portal UI)

🚧 In progress / next

  • The near-term roadmap (T0–T3, T5) is complete. Next is the long-term platform β€” wallet federation and post-quantum signing (T4), gated on the ADR-002 identifier-abstraction migration.

πŸ“‹ Deferred β€” long-term platform (designed, not yet implemented; resequenced per ADR-007)

  • Identifier-abstraction migration β€” ADR-002, now the gate for Phase 4
  • Wallet federation (OID4VC / OID4VP) β€” ADR-004
  • Post-quantum hybrid signing + @qauth-labs/crypto β€” ADR-005
  • SDKs (@qauth-labs/core, @qauth-labs/react, @qauth-labs/node), auth-ui, admin-panel

ADR-006 (OAuth grants β€” client_credentials / client_secret_basic + aud claim) is implemented and shipping today, not deferred; the grants and audience binding above ship in the auth server now.

Tracking: MVP milestone Β· ADR index Β· MVP-PRD

πŸ—οΈ Architecture

Phase 1: Modular Monolith (TypeScript)

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚              Auth Server (TypeScript/Node.js)        β”‚
β”‚                                                      β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚  API Layer (REST)                              β”‚  β”‚
β”‚  β”‚  OAuth 2.1 Β· OIDC 1.0 (βœ…)                     β”‚  β”‚
β”‚  β”‚  OID4VC Β· OID4VP (πŸ“‹ Phase 4)                  β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚                          ↓                           β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚  federation-core  (πŸ“‹ Phase 2/4)               β”‚  β”‚
β”‚  β”‚  β€’ Upstream normalisation (VC wallet / OIDC /  β”‚  β”‚
β”‚  β”‚    password β†’ internal user model)             β”‚  β”‚
β”‚  β”‚  β€’ Downstream token issuance                   β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚                          ↓                           β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚  Crypto Layer                                  β”‚  β”‚
β”‚  β”‚  β€’ JWT signing / verification                  β”‚  β”‚
β”‚  β”‚      βœ… Ed25519 via `jose`                     β”‚  β”‚
β”‚  β”‚      πŸ“‹ Phase 5 β€” native bindings via napi-rs  β”‚  β”‚
β”‚  β”‚  β€’ Password hashing βœ… Argon2id (@node-rs)     β”‚  β”‚
β”‚  β”‚  β€’ DID resolution πŸ“‹ Phase 6+                  β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
              ↓                           ↓
        PostgreSQL 18                  Redis 7

Phase 6+: Microservices extraction (when needed)

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  API Gateway (TS)    β”‚
β”‚  β€’ REST              β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
          ↓ gRPC
    β”Œβ”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    ↓           ↓             ↓              ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Auth   β”‚ β”‚ Token   β”‚ β”‚ Session  β”‚ β”‚ Developer   β”‚
β”‚ (TS)   β”‚ β”‚ (TS)    β”‚ β”‚ (TS)     β”‚ β”‚ Portal (TS) β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Nx Monorepo Structure

Legend: βœ… implemented Β· 🚧 in progress Β· πŸ“‹ planned

qauth/
β”œβ”€β”€ apps/
β”‚   β”œβ”€β”€ auth-server/          βœ… Fastify OAuth 2.1 / OIDC 1.0 server
β”‚   β”œβ”€β”€ developer-portal/     βœ… TanStack Start portal β€” auth, client CRUD, API keys
β”‚   β”œβ”€β”€ migration-runner/     βœ… Drizzle migrations runner
β”‚   β”œβ”€β”€ auth-ui/              πŸ“‹ planned β€” brandable login UI, Phase 2/4
β”‚   └── admin-panel/          πŸ“‹ planned β€” Phase 6+
β”‚
β”œβ”€β”€ libs/
β”‚   β”œβ”€β”€ server/
β”‚   β”‚   β”œβ”€β”€ config/           βœ… environment config + Zod validation
β”‚   β”‚   β”œβ”€β”€ jwt/              βœ… EdDSA signing / verification via `jose`
β”‚   β”‚   β”œβ”€β”€ password/         βœ… Argon2id via @node-rs/argon2
β”‚   β”‚   β”œβ”€β”€ pkce/             βœ… PKCE utilities
β”‚   β”‚   β”œβ”€β”€ email/            βœ… Resend / SMTP / Mock providers
β”‚   β”‚   └── federation/       πŸ“‹ CredentialProvider interface (ADR-003)
β”‚   β”‚                         #     password.provider.ts, wallet.provider.ts
β”‚   β”‚                         #     Normalises upstream β†’ VerifiedIdentity
β”‚   β”‚
β”‚   β”œβ”€β”€ fastify/plugins/      βœ… db Β· cache Β· email Β· jwt Β· password Β· pkce Β· mcp-guard
β”‚   β”œβ”€β”€ infra/
β”‚   β”‚   β”œβ”€β”€ db/               βœ… PostgreSQL 18 + Drizzle ORM, repository pattern
β”‚   β”‚   └── cache/            βœ… Redis 7 connection + caching utilities
β”‚   β”‚
β”‚   β”œβ”€β”€ shared/
β”‚   β”‚   β”œβ”€β”€ errors/           βœ… centralised error classes
β”‚   β”‚   β”œβ”€β”€ validation/       βœ… email / password validation utilities
β”‚   β”‚   └── testing/          βœ… test helpers and fixtures
β”‚   β”‚
β”‚   β”œβ”€β”€ ui/                   βœ… shared React primitives (early)
β”‚   β”‚
β”‚   β”œβ”€β”€ core/                 πŸ“‹ planned extraction (ADR-005)
β”‚   β”‚   β”œβ”€β”€ oauth/            #   currently inlined in apps/auth-server
β”‚   β”‚   β”œβ”€β”€ oidc/             #   currently inlined in apps/auth-server
β”‚   β”‚   └── crypto/           #   @qauth-labs/crypto β€” napi-rs + aws-lc-rs (Phase 5)
β”‚   β”‚                         #     @noble/post-quantum dev/CI fallback
β”‚   β”‚
β”‚   └── sdk/                  πŸ“‹ planned β€” Phase 3
β”‚       β”œβ”€β”€ js/               #   Vanilla JS SDK
β”‚       β”œβ”€β”€ react/            #   React SDK + hooks
β”‚       └── node/             #   Server-side SDK
β”‚
└── services/                 πŸ“‹ planned microservices β€” Phase 6+
    β”œβ”€β”€ token-service/        #   Token generation (gRPC)
    └── session-service/      #   Session management (gRPC)

πŸš€ Features

Phase 1 β€” Core Auth Server (complete)

Status: Core OAuth 2.1 / OIDC flows work end-to-end with Ed25519 JWTs, Argon2id, PKCE, multi-tenancy via Realms, dynamic client registration, resource-indicator audience binding, and consent. The T3 hardening items β€” OIDC conformance detail (ID token, nonce, claims), structured logging + metrics, security headers, and the developer-portal Dockerfile β€” shipped under the T3 milestone (see ADR-007). For the full snapshot, see Current Status.

Core authentication (working today):

  • OAuth 2.1 / OpenID Connect 1.0 authorization code flow
  • OAuth 2.1 client_credentials grant for service-to-service auth (RFC 6749 4.4)
  • Client authentication via client_secret_post and client_secret_basic (RFC 6749 2.3.1)
  • Email/password authentication with Argon2id hashing
  • JWT token issuance with aud and scope claims, refresh, and revocation (Ed25519 / EdDSA)
  • Token introspection (RFC 7662)
  • OIDC userinfo endpoint
  • Multi-tenancy via Realms for complete data isolation
  • Mandatory PKCE on all authorization code flows

Infrastructure (working today):

  • Email verification β€” Resend, SMTP, and Mock providers
  • PostgreSQL 18 + Redis 7
  • Docker deployment with automated migrations and health checks
  • Structured audit logging (basic)
  • Scriptable machine-client provisioning (nx run db:db:seed-oauth-clients) β€” JSON-manifest-driven, idempotent, argon2id-hashed secrets; useful for bootstrapping client_credentials clients at deploy time, independently of the developer portal

Developer tools:

  • REST API (OAuth 2.1 / OIDC endpoints) βœ…
  • OpenAPI / Swagger UI at /docs βœ…
  • Self-service developer portal βœ… (auth, client CRUD, API keys)
  • TypeScript / React / Node.js SDKs πŸ“‹ (Phase 3)

Delivered post-MVP (near-term tracks)

Developer Portal (Phase 2 β€” shipped):

  • Self-service OAuth client registration and management βœ… (/api/clients + portal UI)
  • API key management βœ… (environment-gated developer API keys, ADR-008)
  • Federation provider configuration UI πŸ“‹ (deferred with wallet federation, T4)

Production Hardening (Phase 3 / T3 β€” shipped):

  • OIDC discovery + JWKS endpoint, ID tokens, nonce, scopes βœ…
  • Rate limiting (Redis token bucket) βœ… (with the T5 environment rate-limit tier)
  • Security headers (Helmet: HSTS, CSP, X-Frame-Options) βœ…
  • Prometheus metrics βœ…
  • OIDC 1.0 formal conformance (OpenID Foundation certification suite) πŸ“‹
  • Kubernetes manifests πŸ“‹

Phase 4 β€” Wallet Federation Bridge (OID4VC / OID4VP):

  • OID4VP authorization request handling
  • OID4VC Verifiable Presentation endpoint
  • Trust anchor validation (extensible: EU Trusted List and other registries)
  • federation-core: normalises Verifiable Credentials β†’ standard OAuth 2.1 tokens
  • Wallet login UI flow in auth-ui
  • Inverse: QAuth as a Verifiable Credential issuer

Phase 5 β€” Post-Quantum Crypto:

  • @qauth-labs/crypto: native Node.js binding (napi-rs + aws-lc-rs)
  • Hybrid composite ML-DSA-65 + Ed25519 JWT signing (IETF LAMPS composite model)
  • Reference-token architecture to handle PQC JWT size constraints
  • Crypto-agile abstraction: algorithm swaps require no changes to business logic
  • @noble/post-quantum fallback for dev/CI environments

Phase 6+ β€” Enterprise & Scale:

  • Social login (Google, GitHub, Microsoft)
  • WebAuthn / Passkeys, TOTP / MFA
  • SAML 2.0, LDAP / Active Directory
  • W3C Decentralised Identifiers (DIDs)
  • Organizations, Teams, advanced RBAC
  • GraphQL API, webhook system
  • Multi-region, CDN, microservices extraction

πŸ› οΈ Technology Stack

Backend:

  • Runtime: Node.js 24 LTS
  • Language: TypeScript 6.0
  • Framework: Fastify
  • API: REST (OAuth 2.1 / OIDC)
  • ORM: Drizzle ORM
  • Database: PostgreSQL 18
  • Cache/Session: Redis 7
  • Password hashing: @node-rs/argon2 (Rust native binding, Argon2id)
  • JWT (today): jose (Ed25519 / EdDSA)
  • Crypto (planned, ADR-005): @qauth-labs/crypto β€” native Node.js binding (napi-rs + aws-lc-rs); @noble/post-quantum in dev/CI

Frontend:

  • Meta-framework: TanStack Start
  • Framework: React 19
  • Router: TanStack Router
  • Data Fetching: TanStack Query
  • Build Tool: Vite 8 (Rolldown)
  • UI Primitives: Radix UI
  • Styling: Tailwind CSS
  • Tables: TanStack Table
  • Forms: TanStack Form

Infrastructure:

  • Monorepo: Nx 23
  • Package Manager: pnpm 11
  • Linting: ESLint 10
  • Containerization: Docker
  • Orchestration: Kubernetes ready (manifests planned, Phase 3)
  • Observability: OpenTelemetry (planned, Phase 3)
  • Cache/Session: Redis with ioredis

πŸš€ Quick Start

Local Development with Docker

The easiest way to get started with QAuth locally is using Docker Compose. This will set up PostgreSQL, Redis, and the auth-server with a single command.

Prerequisites:

  • Docker 20.10+ and Docker Compose 2.0+
  • OpenSSL (for generating JWT keys)

Quick Start:

  1. Generate JWT keys (required for authentication):
# Generate EdDSA key pair
openssl genpkey -algorithm Ed25519 -out private.pem
openssl pkey -in private.pem -pubout -out public.pem
  1. Set up environment variables:
# Copy the example environment file
cp .env.docker.example .env

# Edit .env and add your JWT keys:
# JWT_PRIVATE_KEY="$(cat private.pem)"
# JWT_PUBLIC_KEY="$(cat public.pem)"
  1. Start all services:
docker compose up -d

This will:

  • Start PostgreSQL 18 (with uuidv7() support)
  • Start Redis 7
  • Build and start the auth-server
  • Run database migrations automatically
  • Expose the API on http://localhost:3000
  1. Verify the setup:
# Check service health
curl http://localhost:3000/health

# Browse interactive API docs
open http://localhost:3000/docs

# Check service logs
docker compose logs -f auth-server

Accessing Services:

Running Migrations Manually:

Migrations run automatically via the migration-runner service before auth-server starts. You can also run them manually:

docker compose run --rm migration-runner

Stopping Services:

docker compose down

# To also remove volumes (deletes all data):
docker compose down -v

Testing the Setup:

A comprehensive test script is available to verify everything works:

./scripts/test-docker.sh

This script will:

  • Check environment configuration
  • Build Docker images
  • Start all services
  • Run migrations
  • Verify health checks
  • Test API endpoints
  • Verify data persistence

Troubleshooting:

  • Port conflicts: If ports 3000, 5432, or 6379 are already in use, modify the port mappings in docker-compose.yml
  • Migration errors: Check that PostgreSQL is healthy: docker compose ps
  • JWT errors: Ensure your JWT keys are properly formatted in .env (include BEGIN/END lines)
  • Build failures: Ensure you have enough disk space and Docker has sufficient resources allocated
  • Migration runner fails: Check logs with docker compose logs migration-runner

For more details, see the Docker documentation.

Self-hosted Mode (Production)

βœ… Production hardening (T3) is complete β€” rate limiting, security headers, CSRF, secure cookies, OIDC conformance, and structured logging + /metrics all ship. Deploy with the documented production configuration (strict cookies, HSTS, LOG_LEVEL, etc.). Kubernetes manifests remain a post-MVP item.

# Docker deployment (once tagged images are published)
docker run -p 3000:3000 qauth/auth-server

# Or with docker-compose
curl -O https://qauth.dev/docker-compose.yml
docker compose up -d

πŸ—ΊοΈ Roadmap

Near-term direction is MCP-first (ADR-007). The tracks below set near-term priority; the numbered phases that follow remain the long-term plan, resequenced so wallet federation (Phase 4) and post-quantum signing (Phase 5) follow the MCP work.

  • βœ… T0 β€” Trust floor: real-DB repository tests, logout endpoint test, CI typecheck + coverage gate
  • βœ… T1 β€” MCP productization: @qauth-labs/mcp-guard (RFC 9728 metadata + token validation + step-up scope challenges), Client ID Metadata Documents (CIMD) support, MCP quickstart + example, RFC 7009 revocation
  • βœ… T2 β€” Agent-native authZ (the Phase 9 substance, pulled forward): agent client type, RFC 8693 token-exchange delegation, scope modes (ReadOnly/Admin/Exec), step-up, per-agent audit
  • βœ… T3 β€” OIDC conformance + hardening (done): security (CSRF/Helmet/secure cookies/XSS), observability (pino//metrics/request-id/failed-login lockout), ID token/nonce/claims, developer-portal Docker image
  • βœ… T5 β€” Environment-aware authZ (ADR-008) (done): environment as a fail-safe, operator-set policy dimension; resolveEnvironmentPolicy driving token TTLs / PKCE / localhost redirects / rate-limit tier / agent step-up / T3 bundle; environment-gated developer API keys (backend + portal UI)
  • πŸ“‹ T4 β€” Federation + PQC (deferred long-term moat): Phases 4–5 below, gated on the ADR-002 migration

Phase 1: Core Auth Server (complete)

  • Database schema design (PostgreSQL + Drizzle ORM, UUIDv7)
  • Multi-tenancy via Realms
  • Repository pattern with BaseRepository interface
  • Centralised error handling (@qauth-labs/shared-errors)
  • Core auth server (Fastify/TypeScript)
  • Email/password authentication with Argon2id
  • OAuth 2.1 authorization code flow + PKCE
  • JWT issuance / refresh / revocation (EdDSA)
  • Token introspection (RFC 7662), OIDC userinfo
  • Email verification (Resend, SMTP, Mock providers)
  • PostgreSQL + Redis setup
  • Docker deployment with automated migrations
  • OpenAPI / Swagger UI docs
  • OIDC 1.0 ID tokens, nonce, scope/claims handling (T3)
  • Structured logging (pino) + Prometheus metrics (T3)
  • Rate limiting (Redis token bucket) (T3 + T5 environment tier)

Phase 2: Developer Portal (registration/login/verify + client management + API keys shipped)

  • Developer registration / login
  • Self-service OAuth client management (CRUD β€” /api/clients + portal UI)
  • API key management (environment-gated developer API keys, ADR-008)
  • Federation provider configuration UI (deferred with wallet federation, T4)

Phase 3: Production Hardening & SDKs

  • OIDC discovery (/.well-known/openid-configuration) + JWKS endpoint (T3)
  • CSRF protection, security headers (Helmet) (T3)
  • OIDC 1.0 formal conformance (OpenID Foundation certification suite)
  • Kubernetes manifests
  • JavaScript / React / Node.js SDKs (@qauth-labs/core, @qauth-labs/react, @qauth-labs/node)

Phase 4: Wallet Federation Bridge (OID4VC / OID4VP) (deferred β€” gated on ADR-002 migration)

  • OID4VP authorization request handling
  • OID4VC Verifiable Presentation endpoint
  • Trust anchor validation (extensible: EU Trusted List and other registries)
  • federation-core library: VC wallet β†’ standard OAuth 2.1 / OIDC tokens
  • Wallet login UI flow in auth-ui
  • Inverse direction: QAuth as a Verifiable Credential issuer
  • Integration tests against EUDI reference wallet

Phase 5: Post-Quantum Crypto (deferred β€” long-term platform)

  • @qauth-labs/crypto: native Node.js binding (napi-rs + aws-lc-rs)
  • Hybrid composite ML-DSA-65 + Ed25519 JWT signing
  • Reference-token architecture for PQC JWT size compatibility
  • Crypto-agile abstraction layer (sign / verify / generateKeyPair)
  • @noble/post-quantum dev/CI fallback
  • Security review of cryptographic implementation

Phase 6+: Enterprise & Scale

  • Social login (Google, GitHub, Microsoft)
  • WebAuthn / Passkeys, TOTP / MFA
  • SAML 2.0, LDAP / Active Directory
  • W3C DIDs, advanced RBAC, Organizations & Teams
  • GraphQL API, webhooks, multi-region, microservices extraction

🧩 Planned SDK Usage (Phase 3)

πŸ“‹ Not yet published. The SDK packages (@qauth-labs/core, @qauth-labs/react, @qauth-labs/node) are planned for Phase 3. The examples below show the intended API surface β€” they will not work until the packages are released. For Phase 1 integration today, call the OAuth 2.1 / OIDC endpoints directly (see /docs on a running instance).

Auth as a Service Mode (planned)

// πŸ“‹ Planned β€” not yet published
npm install @qauth-labs/core

import { QAuth } from '@qauth-labs/core';

const auth = new QAuth({
  domain: 'auth.yourapp.com',
  projectId: 'your-project-id',
  apiKey: 'your-api-key',
});

const { user, session } = await auth.signInWithPassword({
  email: 'user@example.com',
  password: 'password',
});

await auth.signUp({
  email: 'newuser@example.com',
  password: 'securepass',
  metadata: { plan: 'pro' },
});

const session = await auth.getSession();

Self-hosted Mode (planned)

// πŸ“‹ Planned β€” not yet published
import { QAuth } from '@qauth-labs/core';

const auth = new QAuth({
  mode: 'self-hosted',
  baseUrl: 'https://auth.yourcompany.com',
  clientId: 'internal-app',
});

await auth.loginWithRedirect();

React SDK (planned)

// πŸ“‹ Planned β€” not yet published
import { QAuthProvider, useAuth } from '@qauth-labs/react';

function App() {
  return (
    <QAuthProvider
      mode="self-hosted"
      baseUrl="https://auth.yourcompany.com"
      clientId="..."
    >
      <Dashboard />
    </QAuthProvider>
  );
}

function Dashboard() {
  const { user, login, logout, loading } = useAuth();

  if (loading) return <Spinner />;
  if (!user) return <button onClick={login}>Login</button>;

  return <div>Welcome {user.name}</div>;
}

πŸ“Š Deployment Modes

Feature Self-hosted (today) Auth as a Service (planned)
Availability βœ… Today (early) πŸ“‹ Phase 3+
Setup Time ~15 min with Docker 15 minutes
Infrastructure You manage None (hosted)
Custom Domain βœ… βœ…
Custom Branding βœ… βœ…
Data Location Your servers Our servers
Compliance Full control Standard
Pricing Free (self-host costs) Usage-based
Best For Enterprise/Compliance Startups/Products
Maintenance You manage Zero

Quick Decision Guide

Self-hosted fits if:

  • You have compliance requirements (GDPR, HIPAA, eIDAS 2.0)
  • You need complete data sovereignty
  • You're an enterprise with existing infrastructure
  • You want to avoid vendor lock-in

Auth as a Service will fit (when available) if:

  • You need custom branding without running infrastructure
  • You're building a startup / product
  • You want API-first headless auth
  • You want to focus on your product, not identity plumbing

πŸ“š Documentation

Guides (start at the docs index):

  • MCP Quickstart β€” run QAuth + a mcp-guard-protected MCP server and complete the full OAuth handshake end-to-end
  • OAuth 2.1 Flow β€” every endpoint with copy-paste curl (PKCE, authorize, token, refresh, client_credentials, introspection)
  • Agent Authorization β€” the agent client type, RFC 8693 on-behalf-of delegation, scope modes, and step-up
  • API Reference β€” hand-written contract for /auth/*, /oauth/*, discovery, and /api/clients
  • Environment-Aware Authorization β€” the environment policy profile (dev/staging/prod) and environment-gated API keys
  • Browser Security β€” T3 hardening: security headers, CSRF, secure cookies, XSS-safe output
  • Observability β€” structured logging, /metrics, request-id, failed-login lockout
  • Code Examples β€” copy-paste Node/TS and browser (PKCE) clients
  • Docker Development Guide β€” local development with Docker

Reference:

Library documentation:

Planned documentation (future phases):

  • SDK Documentation (Phase 3)
  • Multi-tenancy Guide
  • Security Best Practices

🀝 Contributing

We welcome contributions! See our Contributing Guide.

πŸ“„ License

Apache License 2.0 β€” see LICENSE file for details.

Copyright Β© 2025–2026 QAuth Labs

πŸ”— Links


Note: This project is under active development. Core OAuth 2.1 / OIDC, MCP / AI-agent auth, the T3 production-hardening track (security headers, CSRF, secure cookies, OIDC conformance, observability), and the T5 environment-aware authorization posture (ADR-008) all ship today; the near-term roadmap is complete, and remaining work is the long-term platform (wallet federation + post-quantum signing, T4). Review the production configuration before deploying.

🀲 Acknowledgments

Inspired by: Keycloak, Ory, Auth0, Clerk, and Supabase Auth.

Standards and prior art this project builds on: OAuth 2.1 RFC 9700, OIDC Core 1.0, OID4VC, OID4VP, NIST FIPS 204 (ML-DSA), W3C DID v1.0.

Releases

No releases published

Packages

 
 
 

Contributors

Languages