Design Your AppManage Authentication
Design Your App

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:

  1. User and user data management

  2. User group management

  3. Login and logout operations

  4. Verification services

  5. Role management (RBAC)

  6. Permission management (PBAC) and advanced access control

  7. 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

  1. 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.

  2. Through Additional Services Although it's ideal to stick to the auth service 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 the userId.


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):

  1. id A unique identifier (UUID) for each user. Like all other Mindbricks data objects, the id field is automatically included.

    • Appears in objects like session as userId.

    • Other data objects will reference the user with userId.

  2. email Represents the user's email address.

    • Serves as both a unique identifier and the primary username for login.

    • Also used for communication, notifications, and verification flows.

  3. password Stores the user's password securely.

    • Passwords are hashed (and salted) using a one-way algorithm — they are never stored in plain text.
  4. emailVerified Indicates 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 EmailVerificationNeeded error when the user tries to log in with an unverified email. The frontend must then trigger the email verification flow (see Verification Services).

  5. 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: UserNameType with 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.
    
  6. avatar A 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 userAutoAvatarScript field defined in LoginDefUserSettings. 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.

  7. roleId Stores 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 (the RoleItem.value is of type Any). That means you can use strings ("admin") or numbers (1) depending on your preference.

    • When usersHaveMultipleRoles is enabled, roleId is treated as an array.

  8. mobile (optional) Represents the user’s mobile phone number, activated via:

    {
      "authentication": {
        "loginDefinition": {
          "userSettings": {
            "userMobileIsActive": true
          }
        }
      }
    }
    
  9. mobileVerified (optional) Indicates whether the user's mobile number has been verified. This is meaningful only if userMobileIsActive is true. 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 email uniqueness is tenant-scoped.

The tenant ID field name depends on your tenant naming settings. For example:

  • clientId if the tenant is named "client"

  • storeId if 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 user object 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,
          "defaultValues": {
            "default": "male",
            "defaultInUpdate": null
          }
        },
        "indexSettings": {
          "indexedInElastic": true,
          "indexedInDb": false,
          "unique": false,
          "clusterInRedis": false,
          "cacheSelect": false,
          "isSecondaryKey": false,
          "fulltextSearch": false
        },
        "enumSettings": {
          "hasEnumOptions": true,
          "configuration": {
            "enumOptions": ["male", "female"]
          }
        }
      }
    ]
  }
}

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": {
        "superAdminEmail": "super.admin@myproject.com",
        "superAdminPassword": "yourPassword"
      }
    }
  }
}

If you omit superAdminEmail, the default is "admin@admin.com". The default password is "superadmin", as defined in the pattern defaults.

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:

  1. id UUID representing the unique identity of the user group.

  2. groupName The name of the group, which will be shown in the application’s UX.

  3. avatar A 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:

  1. id A UUID representing this specific user–group membership (useful when removing a user from a group).

  2. groupId The ID of the group.

  3. userId The ID of the user.

  4. ownerId The 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 email/password login

  • 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 via Email and Password

The most common login method is via email 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.

The user model includes:

  • emailVerified

  • mobileVerified

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, 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 can auto-create the user account using the information returned by the provider (depending on the useForRegister flag).

After that, login behavior is identical to a native login — a JWT session is issued.

Enabling Google Login

In the ontology, Google login is configured as:

{
  "authentication": {
    "socialLogins": {
      "google": {
        "useGoogleLogin": true,
        "configuration": {
          "clientId": "yourGoogleClientIdHere",
          "clientSecret": "yourGoogleClientSecretHere",
          "useForRegister": true
        }
      }
    }
  }
}

Enabling Apple Login

{
  "authentication": {
    "socialLogins": {
      "apple": {
        "useAppleLogin": true,
        "configuration": {
          "clientId": "yourAppleClientIdHere",
          "useForRegister": true
        }
      }
    }
  }
}

Enabling GitLab and GitHub Login

