Skip to content

Platform overview

The Vendidit auth platform is one identity service (Go) plus a family of consumer SDKs that let any browser app or backend service authenticate users against it. Tokens are short-lived HS256 JWTs that downstream services verify locally — no per-request network hop on the hot path.

Hosted services

URLWhat it is
new-auth.vendidit.comProduction auth-server (Go). API base: /api/v1. Health: /health.
auth-demo.vendidit.comLive demo + visual feature catalog. Every atom, form, and flow the browser SDK ships has a working page; the source under auth-client-demo/ is the canonical “how to integrate” reference.

The auth-server is the single source of truth for users, organizations, roles, permissions, sessions, and refresh tokens. Every SDK is either a typed wrapper around its HTTP surface or a way to validate the JWTs it issues.

Three layers, four runtimes

  • The serviceauth-server. Owns Postgres, Redis, the JWT signing secrets, the SSO state store, the audit log, EventBridge schedulers. Everything else is a client.
  • Browser sideauth-client (vanilla TS) + framework adapters (./react, ./preact, ./solid, ./vue, ./astro) + UI components (./preact/ui/{atoms,forms,flows}).
  • Backend side — backends pick one of the auth-server-* packages. TypeScript backends pick auth-server-nest (NestJS module) or auth-server-ts (vanilla TS core). PHP backends pick auth-server-laravel (Laravel adapter) or auth-server-php (vanilla PHP core).

All four TS packages share one type contract via auth-shared — a source-only package that mirrors the auth-server’s exact wire shape.

All nine packages

@vendidit/auth-server Go

The Go identity service. Owns users, orgs, roles, sessions, JWT signing. Single source of truth.

@vendidit/auth-shared TS types

Source-only TS package — JWT claims, principals, wire DTOs, error codes. Mirrors the server’s wire shape.

@vendidit/auth-client TS

Browser SDK — login, refresh-rotation, SSO/PKCE, 2FA, magic links. Framework adapters for React, Preact, Solid, Vue, Astro.

@vendidit/auth-client-demo Demo

Live integration reference at auth-demo.vendidit.com. 45 catalog pages plus full auth routes.

@vendidit/auth-server-ts TS

Framework-agnostic TS backend core. AuthClient facade, Flows, JwtValidator, HttpTransport, typed exception hierarchy.

@vendidit/auth-server-nest TS

NestJS adapter — module, guards, decorators. Wraps auth-server-ts. Ships Axios + Redis adapters out of the box.

@vendidit/auth-server-php PHP

Framework-agnostic PHP 8.1+ core. PSR-18 transport, PSR-16 cache, PSR-3 logger. Mirrors auth-server-ts.

@vendidit/auth-server-laravel PHP

Laravel adapter — VenAuth facade, middleware aliases, guard, Blade directives, HasVenAuth trait.

How a request flows

Browser sign-in → backend API call

  1. Browser app loads auth-client (configured with apiBaseUrl = the auth-server, and an appCode registered for that app).
  2. User submits <LoginForm>auth-client POSTs /auth/login → server returns { access_token, refresh_token, user, organizations, ... }.
  3. Tokens stored via the SDK’s TokenStore port (default: localStorage).
  4. Browser makes a request to its own backend API with Authorization: Bearer <access_token>.
  5. Backend (NestJS / Laravel / whatever) validates the JWT locally with one of the auth-server-* SDKs — checks signature against the shared JWT_ACCESS_SECRET, audience, issuer, expiry, and the per-user token-version cached in Redis. No round-trip to the auth-server on the hot path.
  6. Backend services consume the decoded principal (AuthenticatedUser or ServicePrincipal) — same shape across every SDK because they all import from auth-shared.

Service-to-service (m2m)

  1. Service A is registered with the auth-server as an m2m client via the /admin/m2m-clients route, given a client_id + client_secret.
  2. Service A calls /oauth/token with grant_type=client_credentials → gets a service-scoped access token (token_type: "service").
  3. Service A calls Service B with that bearer; Service B validates exactly the same way as a user token. The ServicePrincipal shape tells it this is an m2m call.
  4. ServiceAuthClient (in both TS + PHP cores) handles fetching + caching the m2m token automatically.

Refresh-token rotation

auth-client (browser) and the auth-server-* SDKs (backend) handle this automatically. Every refresh creates a new refresh-token row inheriting the parent’s family_id and revokes the parent. If a revoked token is ever presented again, the auth-server revokes the entire family (RFC 6819 §5.2.2.3 reuse detection) — the legitimate user has to re-auth.

Cross-cutting conventions

  • JWT secret: JWT_ACCESS_SECRET shared between the auth-server and every backend SDK consumer. Rotation supported via JWT_ACCESS_SECRET_PREVIOUS — validators try active first, fall back to previous on signature mismatch only.
  • Wire format: all timestamps are RFC 3339 ISO strings (e.g. "2026-05-15T17:52:56Z"), not Unix seconds. Money is decimal(10,2). Snake_case on the wire, camelCase only on normalized principals (AuthenticatedUser, ServicePrincipal).
  • App scoping: every login request carries an app_code identifying which consuming app. Tokens carry app_id + app_code claims. Backend SDKs can gate requests by app via middleware (vauth.app:auctions).
  • Permissions: resource:action strings (e.g. users:read, auctions:create). Each consuming service registers its permission manifest on boot via Flows.registerPermissions() / PermissionRegistrar.
  • Roles: system_admin (platform owner, bypasses every gate), super_admin (cross-org data ops), org_admin / org_manager / seller / buyer / org_member (org-scoped), base_user (anyone signed in).

Adding a new consumer

  • Browser app: npm install @vendidit/auth-client, wrap your app in <AuthProvider>, drop in <CompleteLoginFlow> or compose your own UI from the atoms / forms exports. See Browser quickstart.
  • NestJS backend: npm install @vendidit/auth-server-nest, register AuthClientModule.forRoot(...) in your AppModule. See NestJS quickstart.
  • Laravel backend: composer require vendidit/auth-server-laravel, publish config, set the guard, apply vauth middleware. See Laravel quickstart.
  • Anything else: depend on the framework-agnostic core (auth-server-ts for TS, auth-server-php for PHP) and build a thin adapter for your framework.

Next reads