Understanding Authentication And Authorization in Mindbricks
Mindbricks is an AI-powered, pattern-based backend microservice code generator. This document aims to guide human or AI architects* in designing applications on Mindbricks with authentication and authorization capabilities. It is recommended to read this document alongside the Mindbricks Pattern documentation, especially for the referenced patterns.
*Architect refers to either AI agents or human users of Mindbricks, including product managers, business analysts, and software architects.
Throughout this document, the term "architect" will be used interchangeably for both without further distinction.
Mindbricks Authentication Module
While a Mindbricks project consists primarily of service modules, it also includes several core modules that must or can be defined to enable common functionalities. One such core module is the Authentication module, which governs authentication and authorization behavior across all Mindbricks services, particularly the auth service — a service automatically generated by Mindbricks based on this module's configuration.
Human architects can access and configure this module by opening the Authentication menu in the project sidebar, loading each chapter, and setting the relevant options. Most chapters of the Authentication module will be covered in this document; however, for a pattern-based understanding, you should also refer to the Mindbricks Patterns documentation, specifically the ProjectAuthentication pattern.
AI agents should populate the authentication module's settings according to the pattern definitions and the guidelines provided here.
Although the Authentication module primarily manages authentication and authorization behavior, certain settings might still need to be configured within individual service modules.
The ProjectAuthentication pattern structure
From the ontology, the ProjectAuthentication pattern is defined as:
{
"ProjectAuthentication": {
"authenticationEssentials": "AuthBasics",
"loginDefinition": "LoginDefinition",
"verificationServices": "VerificationServices",
"accessControl": "AccessControl",
"socialLogins": "SocialLoginSettings",
"userProperties": ["DataProperty"],
"tenantProperties": ["DataProperty"]
}
}
Mindbricks Services and the auth Service
While most business logic and data management in Mindbricks are handled through services designed by architects, some core functionalities are bundled into automatically generated services based on project settings — the auth service is one of them.
Once you activate the Authentication module and complete the necessary configuration, Mindbricks ensures that the application design and the generated codebase include a microservice named auth.
The auth service provides and manages the following functionalities:
-
User and user data management
-
User group management
-
Login and logout operations
-
Verification services
-
Role management (RBAC)
-
Permission management (PBAC) and advanced access control
-
Multi-tenancy management
Important:
Architects should not attempt to redesign these features in additional modules unless they have a specific advanced requirement.
Even though you technically could reimplement all these behaviors manually, it is strongly recommended to rely on the factory-provided `auth` service.
This ensures that Mindbricks can automatically handle related flows across other services, saving time and reducing potential errors.
How You Can Extend Auth Functionality
-
Through Configuration Settings You can customize or extend authentication behavior by modifying settings within the Authentication module. For example, you can add extra user or tenant properties, define custom roles, and configure permissions directly via settings.
-
Through Additional Services Although it's ideal to stick to the
authservice for authentication-related processes, you can design additional services to extend behavior. For example, if your user data model is distributed across multiple complex objects (tables, in conventional terms), you can create an extra service (e.g.,userProfile) and link it to the users in the auth service using theuserId.
User and User Data Management
When the auth service is created, a default user data object is automatically included in its service definition. Thus, once the auth service is active, you can always reference the user data object from anywhere within other services.
The user object comes with several system-defined properties — some mandatory, some optional. Additionally, architects can add custom properties, similar to how they design data objects in other Mindbricks services.
user Data Object Properties (System-owned)
Mindbricks automatically generates the following system properties for the user object (some of these are explicitly described in patterns; others are part of the auth service's internal design):
-
idA unique identifier (UUID) for each user. Like all other Mindbricks data objects, theidfield is automatically included.-
Appears in objects like session as
userId. -
Other data objects will reference the user with
userId.
-
-
emailRepresents the user's email address.- When
primaryLoginIdentifieris'email'(the default), email serves as the primary username for login and is always required. - When
primaryLoginIdentifieris'mobile', email presence depends on thesecondaryIdentifierPresencesetting ('none','optional', or'required'). - When
primaryLoginIdentifieris'emailOrMobile', email is always present and can be used for login. - Also used for communication, notifications, and verification flows.
- When
-
passwordStores the user's password securely.- Passwords are hashed (and salted) using a one-way algorithm — they are never stored in plain text.
-
emailVerifiedIndicates whether the user's email address has been verified.Even if email verification is optional in your application, this field exists. To require email verification before login, configure:
{ "authentication": { "loginDefinition": { "userSettings": { "emailVerificationRequiredForLogin": true } } } }If email verification is required, the frontend will receive an
EmailVerificationNeedederror when the user tries to log in with an unverified email. The frontend must then trigger the email verification flow (see Verification Services). -
Naming Properties
User names can be stored either as a single full name or as a name–surname pair, configurable via
userNameType. The ontology defines this as an enum:UserNameTypewith values"asFullname"or"asNamePair".{ "authentication": { "loginDefinition": { "userSettings": { "userNameType": "asFullname" } } } }-
name: First (and middle, if any) name when using a name pair. -
surname: Family name when using a name pair. -
fullname: Full name when using the full-name model.
When using the name–surname model, the session will also auto-generate a `fullname` field by combining the two. -
-
avatarA URL pointing to the user's avatar image.-
The auth service only stores the URL — it does not manage uploads.
-
Image uploading should be handled by the client (e.g., using the Mindbricks Bucket Service).
To enable auto-generation of avatars, use the
userAutoAvatarScriptfield defined inLoginDefUserSettings. This is an MScript that returns a URL string. The default in the ontology is:{ "authentication": { "loginDefinition": { "userSettings": { "userAutoAvatarScript": "`https://gravatar.com/avatar/${LIB.common.md5(this.email ?? 'nullValue')}?s=200&d=identicon`" } } } }You can customize this script to use your own avatar service, as long as it remains a valid MScript expression.
-
-
roleIdStores the user's assigned role or roles when Role-Based Access Control (RBAC) is enabled.Enabling RBAC is done via
AccessControl.roleSettings.rbacIsActive(see Role Management (RBAC)).-
Internally, role values are stored as type
Any(theRoleItem.valueis of typeAny). That means you can use strings ("admin") or numbers (1) depending on your preference. -
When
usersHaveMultipleRolesis enabled,roleIdis treated as an array.
-
-
mobile(conditional) Represents the user's mobile phone number, stored in E.164 format (e.g.+905551234567). The backend automatically normalizes mobile numbers to E.164 format (+ followed by country code and subscriber number, no spaces or dashes) before storing. The mobile field is present in the user data model when:primaryLoginIdentifieris'mobile'(mobile is the primary login field), orprimaryLoginIdentifieris'emailOrMobile'(both identifiers are supported), orprimaryLoginIdentifieris'email'andsecondaryIdentifierPresenceis'optional'or'required'
When
primaryLoginIdentifieris'email'andsecondaryIdentifierPresenceis'none'(the default), the mobile field is not included in the user data model.{ "authentication": { "loginDefinition": { "userSettings": { "primaryLoginIdentifier": "mobile", "secondaryIdentifierPresence": "optional" } } } } -
mobileVerified(conditional) Indicates whether the user's mobile number has been verified. This field exists only when the mobile field is present in the user data model. To require mobile verification for login:{ "authentication": { "loginDefinition": { "userSettings": { "mobileVerificationRequiredForLogin": true } } } }The corresponding verification flow is configured under
verificationServices.mobileVerification.
The Tenant ID Property in the user Object (for Multi-Tenant Apps)
In multi-tenant applications, users belong to specific tenants, and login identifier uniqueness is tenant-scoped (email when email is primary, mobile when mobile is primary, or both when using dual identifiers).
The tenant ID field name depends on your tenant naming settings. For example:
-
clientIdif the tenant is named"client" -
storeIdif the tenant is named"store"
Multi-tenancy is activated with:
{
"authentication": {
"loginDefinition": {
"tenantSettings": {
"useMultiTenantFeature": true,
"configuration": {
"tenantName": "client"
}
}
}
}
}
When this is active, the Mindbricks generators ensure that:
-
The
userobject is tenant-scoped (tenant ID added). -
Other tenant-aware objects also include the tenant ID field.
For a complete understanding of multi-tenancy, see Multi Tenancy Management.
Custom user Data Properties
You can freely add custom properties to the user object, provided their names do not conflict with system-defined fields.
In the ontology, ProjectAuthentication.userProperties is an array of DataProperty definitions.
{
"authentication": {
"userProperties": [
{
"basicSettings": {
"name": "sex",
"type": "Enum",
"isArray": false,
"description": "The sex value of the user.",
"isRequired": true,
"allowUpdate": true,
"requiredInUpdate": false,
"allowAutoUpdate": true,
"autoIncrement": false,
"hashed": false,
"enumOptions": ["male", "female"],
"defaultValues": {
"default": "male",
"defaultInUpdate": null
}
},
"indexSettings": {
"indexedInElastic": true,
"indexedInDb": false,
"unique": false,
"clusterInRedis": false,
"cacheSelect": false,
"isSecondaryKey": false,
"fulltextSearch": false
}
}
]
}
}
Human architects can add these properties in the User Properties section under the Authentication module UI, while AI agents should populate them directly in JSON.
Super Admin Account
When the application is deployed, Mindbricks automatically creates a Super Admin account in the user table of the auth service. This account holds absolute authority, granting full access and control across the system.
The Super Admin role is internally recognized as superAdmin. The credentials are configured under LoginDefUserSettings:
{
"authentication": {
"loginDefinition": {
"userSettings": {
"superAdminIdentifier": "super.admin@myproject.com",
"superAdminPassword": "yourPassword"
}
}
}
}
If you omit superAdminIdentifier, the default is "admin@admin.com". When primaryLoginIdentifier is "mobile", this should be a mobile number in E.164 format (e.g. "+905551234567"). The default password is "superadmin", as defined in the pattern defaults.
When the secondary identifier field is required (i.e. secondaryIdentifierPresence is "required" or dualIdentifierRegistration is "both"), the Super Admin is seeded with a placeholder value for the secondary field: "noreply@system.local" for email, "+10000000000" for mobile. These placeholders satisfy the NOT NULL constraint and should be replaced by the administrator after first login.
Automatic Correction for Mobile-Primary Projects
When primaryLoginIdentifier is "mobile" and superAdminIdentifier is still the default value "admin@admin.com", Mindbricks automatically replaces it with "+10000000001" during configuration validation. This prevents a broken first-login experience, since the login system only queries the mobile column when mobile is the primary identifier — an email address stored in the mobile field would never match.
If a custom email address (anything other than "admin@admin.com") is provided as superAdminIdentifier when primaryLoginIdentifier is "mobile", Mindbricks raises a validation error and requires you to set a proper mobile number in E.164 format.
First Login After Deployment
The login endpoint (POST /login) accepts a username field. The lookup is always performed against the primary identifier column only: the email column when email is primary, the mobile column when mobile is primary, or auto-detected based on input format when emailOrMobile. Passing an email address as username when mobile is the primary identifier will not match any user, even if the user has an email stored in the database.
The following table shows the default Super Admin credentials for each configuration:
primaryLoginIdentifier | Default superAdminIdentifier | Login username value | How it is stored |
|---|---|---|---|
"email" (default) | "admin@admin.com" | admin@admin.com | email field |
"mobile" | Auto-corrected to "+10000000001" | +10000000001 | mobile field |
"emailOrMobile" | "admin@admin.com" | admin@admin.com | email field (email preferred in dual mode) |
The default password is always "superadmin" unless overridden via superAdminPassword.
Setting Custom Data for Super Admin
If your project defines additional custom user properties, Mindbricks allows you to prepopulate these fields for the Super Admin account as well.
The ontology defines superAdminData as an array of DataMapItem. For example:
{
"authentication": {
"loginDefinition": {
"userSettings": {
"superAdminData": [
{
"name": "age",
"value": "25"
},
{
"name": "instagramName",
"value": "`myProjectOfficial`"
}
]
}
}
}
}
Each value is MScript, so you can also use expressions if needed.
If a value for a required custom property is missing, Mindbricks will:
- Use the field's default value (if defined), or
- Leave it null (only if nulls are allowed).
User Registration
User registration in the auth service can be configured to be public or restricted.
-
Public registration allows anyone to create an account without prior authorization.
-
Restricted registration means only administrators (with appropriate admin roles/permissions) can create user accounts.
Control this behavior via:
{
"authentication": {
"loginDefinition": {
"userSettings": {
"userRegisterIsPublic": true
}
}
}
}
When `userRegisterIsPublic` is true, the POST /users API endpoint can be accessed without an access token.
Mindbricks automatically applies rate limiting and anti-bot protections to mitigate abuse.
When `userRegisterIsPublic` is false, the POST /users API requires an authenticated admin-level session.
User Group Management
The Mindbricks auth service supports user grouping, allowing architects to organize users into logical groups. This is particularly useful for permission management, but it can also support other group-based business logic across services.
-
A user can belong to zero, one, or multiple groups.
-
Only users with admin-level access can create user groups and assign users to them.
Groups are activated via LoginDefUserSettings.userGroupsActive:
{
"authentication": {
"loginDefinition": {
"userSettings": {
"userGroupsActive": true
}
}
}
}
When userGroupsActive is true, the auth service automatically includes two additional data objects (at code-generation level):
-
userGroup -
userGroupMember
userGroup Data Object Properties (System-owned)
The userGroup data object stores metadata about each user group. System-created properties typically include:
-
idUUID representing the unique identity of the user group. -
groupNameThe name of the group, which will be shown in the application's UX. -
avatarA public URL pointing to the group's avatar image.
As with user avatars, the auth service does not upload or store image binaries, only URLs.
You can configure auto-generated group avatars using the userGroupAutoAvatarScript field in LoginDefUserSettings. The default is also based on Gravatar:
{
"authentication": {
"loginDefinition": {
"userSettings": {
"userGroupAutoAvatarScript": "`https://gravatar.com/avatar/${LIB.common.md5(this.groupName ?? 'nullValue')}?s=200&d=identicon`"
}
}
}
}
userGroupMember Data Object Properties (System-owned)
This implicit data object manages the relationships between users and groups — each record represents one membership. System properties include:
-
idA UUID representing this specific user–group membership (useful when removing a user from a group). -
groupIdThe ID of the group. -
userIdThe ID of the user. -
ownerIdThe ID of the admin user who created this membership record, automatically populated from the current session.
Tenant-Level Grouping
In multi-tenant applications, you can choose whether user groups are tenant-scoped or global:
-
Tenant-level groups: Created and visible only within the tenant that owns them. Only tenant admins can manage them.
-
SaaS-level (global) groups: Visible across tenants. Created and managed by SaaS-level admins (e.g.,
superAdmin). Tenant admins can assign users to these global groups but cannot create or delete them.
This behavior is controlled via userGroupsInTenantLevel:
{
"authentication": {
"loginDefinition": {
"userSettings": {
"userGroupsInTenantLevel": true
}
}
}
}
When this is enabled, a tenant ID field (e.g., clientId, storeId) is also added to userGroup and userGroupMember objects.
Login Management
The Mindbricks auth service supports multiple login methods, including:
-
Native identifier/password login (email/password, mobile/password, or either depending on
primaryLoginIdentifier) -
Social logins (Google, Apple, GitHub, GitLab)
-
SSO (Single Sign-On) via external identity providers
-
(Optionally) Remote service authentication
Each login method ultimately integrates with the same authentication flow, issuing a JWT token upon success. This token is used for subsequent request authentication.
Login Identifier Model
The primaryLoginIdentifier setting in LoginDefUserSettings determines which field users provide to log in:
email(default) — Users log in with email and password.mobile— Users log in with mobile number and password (WhatsApp-style). Mobile numbers are stored and matched in E.164 format.emailOrMobile— Users can log in with either email or mobile, plus password. Both fields exist in the data model.
When the primary identifier is email or mobile, the non-primary identifier (the "secondary") is controlled by secondaryIdentifierPresence:
'none'— The secondary field is not stored at all.'optional'— The secondary field exists but is not required during registration.'required'— The secondary field must be provided during registration.
When primaryLoginIdentifier is emailOrMobile, the dualIdentifierRegistration setting controls registration:
'atLeastOne'— Users must provide at least one identifier (email or mobile) during registration.'both'— Users must provide both email and mobile during registration.
Login via Identifier and Password
The most common login method is via the primary identifier and password. This uses JWT-based authentication, which is configured under authenticationEssentials.JWTAuthentication. JWT auth is enabled by default in the patterns.
{
"authentication": {
"authenticationEssentials": {
"JWTAuthentication": {
"useJWTForAuthentication": true,
"configuration": {
"tokenPeriodInDays": 30,
"keyRefreshPeriodInDays": 150
}
}
}
}
}
Mindbricks creates a JWT access token after successful login, which is then used to authenticate subsequent requests — either via cookie or the Authorization header.
Login is typically handled via:
POST /login
If login is successful:
-
A session object is returned in the response.
-
A JWT token is issued.
-
For browser clients, a secure cookie is set (see Access Token Management, CookieSettings).
The token can also be sent in future requests via:
Authorization: Bearer <token>
Email and Mobile Verification During Login
Mindbricks allows email and/or mobile number verification as prerequisites for login. This ensures users have verified contact information before gaining access. All mobile numbers are normalized to E.164 format (+countryCode followed by subscriber number) before storage and comparison.
The user model includes:
emailVerified— present when the email field exists in the user data modelmobileVerified— present when the mobile field exists in the user data model (depends onprimaryLoginIdentifierandsecondaryIdentifierPresence)
You can require verification before login via:
{
"authentication": {
"loginDefinition": {
"userSettings": {
"emailVerificationRequiredForLogin": true,
"mobileVerificationRequiredForLogin": true
}
}
}
}
If a user attempts to log in without verifying their email or mobile number (when required), the system responds with an HTTP 403 and a specific error code, for example:
{
"result": "ERR",
"status": 403,
"message": "errMsg_EmailNotVerified",
"errCode": "EmailVerificationNeeded"
}
or
{
"result": "ERR",
"status": 403,
"message": "errMsg_MobileNotVerified",
"errCode": "MobileVerificationNeeded"
}
It is good UX to handle verifications during or immediately after registration. Mindbricks also includes verification flags in registration responses, for example:
{
"emailVerificationNeeded": true
}
or
{
"mobileVerificationNeeded": true
}
Two-Factor Authentication (2FA)
Mindbricks supports 2FA using email or mobile. Unlike pre-verification (which is a prerequisite for login), 2FA occurs after password (or social/SSO) login, as a second step.
Configuration is still part of LoginDefUserSettings:
{
"authentication": {
"loginDefinition": {
"userSettings": {
"email2FARequiredForLogin": true,
"mobile2FARequiredForLogin": false
}
}
}
}
If 2FA is enabled and triggered, the session is created but marked as needing a second factor:
{
"sessionNeedsEmail2FA": true
}
or
{
"sessionNeedsMobile2FA": true
}
As long as 2FA is incomplete, any attempt to use that session to access protected resources will fail with an HTTP 403 and a special error code, for example:
{
"result": "ERR",
"status": 403,
"message": "errMsg_someRouteRequiresEmail2FA",
"errCode": "EmailTwoFactorNeeded"
}
or
{
"result": "ERR",
"status": 403,
"message": "errMsg_someRouteRequiresMobile2FA",
"errCode": "MobileTwoFactorNeeded"
}
Social Logins
The Mindbricks auth service supports social login via several providers defined under SocialLoginSettings: Google, Apple, Facebook, Microsoft, LinkedIn, GitLab, and GitHub.
Social login allows users to sign in using their existing social accounts. Behind the scenes, Mindbricks uses OAuth2-based flows to authenticate users and extract profile data such as email.
Once the provider returns a verified profile:
-
If the user already exists (by email), they are logged in.
-
If not, Mindbricks returns a registration-needed response that includes a temporary
socialCodereference.
After that, frontend exchanges socialCode and either completes registration or receives a direct login result. Final login behavior is identical to native login — a JWT session is issued.
Frontend URL and Auth Callback
After OAuth processing, the auth service redirects the browser back to the frontend application's callback page. The redirect URL is resolved at runtime as follows:
- If
SOCIAL_LOGIN_REDIRECT_URLis explicitly set in the deployment environment, that value is used as-is. - Otherwise, the auth service derives it from
FRONTEND_URL + /auth/callback.
FRONTEND_URL is an environment variable automatically set from the project's frontendUrl setting in Basic Project Settings (see BasicProjectSettings.frontendUrl). It contains the base URL of the frontend application for the current deployment environment. This variable is important beyond social login — it is also used for email notification links, password reset URLs, and other frontend-facing URLs.
| Environment | FRONTEND_URL default (if frontendUrl not configured) |
|---|---|
| dev | http://localhost:5173 |
| test | https://{codename}.prw.mindbricks.com |
| stage | https://{codename}-stage.mindbricks.co |
| prod | https://{codename}.mindbricks.co |
You can override FRONTEND_URL for any environment by configuring the frontendUrl field in your project's Basic Project Settings. If you use a custom domain (e.g., https://app.mycustomdomain.com), set it there.
The frontend must have a page at /auth/callback (relative to FRONTEND_URL). This is the default route where the auth service redirects after OAuth processing. The callback page receives query parameters (provider, socialCode, or error) and exchanges the socialCode for the full session data via POST /auth/social-login-result.
In rare cases where a different callback path is needed, SOCIAL_LOGIN_REDIRECT_URL can be explicitly set as a custom variable in Basic Project Settings or as a deployment environment variable to override the default. In most cases, you do not need to set SOCIAL_LOGIN_REDIRECT_URL — the default derived from FRONTEND_URL is sufficient.
Enabling Google Login
In the ontology, Google login is configured as:
{
"authentication": {
"socialLogins": {
"google": {
"useGoogleLogin": true,
"configuration": {
"clientId": "yourGoogleClientIdHere",
"clientSecret": "yourGoogleClientSecretHere"
}
}
}
}
}
Enabling Apple Login
{
"authentication": {
"socialLogins": {
"apple": {
"useAppleLogin": true,
"configuration": {
"clientId": "yourAppleClientIdHere"
}
}
}
}
}
Enabling GitLab and GitHub Login
{
"authentication": {
"socialLogins": {
"gitlab": {
"useGitlabLogin": true,
"configuration": {
"clientId": "yourGitlabClientIdHere",
"clientSecret": "yourGitlabClientSecretHere"
}
},
"github": {
"useGithubLogin": true,
"configuration": {
"clientId": "yourGithubClientIdHere",
"clientSecret": "yourGithubClientSecretHere"
}
}
}
}
}
Social Login Registration Behavior (Current)
Social login for new users is a two-step flow:
- OAuth callback authenticates the user and creates a short-lived
socialCode. - Frontend exchanges
socialCodewithPOST /auth/social-login-result. - If user does not exist, backend returns
type: RegisterNeededForSocialLoginwith:socialCodeaccountInfo(verified profile fields from provider)
At this point frontend has two valid registration paths:
-
Direct registration with social profile data
Frontend calls register API usingsocialCodeand minimal fields. Backend complements user data from social profile. -
Registration with additional user input
Frontend first collects missing/required fields (for example mobile or custom required properties), then calls register API with those fields plussocialCode.
The register API resolves social profile data by socialCode, merges provided fields, and creates the user accordingly.
Legacy Migration Note
Older projects may still contain useForRegister in social login configurations. During current write/migration flows this legacy field is removed automatically, and social-login registration behavior follows the current default model.
Security note:
Although OAuth is used to verify email ownership, once the user model is created, Mindbricks handles subsequent sessions as native JWT-based sessions.
Permissions, roles, and access control apply in the same way as with native login.
SSO Login (Single Sign-On)
Mindbricks supports SSO-based authentication via the SSOAuth configuration under authenticationEssentials.ssoAuthentication. This allows users to log in through an external identity provider (IdP), such as an organization's SSO server.
Enabling SSO Authentication
{
"authentication": {
"authenticationEssentials": {
"ssoAuthentication": {
"useSSOForAuthentication": true,
"configuration": {
"ssoName": "yourSSOName",
"tokenPeriodInMinutes": 15,
"emailPropertyInProfile": "email",
"userNamePropertyInProfile": "name",
"ssoUserIdPropertyInProfile": "sub",
"ssoServerSettings": {
"tokenHost": "https://auth.mysso.com",
"authPath": "/oauth2/authorize",
"tokenPath": "/oauth2/token",
"userInfoPath": "/userinfo",
"logoutPath": "/logout",
"redirectUrl": "https://app.myApplication.com/home",
"clientId": "yourClientId",
"clientSecret": "yourClientSecret"
}
}
}
}
}
}
Profile Mapping
Instead of assuming field names, Mindbricks lets you map SSO profile fields explicitly:
-
emailPropertyInProfile(required) -
userNamePropertyInProfile(optional) -
ssoUserIdPropertyInProfile(optional, mapped toSSOUserIdin session)
Example mapping for a profile:
{
"user_email": "jane@example.com",
"displayName": "Jane Doe",
"user_id": "abc-123"
}
Configuration:
{
"authentication": {
"authenticationEssentials": {
"ssoAuthentication": {
"useSSOForAuthentication": true,
"configuration": {
"ssoName": "myCorporateSSO",
"emailPropertyInProfile": "user_email",
"userNamePropertyInProfile": "displayName",
"ssoUserIdPropertyInProfile": "user_id"
}
}
}
}
}
After successful SSO login, Mindbricks issues its own JWT token, just like in native or social logins. That token is then used for all subsequent API calls until it expires.
Remote Service Login
The ontology includes remoteServiceAuthentication and remoteSession under AuthBasics. These allow you to delegate authentication and/or session retrieval to external services.
For example, a minimal configuration skeleton looks like:
{
"authentication": {
"authenticationEssentials": {
"remoteServiceAuthentication": {
"isRemoteServiceAuthenticationActive": true,
"configuration": {
"remoteServiceRequest": {
"httpRequestUrl": "https://external-auth.example.com/validate",
"httpRequestMethod": "POST"
},
"sessionIdPathInToken": "sessionId",
"sessionReadLocation": "readFromRemoteService"
}
},
"remoteSessionSettings": {
"useRemoteSession": true,
"configuration": {
"sessionRequest": {
"httpRequestUrl": "https://external-auth.example.com/session",
"httpRequestMethod": "GET"
}
}
}
}
}
}
This document does not go into the details of remote auth flows, but it is important to note that they are available in the ontology.
Access Token Management
After any successful login (native, social, or SSO), the auth service issues a JWT (JSON Web Token). This token serves as the main credential for authenticating API requests throughout the user's session.
Token Expiration
JWT tokens have a limited lifetime to enhance security. In the ontology, token lifetime is configured via JWTAuthConfig.tokenPeriodInDays:
{
"authentication": {
"authenticationEssentials": {
"JWTAuthentication": {
"useJWTForAuthentication": true,
"configuration": {
"tokenPeriodInDays": 30
}
}
}
}
}
-
After the configured period, the token becomes invalid.
-
Services will return HTTP 401
Unauthorizedwhen an expired token is used. -
The client must perform a new login to obtain a fresh token.
Key Management for Token Verification
Each token is digitally signed by the auth service using a private key. The corresponding public key is exposed via the auth service (GET /publickey) so that other services can verify tokens without accessing the private key.
Key rotation is configured with keyRefreshPeriodInDays:
{
"authentication": {
"authenticationEssentials": {
"JWTAuthentication": {
"useJWTForAuthentication": true,
"configuration": {
"tokenPeriodInDays": 30,
"keyRefreshPeriodInDays": 150
}
}
}
}
}
Key rotation and token expiration are separate concerns:
- Token expiration limits the lifetime of each session.
- Key rotation limits the lifetime of each signing key, improving resilience against key compromise.
Access Token Usage in API Consumption
When a client makes an API call, it must present the JWT token. Mindbricks services check, in order (implementation-dependent):
-
Query parameter (e.g.,
access_token) -
Authorization: Bearer <token>header -
A custom header (same as cookie name)
-
Cookie
Cookie and header names are determined by Mindbricks conventions and may depend on tenant codename and project name, for example:
-
Single-tenant:
myApp-access-token -
Multi-tenant with tenant codename
store123:myApp-access-token-store123
The exact naming is not part of the static pattern file but is defined by the runtime auth service design.
Verification Services
The Mindbricks auth service provides several built-in verification flows that can be used during login, registration, password reset, or other user-related operations:
-
Password Reset (by Email or Mobile)
-
Email Verification
-
Mobile Verification
-
Two-Factor Authentication (2FA) via Email or Mobile
Each verification flow follows a consistent lifecycle pattern:
-
Client calls a start endpoint.
-
Server generates a one-time code or link.
-
Code/link is delivered via email or SMS.
-
Client submits the code or triggers the link.
-
Server completes the verification and applies the intended effect (e.g., resetting a password or confirming an email).
General Configuration Structure
All verification services are configured under authentication.verificationServices, based on VerificationServices and VerificationConfig.
Each verification type has:
-
An
isActiveflag (e.g.,passwordResetByEmailIsActive). -
A
configurationobject implementingVerificationConfig.
For example:
{
"authentication": {
"verificationServices": {
"verificationSettings": {
"verificationMode": "testMode"
},
"passwordResetByEmail": {
"passwordResetByEmailIsActive": true,
"configuration": {
"resendTimeWindow": 3600,
"expireTimeWindow": 86400,
"verificationType": "byCode",
"verificationTemplate": "$assetRead-PasswordResetByEmail.ejs"
}
}
}
}
}
Shared Settings Across Verifications
All verifications use VerificationConfig fields:
-
resendTimeWindow******** (seconds) How often a user can request a new code:{ "authentication": { "verificationServices": { "passwordResetByEmail": { "configuration": { "resendTimeWindow": 3600 } }, "mobileVerification": { "configuration": { "resendTimeWindow": 60 } } } } } -
expireTimeWindow******** (seconds) How long a code remains valid after issuance:{ "authentication": { "verificationServices": { "passwordResetByEmail": { "configuration": { "expireTimeWindow": 86400 } }, "mobile2Factor": { "configuration": { "expireTimeWindow": 300 } } } } } -
verificationType:"byCode"or"byLink"{ "authentication": { "verificationServices": { "passwordResetByEmail": { "configuration": { "verificationType": "byLink" } }, "passwordResetByMobile": { "configuration": { "verificationType": "byCode" } } } } }Common convention: - Use "byLink" for email-based verifications. - Use "byCode" for mobile (SMS) verifications. -
verificationTemplateThe EJS template (from the service library assets) used to render the verification message.
Verification Mode: testMode vs liveMode
Verification mode is set globally under verificationServices.verificationSettings.verificationMode:
{
"authentication": {
"verificationServices": {
"verificationSettings": {
"verificationMode": "testMode"
}
}
}
}
Possible values are:
-
"testMode"– secret code is also returned in the API response (useful during development). -
"liveMode"– secret code is only sent via the real channel (email/SMS).
Verification URLs (for byLink)
When using "byLink", Mindbricks generates a link that points to a specific path on your frontend. The exact path is determined by your frontend design, but typical patterns are:
https://app.myApp.com/passwordResetByEmail/{hash}
https://app.myApp.com/mobileVerification/{hash}
https://app.myApp.com/emailVerification/{hash}
...
The frontend must be prepared to handle each verification path corresponding to your configuration and API guide.
Role Management (RBAC)
Mindbricks supports Role-Based Access Control (RBAC) as a flexible, declarative way to manage user permissions across your application. RBAC is configured under AccessControl.roleSettings, implemented by the RBACSettings and RBACSettingsConfig patterns.
In Mindbricks, roles are defined at design time and treated as a static vocabulary.
This gives you consistent behavior across services and simplifies permission reasoning.
Enabling RBAC
{
"authentication": {
"accessControl": {
"roleSettings": {
"rbacIsActive": true,
"configuration": {
"usersHaveMultipleRoles": false
}
}
}
}
}
When rbacIsActive is true, the auth service and other modules can enforce access control based on roles.
Please note that even when RBAC is not explicitly activated, Mindbricks still applies a system-level role model, particularly within the auth service. The roleId property is always attached to every user, ensuring that fundamental authorization flows remain consistent.
In single-tenant projects, the system automatically provides the following built-in roles:
-
superAdmin -
admin -
user
In multi-tenant (SaaS) projects, Mindbricks activates an extended system role set:
SaaS-level roles:
-
superAdmin -
saasAdmin -
saasUser
Tenant-level roles (applied per tenant):
-
tenantOwner -
tenantAdmin -
tenantUser
These roles are generated automatically by the platform and support the foundational permission logic required for managing tenants, users, and administrative hierarchies, even before any custom RBAC configuration is introduced.
Defining Roles
Roles are defined via rolesObject, an array of RoleItem objects (each with name and value):
{
"authentication": {
"accessControl": {
"roleSettings": {
"rbacIsActive": true,
"configuration": {
"rolesObject": [
{ "name": "Admin", "value": "admin" },
{ "name": "User", "value": "user" },
{ "name": "Manager", "value": "manager" }
]
}
}
}
}
}
-
name: Display label (used in UIs and documentation). -
value: Stored inuser.roleIdand session.
The value type is Any, which means you are free to use strings or numbers; there is no separate roleIdDataType configuration in the current ontology. You choose the convention and stick to it.
Multiple Roles per User
You can allow users to have multiple roles via usersHaveMultipleRoles:
{
"authentication": {
"accessControl": {
"roleSettings": {
"rbacIsActive": true,
"configuration": {
"usersHaveMultipleRoles": true
}
}
}
}
}
When this is true, the session will treat roleId as an array of values instead of a single value.
Custom Role Lookups
RBACSettingsConfig also supports customRoleLookups as an array of DataMapItem with MScript values (e.g., dynamic logical roles):
{
"authentication": {
"accessControl": {
"roleSettings": {
"rbacIsActive": true,
"configuration": {
"customRoleLookups": [
{
"name": "isProjectAdmin",
"value": "this.session && this.session.userId === this.project.ownerId"
}
]
}
}
}
}
}
These logical roles are evaluated at runtime and can be used inside Business APIs and validation scripts.
Permission Management (PBAC)
In addition to RBAC, Mindbricks offers Permission-Based Access Control (PBAC) — a fine-grained system for defining and evaluating permissions at multiple levels.
PBAC is configured using the PermissionBasics, PermissionBasicsConfig, PermissionGroup, PermissionTypes, OBACPermission, and AbacPermission patterns.
Enabling PBAC
{
"authentication": {
"accessControl": {
"permissionBasics": {
"pbacIsActive": true,
"configuration": {
"permissionGroups": []
}
}
}
}
}
Defining Permissions and Groups
Permissions are defined in named groups under permissionGroups:
{
"authentication": {
"accessControl": {
"permissionBasics": {
"pbacIsActive": true,
"configuration": {
"permissionGroups": [
{
"groupName": "projectManagement",
"permissions": [
"createProject",
"editProject",
"deleteProject"
]
},
{
"groupName": "userManagement",
"permissions": [
"inviteUser",
"removeUser"
]
}
]
}
}
}
}
}
Each permission string must be unique across the project. In your logic, you can reference them as:
-
"projectManagement.createProject" -
"userManagement.inviteUser"
or simply by "createProject" depending on your naming style.
Activating Permission Types
The PermissionTypes object defines which strategies are active in the system:
{
"authentication": {
"accessControl": {
"permissionTypes": {
"roleBasedPermissionsIsActive": true,
"userBasedPermissionsIsActive": true,
"userGroupBasedPermissionsIsActive": true,
"objectBasedPermissionsIsActive": true,
"tenantBasedPermissionsIsActive": true
}
}
}
}
-
roleBasedPermissionsIsActive– permissions via roles -
userBasedPermissionsIsActive– direct user permissions -
userGroupBasedPermissionsIsActive– group-based permissions -
objectBasedPermissionsIsActive– object-scoped permissions (OBAC) -
tenantBasedPermissionsIsActive– tenant-scoped permission logic
Object-Based Permissions (OBAC)
Object-based permissions are configured through OBACPermission:
{
"authentication": {
"accessControl": {
"objectBasedSettings": {
"objectBasedPermissionsIsActive": true,
"dataObjects": [
"project",
"invoice"
]
}
}
}
}
This means that access to specific instances of project or invoice can be controlled by object-level rules (e.g., per-record permissions).
Tenant-Based Permissions
Tenant-based permission logic is activated via tenantBasedPermissionsIsActive in PermissionTypes. At a conceptual level, this enables:
-
SaaS-level administrators to define tenant-specific permission profiles.
-
Different tenants to have different permission sets or feature capabilities.
The exact mechanism for storing such special per-tenant permissions is implementation-specific, but the intent matches what you previously described as "special tenant permissions" or "feature flags per tenant".
Attribute-Based Access Control (ABAC)
ABAC is handled via the AbacPermission pattern (attributeBasedSettings):
{
"authentication": {
"accessControl": {
"attributeBasedSettings": {
"attributeBasedPermissionsIsActive": true,
"abacDefinitions": [
{
"name": "projectEditors",
"dataObject": "project",
"whereClause": "{ projectType: 'external' }",
"permissions": [
"projectManagement.editProject"
]
}
]
}
}
}
}
-
dataObject– the target data object. -
whereClause– an MScript expression that yields a query-like object. -
permissions– permission strings granted when the rule matches.
ABAC rules are evaluated in the context of data objects and may override or augment role-based and user-based permissions.
PBAC Permission Assignment Storage
The ontology you shared does not explicitly define a givenPermissions data object, so this document does not assume a specific pattern class name for storing permission assignments. Instead, we can state:
When PBAC is active, Mindbricks persists permission assignments according to its internal authorization model.
In some deployments, this may appear as a dedicated "permission assignment" data object (for example, a custom data object you define yourself).
You are free to model such an object explicitly (e.g., with fields like permissionName, roleId, subjectUserId, objectId, canDo) using standard DataObject and DataProperty patterns if you need direct CRUD over permission assignments.
The conceptual structure described in your earlier draft (with fields like permissionName, roleId, subjectUserId, subjectUserGroupId, objectId, canDo, plus a tenant-scoped ID) is still valid as a design pattern, but it is not currently present as a named ontology object in patterns.json.
PBAC Permission Types Summary
The following table summarizes different permission mechanisms in the PBAC architecture.
Each mechanism can be activated or deactivated depending on the project's authorization needs.
| Permission Type | Description | Activation Setting Key |
|---|---|---|
| Role-Based | Permissions granted based on roles | roleBasedPermissionsIsActive |
| User-Based | Permissions granted directly to users | userBasedPermissionsIsActive |
| User Group-Based | Permissions granted to user groups | userGroupBasedPermissionsIsActive |
| Tenant-Based | Tenant-specific permission logic and profiles | tenantBasedPermissionsIsActive |
| Object-Based (OBAC) | Permissions tied to specific object instances | objectBasedPermissionsIsActive |
| Attribute-Based (ABAC) | Permissions evaluated via attribute-level rules (AbacPermission) | attributeBasedPermissionsIsActive in attributeBasedSettings |
Multi Tenancy Management
Mindbricks supports both single-tenant and multi-tenant architectures. Multi-tenancy allows multiple organizations, clients, or workspaces to share the same system while keeping data and permissions isolated.
Tenant-specific settings are configured via LoginDefTenantSettings under loginDefinition.tenantSettings.
Enabling Multi-Tenant Mode
{
"authentication": {
"loginDefinition": {
"tenantSettings": {
"useMultiTenantFeature": true,
"configuration": {
"tenantName": "client"
}
}
}
}
}
-
By default, projects are single-tenant, and
tenantSettingscan be omitted. -
When
useMultiTenantFeatureistrue, Mindbricks treats users, data, and permissions as tenant-scoped by default.
Defining the Tenant Concept
LoginDefTenantSettingsConfig.tenantName defines the tenant concept label:
{
"authentication": {
"loginDefinition": {
"tenantSettings": {
"useMultiTenantFeature": true,
"configuration": {
"tenantName": "client"
}
}
}
}
}
This tenantName is used to:
-
Name the tenant data object (conceptually like
clientorstore). -
Generate related property names (e.g.,
clientId,storeId) across user and domain objects. -
Influence naming in generated code.
Tenant Registration Rules
LoginDefTenantSettingsConfig also controls whether tenants can be created publicly or only by SaaS-level admins:
{
"authentication": {
"loginDefinition": {
"tenantSettings": {
"useMultiTenantFeature": true,
"configuration": {
"tenantName": "client",
"tenantRegisterIsPublic": true
}
}
}
}
}
-
tenantRegisterIsPublic = true: any authenticated user can create a tenant (they become the owner). -
tenantRegisterIsPublic = false: only SaaS-level admins can create tenants.
Tenant Auto-Avatar Script
The ontology provides tenantAutoAvatarScript for automatically generating tenant avatar URLs:
{
"authentication": {
"loginDefinition": {
"tenantSettings": {
"useMultiTenantFeature": true,
"configuration": {
"tenantName": "client",
"tenantAutoAvatarScript": "`https://gravatar.com/avatar/${LIB.common.md5(this.fullname)}?s=200&d=identicon`"
}
}
}
}
}
This is an MScript string evaluated at runtime.
Custom Tenant Properties
You can define additional tenant properties using ProjectAuthentication.tenantProperties:
{
"authentication": {
"tenantProperties": [
{
"basicSettings": {
"name": "subscriptionLevel",
"type": "Enum",
"isArray": false,
"description": "The subscription level of the tenant (e.g., Free, Pro, Enterprise).",
"isRequired": true,
"allowUpdate": true,
"requiredInUpdate": false,
"allowAutoUpdate": false,
"autoIncrement": false,
"hashed": false,
"isFilterParameter": true,
"enumOptions": ["Free", "Pro", "Enterprise"],
"defaultValues": {
"default": "Free",
"defaultInUpdate": null
}
},
"indexSettings": {
"indexedInElastic": true,
"indexedInDb": true,
"unique": false,
"clusterInRedis": false,
"cacheSelect": false,
"isSecondaryKey": false,
"fulltextSearch": false
}
}
]
}
}
As with user properties, tenant custom fields must not conflict with system-owned fields like `name`, `ownerId`, etc.
They follow the standard DataProperty pattern and can be filtered, indexed, or related just like any other domain field.
Tenant-Level Authorization Options
Multi-tenancy automatically scopes data by tenant ID, but you can go further and define tenant-specific permission profiles using tenantBasedPermissionsIsActive in PermissionTypes and, if needed, custom permission/object models.
Conceptually, this allows:
-
Certain tenants to have premium features enabled.
-
Beta features to be rolled out to specific tenants.
-
Tenant-specific access constraints for complex SaaS offerings.
Implementation details for such feature-flag-like behaviors can be modeled using:
-
Custom tenant properties (like
subscriptionLevel) -
PBAC / ABAC rules keyed by tenant ID or subscription fields
-
Tenant-based permission logic toggled via
tenantBasedPermissionsIsActive
API Key Authentication
Mindbricks supports API Key authentication for programmatic access to services on behalf of a user. API keys are intended for server-to-server integrations, CI/CD pipelines, automated scripts, and any scenario where a user's credentials should not be used directly.
Enabling API Key Authentication
Enable API key authentication in the AuthBasics configuration:
{
"authenticationEssentials": {
"apiKeyAuthentication": {
"useAPIKeyForAuthentication": true,
"configuration": {
"apiKeyLocation": "bearer",
"secretApiKeyName": null,
"publicApiKeyName": null
}
}
}
}
When apiKeyLocation is "bearer", the API key is sent in the Authorization: Bearer header alongside JWT tokens. The system distinguishes API keys from JWTs by the sk_mbx_ prefix.
For other locations ("header", "query", "cookie", "body"), set the secretApiKeyName to the field name where the key will be placed in the request.
How API Key Authentication Works
-
Key creation: An authenticated user calls
createSecretApiKeyto generate a new key. The plaintext key (sk_mbx_{random_hex}) is returned only once. The system stores only the SHA-256 hash. -
Making requests: The client sends requests with the API key (in the configured location). Every request must include the key — API key sessions are tokenless (no JWT, no cookie).
-
Session resolution: When a service receives a request with an API key:
- It computes the SHA-256 hash of the key
- Checks Redis for a cached session (
apikeysession:{hash}) - If found, uses the cached session directly
- If not found, calls the auth service's
POST /validateapikeyroute - The auth service looks up the key hash in the database, verifies it, loads the user, and creates a session
- The session is cached in Redis with a 1-day TTL
- After 1 day, the cached session expires and the next request triggers a fresh validation
-
Key management: Users can list, create, and delete their keys via the auth service profile APIs.
Bearer Token Discrimination
When apiKeyLocation is "bearer", both JWT tokens and API keys share the Authorization: Bearer header. The system uses the sk_mbx_ prefix to distinguish between them:
- If the bearer value starts with
sk_mbx_, it is treated as an API key - Otherwise, it is treated as a JWT token and follows the standard JWT authentication flow
This allows both authentication methods to coexist seamlessly on the same endpoints.
Generated Assets
When API key authentication is enabled, the following are automatically generated:
apiKeydata object — stores key records (hash, prefix, userId, expiry, etc.)createSecretApiKey— creates a new secret keydeleteApiKey— deletes a key and cleans up Redis sessionslistApiKeys— lists user's keys (prefix only)POST /validateapikey— internal inter-service validation route (not for client use)
For full API details, see the Auth Service Generated Assets reference.
API Key vs. Password Login vs. M2M
| Feature | Password Login | API Key | M2M |
|---|---|---|---|
| Session created | Yes (JWT + cookie) | Yes (Redis only, tokenless) | No session |
| Token returned | Yes (access token) | No | Ed25519 signed token |
| Session TTL | Configurable (days) | 1 day in Redis | 15 minutes per token |
| User identity | Direct login | On behalf of key owner | Service identity |
| Use case | Interactive users | Programmatic access | Inter-service calls |
Machine-to-Machine (M2M) Authentication
Mindbricks supports Machine-to-Machine (M2M) authentication for secure inter-service communication without requiring user session tokens. M2M tokens use Ed25519 cryptographic signatures and include request payload hashing to prevent token reuse attacks.
Enabling M2M on Business APIs
To allow a Business API to accept M2M tokens, set M2MAllowed: true in the API's authOptions:
{
"authOptions": {
"M2MAllowed": true,
"loginRequired": false
}
}
When M2MAllowed: true:
- Services can call the API using M2M tokens (sent via HTTP headers for REST/gRPC, or in message payload for Kafka)
- If
loginRequired: false, M2M token is required (no user session fallback) - If
loginRequired: true, either M2M token or user session is acceptable
Automatic M2M Token Generation
M2M tokens are automatically generated and included when:
- Using
ApiCallActionto make HTTP requests (token added to headers) - Using
PublishEventActionorServicePublisherto publish Kafka events (token added to message payload)
Each token includes:
- Sender identity:
{SERVICE_SHORT_NAME}-service - Request payload hash (MD5) to prevent token reuse
- 15-minute expiration
Service-Level Access Control
Configure M2M access control at the service level using ServiceOptions:
{
"serviceSettings": {
"serviceOptions": {
"machineToMachineBlockList": ["blocked-service"],
"allowedM2MClients": ["allowed-service-1", "allowed-service-2"]
}
}
}
Access control is enforced in staging and production environments only.
For comprehensive M2M documentation, including REST, gRPC, and Kafka communication patterns, see the Machine-to-Machine Communication guide.
Last updated 1 day ago
Built with Documentation.AI