This repository handles authentication and token issuance in the three-layer separation of concerns (authentication & token issuance / authorization decision / authorization enforcement) of the auth stack.
OAuth 2.0 / OIDC provider. Issue JWTs via session-based login or the authorization code flow — same token format, same introspection endpoint, same downstream verification.
- Modular composition — Pick only the modules you need. Skip session, federation, or authorization code for API-only deployments.
- JWT algorithm selection — EdDSA (default), ES256, RS256, HS256. The default is asymmetric, so the JWKS endpoint (
/.well-known/jwks.json) publishes a real verification key and relying parties never hold one that can also mint tokens. HS256 stays selectable and publishes no JWKS. - OAuth 2.0 compliance — Authorization code flow with PKCE (RFC 7636), token introspection (RFC 7662), refresh tokens
- Session authentication — Local username/password login + OAuth federation (Google, GitHub, and custom providers via per-federation
defineModule(...)modules) - Rate limiting — Per-endpoint configurable limits
- HOCON configuration — Type-safe config with Zod validation and environment variable overrides
npx @o3co/create-auth-provider my-auth-app
cd my-auth-app
pnpm install
pnpm build┌──────────────────────────────────────────┐
│ Composition Root │
│ (standalone template or your own app) │
├─────────┬───────────┬────────────────────┤
│ oauth │ session │ foundation │
│ /oauth │ /session │ HTTP user │
│ routes │ routes │ adapter │
├─────────┴───────────┴────────────────────┤
│ core │
│ Module system · KeyStore · Repositories │
└──────────────────────────────────────────┘
- core — Interfaces, config schemas, token service, app factory. Always required.
- oauth — OAuth routes (
/oauth/token,/oauth/authorize,/oauth/introspect). Required for any token issuance. - session — Session login + provider-registered OAuth federation. Optional — skip for API-only deployments.
- federation-google / federation-github — Concrete OAuth federation providers. Optional — install only the providers you register.
- foundation — Production HTTP user-authentication adapter (client of "the Store"). Optional.
- webauthn / dpop / mtls / oauth-token-exchange / device-grant / redis — Optional capability and adapter modules; see Packages.
| Package | npm | Description |
|---|---|---|
packages/core |
@o3co/auth-provider-core |
Core abstractions all other packages build on: module system, token service, repository interfaces, config schemas |
packages/oauth |
@o3co/auth-provider-oauth |
OAuth 2.0 routes module: /oauth/token, /oauth/authorize, /oauth/introspect |
packages/oauth-token-exchange |
@o3co/auth-provider-oauth-token-exchange |
RFC 8693 Token Exchange grant — on-behalf-of, delegation (act), scope/audience narrowing |
packages/device-grant |
@o3co/auth-provider-device-grant |
RFC 8628 Device Authorization Grant — the device-code flow for TVs, CLIs and IoT |
packages/session |
@o3co/auth-provider-session |
Session and federation routes module: login, logout, OAuth 2.0 federation |
packages/webauthn |
@o3co/auth-provider-webauthn |
Passkey (WebAuthn) credential lifecycle + authentication grant, AS-scope only |
packages/dpop |
@o3co/auth-provider-dpop |
DPoP (RFC 9449) sender-constrained access tokens |
packages/mtls |
@o3co/auth-provider-mtls |
mTLS (RFC 8705) sender-constrained access tokens |
packages/federation-google |
@o3co/auth-provider-federation-google |
Google federation provider |
packages/federation-github |
@o3co/auth-provider-federation-github |
GitHub federation provider |
packages/redis |
@o3co/auth-provider-redis |
Redis-backed adapters and defineModule manifests |
packages/foundation |
@o3co/auth-provider-foundation |
Production HTTP user-authentication adapter ("the Store" client) |
templates/standalone |
— | Deployable server template (composition root) |
create-app |
@o3co/create-auth-provider |
CLI scaffolder |
| Endpoint | Module | Description |
|---|---|---|
POST /oauth/token |
oauth | Token issuance (session, authorization code, refresh) |
GET /oauth/authorize |
oauth | Authorization code flow (PKCE) |
POST /oauth/introspect |
oauth | Token introspection (RFC 7662) |
GET /.well-known/jwks.json |
core | JWKS endpoint (asymmetric algorithms only) |
GET /session/csrf |
session | Issue a double-submit CSRF token |
POST /session/login |
session | Local authentication |
POST /session/logout |
session | Session destruction |
GET /_healthcheck |
core | Health check |
HOCON config file with environment variable overrides. The config schema depends on which modules are registered:
Core (always required):
http { port = 3000 }
oauth {
jwt {
# Required. Canonical issuer stamped as `iss` on every minted token:
# absolute https URL (http only for a loopback host), no query or fragment.
# Boot fails when unset — it is never derived from the Host header.
issuer = ${?OAUTH_JWT_ISSUER}
signingKey {
provider = "local" # "local" is the only built-in; extend via KeyStoreFactory
local {
# Default. Asymmetric, so /.well-known/jwks.json publishes a real
# verification key and no relying party ever holds a key that can
# also MINT tokens. Required — there is no key-material default:
# openssl genpkey -algorithm ed25519 -out jwt-private.pem
# openssl pkey -in jwt-private.pem -pubout -out jwt-public.pem
algorithm = "EdDSA" # EdDSA | ES256 | RS256 | HS256
privateKeyPath = ${?OAUTH_JWT_PRIVATE_KEY_PATH}
publicKeyPath = ${?OAUTH_JWT_PUBLIC_KEY_PATH}
# HS256 instead: set algorithm = "HS256" and supply a secret of at
# least 32 bytes (`openssl rand -hex 32`). No JWKS is published.
# secret = ${?OAUTH_JWT_SECRET}
}
}
}
accessToken { expiresIn = 3600 } # seconds, positive, <= 1 year
refreshToken { expiresIn = 86400 } # seconds, positive, <= 1 year
}Authorization code grant (when oauthAuthorizationModule is registered):
oauth.grants.authorization_code {
pkce {
requireS256 = false # Set to true to reject plain code_challenge_method (S256 only)
requireS256 = ${?OAUTH_GRANTS_AUTHORIZATION_CODE_PKCE_REQUIRE_S256}
}
}Session (when sessionModule is registered):
# `secret` signs the cookie that IS the authenticated session: at least
# 32 bytes (256 bits), e.g. `openssl rand -hex 32`.
session { secret = ${SESSION_SECRET} }
# Shorthand: key name = provider type (google, github, or any registered custom type)
federations {
google {
enabled = false
# clientId, clientSecret, callbackURL — required when enabled = true
}
# github { enabled = false }
}See templates/standalone/config/application.conf for a complete example.
pnpm install
pnpm -r build # build all packages
pnpm -r test # test all packagesnpx @o3co/create-auth-provider my-auth-app
cd my-auth-app
docker build -t my-auth .- auth.policy-verifier — ABAC policy engine for authorization decisions
- auth.proxy — Token validation reverse proxy
- protobuf.interceptors — protobuf-option-driven authorization interceptors for gRPC / ConnectRPC (calls auth.provider for introspection, auth.policy-verifier for authorization)
- auth — Architecture docs and E2E tests
Apache License 2.0 — Copyright 2026 1o1 Co. Ltd.