Novolis Docs
novolis-security / design.md

Design

dotnetsecuritynovolis

Password hashing, encryption, HaveIBeenPwned helpers, an OAuth access-token mint, and a tenant authorization framework.

This is not a commercial Identity Provider. It is not Duende IdentityServer. Canonical positioning: what-this-is.md.

Published docs: https://novolis-platform.github.io/.github/novolis-security/

The end-state contract is REFACTORING_SPEC.md.

Layer placement

Follow library-boundaries for layer placement.

Goals

  • Keep public APIs documented and packable as Novolis.* on GitHub Packages.
  • Prefer BCL types and existing Novolis packages over parallel abstractions.
  • Document restore and ProjectReference-mode builds without local NuGet folder feeds.
  • Keep Authentication, OAuth, and Authorization as separate systems: sign-in, token mint, tenant authz.

Non-goals

  • Local NuGet folder feeds or committed cross-repo ProjectReference into sibling checkouts.
  • Avalonia package references outside Novolis.Avalonia.*.
  • Password grant, OpenID Connect, SAML, nested groups, or negative authorization rules.
  • A full Identity Provider product: ID Tokens as login, userinfo, federation, admin UI, consent UI, dynamic client registration, PAR, JAR, CIBA, Device Code, or Token Exchange.
  • Substituting for Duende IdentityServer, Keycloak, Auth0, Microsoft Entra ID, or similar commercial IdPs.

Packages

  • Novolis.Security.Cryptography
  • Novolis.Security.Encryption
  • Novolis.Security.HaveIBeenPwned
  • Novolis.Security.PasswordHashing
  • Novolis.Security.Secrets
  • Novolis.Security.Authentication.*
  • Novolis.Security.OAuth.*
  • Novolis.Security.OAuth.Client — outbound Novolis-issuer caller. One AddNovolisOAuthClient<TApi> registration per legal credential. Inject INovolisOAuthClient<TApi>. Refresh binds TStore to that client. Does not wrap Novolis.Http.Authentication.
  • Novolis.Security.Authorization.*

Credential store isolation

The credential vault is not a user directory.

  • Allowed on CredentialRecord: opaque CredentialReference, password hash, disabled flag, timestamps.
  • Forbidden on credential records: IdentityId, email, username, phone, display name, tenant, group, or role data.

IdentityId is the JWT subject. CredentialReference never becomes a public identifier.

ICacheStore is the product cache: in-memory for tests and a single process, replaced with a distributed store when more than one process shares lockout, MFA, or OAuth leases.

IMfaProvider is a product second factor. The library default is NoopMfaProvider.

Authorization

Authorization is tenant-scoped. Groups contain identities. Roles contain permissions. Composite roles contain roles and must remain acyclic.

OAuth scopes are not application permissions.

OAuth mints access tokens. Authorization decides tenant capabilities. Neither package is an IdP user directory or a replacement for IdentityServer.