eetr-auth
Architecture

System overview

Packages, layers, Cloudflare bindings, and the authentication flows that make up eetr-auth.

eetr-auth is a Cloudflare-native OAuth 2.1 + OpenID Connect authorization server packaged as an npm monorepo. It is designed to run entirely on Cloudflare's edge platform with no traditional server infrastructure.

Monorepo packages

Layered internal architecture

apps/auth keeps a strict separation between entry points, business logic, and persistence:

src/
├── app/                    # Next.js App Router
│   ├── api/                # REST API routes (OAuth, users, admin)
│   └── (auth|admin)/       # UI pages (login, dashboard)
└── lib/
    ├── services/           # Business logic
    ├── repositories/       # Data access layer (D1 implementations)
    ├── auth/               # Auth utilities (JWT, HMAC, cookies)
    ├── config/             # Runtime config readers
    ├── context/            # Dependency injection registry
    ├── crypto/             # Cryptographic primitives
    └── db/                 # D1 connection helper

Routes and server actions only wire context and call services; services hold all business logic and depend on repositories; repositories do persistence only. The full rules — including how to add new code — are in Layer conventions.

Cloudflare bindings

BindingTypePurpose
DBD1 DatabaseAll persistent data (users, tokens, clients, etc.)
AUTH_ASSETSR2 BucketUser avatars, site logo, JWKS JSON
IMAGESImages APICloudflare image optimization
ASSETSStatic AssetsOpenNext-compiled static files
WORKER_SELF_REFERENCEService BindingInternal self-calls for routing/caching
ARGON_HASHERService BindingPassword hash/verify operations

Authentication flows

Authorization Code + PKCE (S256)

Token refresh (rotation)

Client credentials

Infrastructure & deployment order

Terraform provisions D1 + R2 and emits outputs that are rendered into the gitignored wrangler.generated.jsonc. Deployment always follows this order:

argon-hasher must be deployed before apps/auth, because the auth Worker reaches it through the ARGON_HASHER service binding at startup.

On this page