Identity

Blouppy.Identity is the Starter's own OAuth 2.0 / OpenID Connect server, built on OpenIddict and ASP.NET Identity. It is a separate ASP.NET Core application, with its own Razor pages and its own hexagon: it references nothing of the API's.

What it handles

  • Accounts — registration with e-mail confirmation, password reset, TOTP two-factor with recovery codes, GitHub and Google sign-in, a Cloudflare Turnstile CAPTCHA on the anonymous forms, and a rate limit per address on them.
  • The protocol — /connect/authorize, /connect/token, /connect/revocation, /connect/userinfo, /connect/endsession, /connect/introspect, and the key set at /.well-known/jwks.
  • Personal access tokens — blp_pat_ reference tokens, minted here and introspected by the API (see MCP and access tokens).
  • Single sign-on and SCIM — organizations' verified domains, their OpenID Connect connections and the SCIM 2.0 endpoint (see SSO and SCIM).

How it is put together

ConcernWhere
StorageOne context, ApplicationDbContext: ASP.NET Identity's tables and OpenIddict's applications, authorizations, scopes and tokens
ClientsDeclared in code (Server/ServerConfiguration.cs) and brought in line on every start by ApplicationRegistrar — they are configuration, not sample data
Signing and encryption keysCreated on first start and stored in server_keys, protected by Data Protection, so every replica signs with the same key and a restart invalidates nothing. Certificates you provide can replace them
ClaimsRebuilt from the account at every sign-in and refresh (Server/UserPrincipalFactory)
Old tokensPruned every hour by TokenPruning: tokens and authorizations nobody can use any more, after 14 days

The tokens the API sees

  • The gateway's access token — a JWT signed with the server's RSA key, valid 15 minutes, audience blouppy_api. The API validates it with ASP.NET Core's JWT handler.
  • Its refresh token — encrypted, readable only by the identity host, valid 14 days.
  • A personal access token — a reference token: the API asks the identity host about it (introspection) and caches the answer for a minute.

Where the user's profile lives

The name, e-mail and avatar belong to the identity host. The application database reads them through a projection, users_view, which is why no application domain owns them and why the read side can join a member's name in the same query.

Sign-in pages

The pages — login, registration, two-factor, password reset, SSO sign-in — share one layout, Pages/Shared/_AuthLayout.cshtml, styled with the design system's tokens. The stylesheet is the Tailwind CLI's output, committed so the host builds without Node:

cd back/Blouppy.Identity && npm ci && npm run build:css