Skip to content

Glossary

Terms in modgud and their counterparts in other identity systems.

Core terms

Realm

An isolated identity boundary. Each realm has its own PostgreSQL database (<master-db>_<slug>), its own users, roles, OAuth clients, and login providers.

Mapping to other systems:

modgudKeycloakAuth0Azure AD
RealmRealmTenantTenant (Directory)

The system realm is the first realm, created automatically on first boot. It starts as the Control-Plane realm — flagged IsControlPlane = true — meaning only its users may create further realms. Exactly one realm per deployment is the Control Plane.

The realm boundary is the domain (Host header), not the URL path. Realm acme lives under acme.example.com, the system realm under system.example.com or localhost.

User

A human or service account inside a realm. Users belong to exactly one realm. Identical usernames in different realms are different accounts.

In code: Modgud.Authentication.Domain.ApplicationUser (ASP.NET Core Identity user).

Group

An organisational unit. Groups have members (users or other groups) and carry PermissionRole references. Groups exist in two modes:

  • Manual — admin maintains the member list
  • Auto — a membership script determines members dynamically

See Auto membership.

PermissionRole

A named bundle of permissions. Binds to one App (or to the realm when IsRealmAdmin = true) and references a list of the App catalog's PermissionIds:

Name:          "User Manager"
AppId:         <modgud app id>
PermissionIds: [user:read, user:write]

Permission

A two-segment string <resource>:<action> inside an App's catalog — the App context is implicit from the catalog container. Examples: user:read (in the modgud app), invoice:write (in a billing app), realm:admin (realm-constant bypass). Permissions flow exclusively through groups:

User → Group → Role → Permission

Two bypass tiers: <resource>:admin (resource-wide within the calling app) and realm:admin (realm-wide emergency exit). See Permissions & gating for the full evaluator + UserInfo-emission story.

Session

A server-side record (UserSession Marten document) of an active login. Tracks IP, browser, OS, device type, LastActiveAt, ExpiresAt. Users can revoke their own sessions; admins can force-logout users. UAParser parses the user agent.


OAuth / OIDC terms

Client (OAuth application)

An external application that requests user logins or API access. Created per realm — the same client_id in realm A and realm B are different clients.

Configurable per client:

  • Client ID — public identifier (e.g. my-app)
  • Client Secret — private key (for confidential clients)
  • Redirect URIs — allowed callback URLs
  • Grant Types — which flows are allowed
  • Access Token Type — Reference (default) or JWT

Scope

A permission boundary that a client can request. Scopes appear in the token; resource servers decide based on the scopes whether the request is OK.

Default scopes (set per realm at realm provisioning):

  • openid — required for OIDC, returns the user ID
  • profile — first name, last name
  • email — email address
  • roles — role memberships
  • offline_access — enables refresh tokens

API (resource)

A protected backend API. Has an identifier (audience claim in the token) and a list of scopes it supports. In code: OAuthApiAggregate.

Grant Type

Grant TypeUse case
Authorization Code + PKCEWeb apps, SPAs, mobile apps
Client CredentialsMachine-to-machine, background services
Refresh TokenRenew expired access tokens

No Implicit, no ROPC

Modgud supports neither Implicit Flow nor Resource Owner Password Credentials (ROPC). Both are considered insecure and are deprecated in OAuth 2.1.

Token types

TypeWhat it is
Access TokenAccess to APIs. Reference (opaque, via introspection) or JWT (self-contained)
Identity TokenWho signed in — consumed by the client
Refresh TokenGet a new access token without a fresh login

Access token format

Configurable per client:

FormatHow it worksBest for
Reference (default)Opaque string. APIs validate via the introspection endpoint.SPAs, mobile, public clients — instant revocation.
JWTSelf-contained, signed token. APIs verify locally.Trusted backend services — no introspection roundtrip.

Which one when?

Reference tokens are the safe default. Revoke a reference token and it is dead immediately. JWTs cannot be revoked — they are valid until they expire. Use JWT only for trusted services where the introspection roundtrip gets in the way.


Login providers

An authentication method that users can use. A single LoginProvider aggregate per entry, with a Type discriminator. Configurable per realm.

TypeStatusDescription
InternalWired upBuilt-in username/password. Auto-seeded once per realm, marked IsBuiltIn=true, not editable from the admin UI.
OidcWired upExternal OIDC IdPs (Entra ID, Google, Auth0, ...). Authority + client ID + secret + UserUpdateScript.
Saml / Ldap / KerberosReservedEnum values exist; create endpoint rejects with LoginProvider.TypeNotSupported. The shape ships now so the FE doesn't have to add a "not supported yet" UI per type later.

Configured Oidc providers automatically show "Login with {Provider}" buttons in the login UI. Internal never produces an SSO button — it backs the local username/password form.


Terms in code

Term in codeTerm in docs/UIWhere
TenantIdRealm slugMarten/Wolverine, infrastructure layer
PrincipalUser or group or service accountAuthorization slice (polymorphic)
PersonUser read model in the authorization sliceA subclass of Principal
AggregateEvent-sourced entityDomain layer
*StateInline projection for sync consistencyInfrastructure layer
*ListReadModel / *DetailsReadModelAsync projection for read optimizationInfrastructure layer
LoginProviderLogin provider configuration (Internal / Oidc / ...)Authentication slice

"Realm" vs. "Tenant"

User-facing it is Realm everywhere. The code uses Tenant in the infrastructure layer (TenantId, ITenantSessionFactory, MasterTableTenancy), because that is what Marten and Wolverine call it. Same thing, two names.

Released under the Apache-2.0 License.