Architecture
System Overview
CRED Auth acts as the centralized identity provider for the CRED platform. It issues JWT access tokens and ID tokens that are consumed by downstream services (cred-api-commercial, cred-agent, MCP server, etc.).
flowchart TB
subgraph auth["CRED Auth"]
direction TB
subgraph controllers["HTTP Controllers"]
WK["Well-Known Controller<br/>.well-known/*"]
AC["Auth Controller<br/>/auth/*"]
APP["App Controller<br/>GET /"]
end
subgraph oidc["OIDC Provider โ nest-oidc-provider"]
EP["/oauth/auth ยท /oauth/token ยท /oauth/jwks ยท /oauth/reg<br/>/oauth/me ยท /oauth/token/introspection ยท /oauth/token/revocation"]
end
subgraph services["Services"]
IC["Interaction Controller<br/>/login/:uid/*"]
US["Users Service<br/>Knex โ User"]
JWT["JWT Service<br/>HS256 / RS256"]
end
subgraph db["PostgreSQL โ Knex"]
TABLES["User table ยท OAuthPayload table"]
end
subgraph sec["Security Layer"]
GUARDS["ThrottlerGuard ยท CsrfGuard ยท Helmet ยท ValidationPipe"]
end
controllers --> oidc --> services --> db
end
Core Modules
App Module (src/app.module.ts)
Root module that composes all feature modules. Imports ConfigModule.forRoot() for environment variable access.
OIDC Module (src/oidc/)
The heart of the authorization server. Wires oidc-provider into NestJS via nest-oidc-provider.
| Component | File | Purpose |
|---|---|---|
| OidcConfigService | oidc.config.service.ts |
Builds the full oidc-provider Configuration โ adapter, cookies, JWKS, TTLs, features, claims, findAccount, PKCE policy |
| WellKnownController | well-known.controller.ts |
Serves /.well-known/openid-configuration, oauth-authorization-server, and oauth-protected-resource |
| InteractionController | interactions/interaction.controller.ts |
Login/consent UI โ GET /login/:uid, POST submit/confirm/abort |
| InteractionService | interactions/interaction.service.ts |
Validates credentials, loads interaction details, finishes login/consent/abort via provider.interactionFinished |
| KnexAdapter | adapters/knex.adapter.ts |
oidc-provider persistence adapter โ stores sessions, tokens, clients, grants in the OAuthPayload table |
| OidcErrorLoggerService | oidc-error-logger.service.ts |
Provider event listeners, proxy configuration, custom redirect URI rules for MCP desktop schemes |
Auth Module (src/auth/)
REST-based JWT authentication for direct API access (separate from OIDC flows).
| Component | File | Purpose |
|---|---|---|
| AuthController | auth.controller.ts |
POST /auth/login (get JWT), GET /auth/me (get profile) |
| AuthService | auth.service.ts |
Thin wrapper around UsersService for Passport |
| JwtService | jwt.service.ts |
Sign/verify JWTs โ auto-detects HS256 (JWT_SECRET) or RS256 (OAUTH_JWKS_PRIVATE_KEY) |
| LocalStrategy | strategies/local.strategy.ts |
Passport local strategy (email + password) |
| JwtAuthGuard | guards/jwt-auth.guard.ts |
Bearer token verification guard |
Users Module (src/users/)
| Component | File | Purpose |
|---|---|---|
| UsersService | users.service.ts |
Queries the "User" table via Knex. Provides findByEmail, findById, validateCredentials (bcrypt, timing-safe). Rejects inactive users. |
Database Module (src/database/)
| Component | File | Purpose |
|---|---|---|
| KnexModule | knex.module.ts |
Global module providing KNEX_CONNECTION token. Connects to PostgreSQL via DB_CONNECTION with optional DB_SSL support. |
Security Module (src/security/)
| Component | File | Purpose |
|---|---|---|
| SecurityModule | security.module.ts |
Global module โ registers ThrottlerGuard as APP_GUARD, exports CsrfService and CsrfGuard |
| CsrfService | csrf/csrf.service.ts |
Stateless HMAC-signed CSRF tokens with secret rotation support |
| CsrfGuard | csrf/csrf.guard.ts |
Validates _csrf body field or X-CSRF-Token header; session ID from route :uid or X-Session-Id |
| Throttle Decorators | decorators/throttle.decorator.ts |
@ThrottleLogin, @ThrottleApi, @ThrottleRelaxed, @ThrottleDiscovery |
Project Structure
src/
โโโ main.ts # Bootstrap (Helmet, CORS, ValidationPipe, HBS, trust proxy)
โโโ app.module.ts # Root module
โโโ app.controller.ts # GET / โ service metadata
โโโ auth/
โ โโโ auth.module.ts
โ โโโ auth.controller.ts # POST /auth/login, GET /auth/me
โ โโโ auth.service.ts
โ โโโ jwt.service.ts # JWT sign/verify (HS256 or RS256)
โ โโโ dto/login.dto.ts
โ โโโ guards/jwt-auth.guard.ts
โ โโโ strategies/local.strategy.ts
โโโ database/
โ โโโ knex.module.ts # Global Knex connection
โโโ oidc/
โ โโโ oidc.module.ts # OidcModule.forRootAsync
โ โโโ oidc.config.service.ts # Full oidc-provider Configuration
โ โโโ well-known.controller.ts # Discovery endpoints
โ โโโ oidc-error-logger.service.ts
โ โโโ adapters/
โ โ โโโ knex.adapter.ts # oidc-provider DB adapter
โ โโโ interactions/
โ โโโ interaction.controller.ts
โ โโโ interaction.service.ts
โ โโโ dto/
โโโ security/
โ โโโ security.module.ts # ThrottlerGuard + CSRF
โ โโโ csrf/
โ โ โโโ csrf.service.ts
โ โ โโโ csrf.guard.ts
โ โโโ decorators/
โ โ โโโ throttle.decorator.ts
โ โโโ index.ts
โโโ users/
โโโ users.module.ts
โโโ users.service.ts
views/
โโโ layouts/main.hbs # Base layout
โโโ login.hbs # Login/consent page
โโโ error.hbs # Error page
JWT Signing Strategy
CRED Auth supports two JWT signing methods, auto-detected at startup:
| Priority | Method | Algorithm | When Used | Compatible With |
|---|---|---|---|---|
| 1 | JWT_SECRET |
HS256 | Symmetric shared secret | cred-api-commercial (same secret) |
| 2 | OAUTH_JWKS_PRIVATE_KEY |
RS256 | Asymmetric RSA key pair | Any service verifying via JWKS endpoint |
Both the REST /auth/login endpoint and the OIDC access token flow use the same signing configuration, ensuring all tokens issued by the server are verifiable through a single code path.
Note
When JWT_SECRET is set, it takes precedence. OIDC ID tokens are always signed with RS256 from the JWKS keystore regardless of this setting.
Data Flow: Authorization Code + PKCE
sequenceDiagram
participant C as Client
participant A as CRED Auth
participant DB as PostgreSQL
C->>A: GET /oauth/auth + PKCE challenge
A->>DB: Store Interaction
A-->>C: 302 โ /login/:uid
C->>A: GET /login/:uid
A-->>C: HTML (login form)
C->>A: POST /login/:uid/submit + email, password, _csrf
A->>DB: Validate credentials
DB-->>A: User record
A->>DB: Store Grant
A-->>C: 302 โ /callback?code=โฆ
C->>A: POST /oauth/token + code + code_verifier
A->>DB: Verify code + PKCE
A-->>C: access_token, id_token, refresh_token