{
  "authentication": {
    "socialLogins": {
      "gitlab": {
        "useGitlabLogin": true,
        "configuration": {
          "clientId": "yourGitlabClientIdHere",
          "clientSecret": "yourGitlabClientSecretHere",
          "useForRegister": true
        }
      },
      "github": {
        "useGithubLogin": true,
        "configuration": {
          "clientId": "yourGithubClientIdHere",
          "clientSecret": "yourGithubClientSecretHere",
          "useForRegister": true
        }
      }
    }
  }
}

Controlling Auto-Registration via Social Login

The useForRegister flag controls whether a user without an existing account is auto-created on first social login:

{
  "authentication": {
    "socialLogins": {
      "google": {
        "useGoogleLogin": true,
        "configuration": {
          "clientId": "yourGoogleClientIdHere",
          "clientSecret": "yourGoogleClientSecretHere",
          "useForRegister": false
        }
      }
    }
  }
}

Setting useForRegister to false means Google can only be used for existing users (no automatic onboarding).

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 to SSOUserId in 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 Unauthorized when 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):

  1. Query parameter (e.g., access_token)

  2. Authorization: Bearer <token> header

  3. A custom header (same as cookie name)

  4. 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:

  1. Client calls a start endpoint.

  2. Server generates a one-time code or link.

  3. Code/link is delivered via email or SMS.

  4. Client submits the code or triggers the link.

  5. 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 isActive flag (e.g., passwordResetByEmailIsActive).

  • A configuration object implementing VerificationConfig.

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:

  1. resendTimeWindow******** (seconds) How often a user can request a new code:

    {
      "authentication": {
        "verificationServices": {
          "passwordResetByEmail": {
            "configuration": {
              "resendTimeWindow": 3600
            }
          },
          "mobileVerification": {
            "configuration": {
              "resendTimeWindow": 60
            }
          }
        }
      }
    }
    
  2. expireTimeWindow******** (seconds) How long a code remains valid after issuance:

    {
      "authentication": {
        "verificationServices": {
          "passwordResetByEmail": {
            "configuration": {
              "expireTimeWindow": 86400
            }
          },
          "mobile2Factor": {
            "configuration": {
              "expireTimeWindow": 300
            }
          }
        }
      }
    }
    
  3. 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.
    
  4. verificationTemplate The 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).


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 in user.roleId and 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 TypeDescriptionActivation Setting Key
Role-BasedPermissions granted based on rolesroleBasedPermissionsIsActive
User-BasedPermissions granted directly to usersuserBasedPermissionsIsActive
User Group-BasedPermissions granted to user groupsuserGroupBasedPermissionsIsActive
Tenant-BasedTenant-specific permission logic and profilestenantBasedPermissionsIsActive
Object-Based (OBAC)Permissions tied to specific object instancesobjectBasedPermissionsIsActive
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 tenantSettings can be omitted.

  • When useMultiTenantFeature is true, 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 client or store).

  • 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,
          "defaultValues": {
            "default": "Free",
            "defaultInUpdate": null
          }
        },
        "indexSettings": {
          "indexedInElastic": true,
          "indexedInDb": true,
          "unique": false,
          "clusterInRedis": false,
          "cacheSelect": false,
          "isSecondaryKey": false,
          "fulltextSearch": false
        },
        "enumSettings": {
          "hasEnumOptions": true,
          "configuration": {
            "enumOptions": ["Free", "Pro", "Enterprise"]
          }
        },
        "relationSettings": {
          "hasRelation": false
        },
        "sessionSettings": {
          "isSessionData": false
        },
        "contextSettings": {
          "isContextData": false
        },
        "formulaSettings": {
          "isCalculated": false
        },
        "filterSettings": {
          "isFilterParameter": true,
          "configuration": {
            "filterName": "subscriptionLevel"
          }
        },
        "staticJoin": {
          "isStaticJoin": 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

Was this page helpful?
Built with Documentation.AI

Last updated today