Dragon Guard JWT tokens carry user identity, tenant scope, and role information as standard claims. Understanding the claims structure is essential for implementing client-side role checks, building multi-tenant UIs, and debugging authorization failures. All tokens are signed with HMAC SHA-256 using the secret configured inDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/CodexaCP/DG_BACK/llms.txt
Use this file to discover all available pages before exploring further.
Jwt:Key.
Claims reference
The following claims are present in every Dragon Guard JWT unless noted otherwise.| Claim | Type | Always present | Description |
|---|---|---|---|
userId | string | ✅ | The user’s unique identifier (auth.Users.Id as a UUID string). For GrupoMAS delegated sessions this is a deterministic UUID derived from GrupoMASNative:<companyId>:<username>. |
email | string | ✅ | The user’s email address. For GrupoMAS sessions this is the email returned by MAS, or the username when MAS returns no email. |
isSuperAdmin | string | ✅ | "True" or "False". When "True" the account is SUPERADMIN_SUPREMO with global platform access and no tenant scope. |
isHandheld | string | ✅ | "True" when the token was issued by the handheld login endpoint. |
authProvider | string | ✅ | Identifies the authentication source. See authProvider values. |
company_access | string | ⚠️ per company | One claim per authorized company. Value is the companyId UUID string. Omitted for SUPERADMIN_SUPREMO. |
company_role | string | ⚠️ per company | One claim per authorized company in companyId:roleCode format (e.g. 1b9d6bcd-...:ADMIN). Used for per-company role resolution. Omitted for SUPERADMIN_SUPREMO. |
companyId | string | ⚠️ non-supreme | The default company context (UUID string). Set to the first company in the user’s access list. Omitted for SUPERADMIN_SUPREMO. |
role | string | ✅ | Global role claim. SUPERADMIN_SUPREMO for supreme accounts; the user’s role code for tenant accounts. |
http://schemas.microsoft.com/ws/2008/06/identity/claims/role | string | ✅ | ASP.NET Core ClaimTypes.Role — same value as role. Required for [Authorize(Roles = "...")] attributes. |
externalUsername | string | ⚠️ handheld | The normalized MAS username. Present only on GrupoMAS delegated sessions (authProvider = GrupoMASNative). |
deviceId | string | ⚠️ handheld | The normalized device MAC address (e.g. AA:BB:CC:DD:EE:FF). Present only on handheld tokens when a deviceId was supplied. |
authProvider values
TheauthProvider claim identifies how the user authenticated. Dragon Guard currently issues tokens with two provider values:
| Value | Auth flow | Notes |
|---|---|---|
DragonGuardLocal | Standard POST /api/auth/login | Email/password verified against auth.Users.PasswordHash using BCrypt. Default value when no override is supplied. |
GrupoMASNative | POST /api/auth/grupomas-handheld-login | Credentials delegated to the GrupoMAS ERP. No local password is stored. POST /api/auth/change-password is blocked for these sessions. |
SUPERADMIN_SUPREMO token structure
Supreme administrator accounts (auth.Users.IsSuperAdmin = 1) receive a different token shape than tenant users:
isSuperAdminis"True"roleis"SUPERADMIN_SUPREMO"- No
company_accessclaims - No
company_roleclaims - No
companyIdclaim
ApiControllerBase.HasCompanyAccess grants unconditional access when isSuperAdmin = true, bypassing the company_access check. Supreme endpoints under api/supreme/* additionally call EnsureSupremeAccess() which explicitly rejects non-supreme tokens.
Company context resolution
ApiControllerBase.ResolveCompanyId determines the active tenant for every protected request. Resolution follows a strict priority order:
1 — companyId query parameter
If
companyId is present in the query string and is a valid UUID, it is used. The value is immediately validated against the token’s company_access claims — an unrecognized company ID is rejected with 401 Unauthorized.2 — X-Company-Id request header
If the
X-Company-Id header is present and is a valid UUID, it is used. The same access check applies.Never pass an arbitrary
companyId and expect it to work without token backing. All three resolution paths call EnsureCompanyAccess, which verifies the resolved company is present in the token’s company_access claims (or the user is SUPERADMIN_SUPREMO).Role resolution
ApiControllerBase.Role uses the following logic to determine the effective role for the current request:
- If
IsSupremeAdministrue, return"SUPERADMIN_SUPREMO"immediately. - Resolve the effective company via
ResolveCompanyId(). - Search the token’s
company_roleclaims for a claim whosecompanyIdsegment matches the resolved company. Return theroleCodesegment from that claim. - If no matching
company_roleclaim is found, fall back to the globalroleclaim.
company_role claims. The fallback to role ensures backward compatibility with tokens issued before per-company role claims were introduced.
Token validation configuration
Dragon Guard validates incoming JWTs using the followingTokenValidationParameters settings — all four validation checks are enabled:
| Parameter | Enabled | Notes |
|---|---|---|
ValidateIssuer | ✅ | Issuer must match Jwt:Issuer from server configuration. |
ValidateAudience | ✅ | Audience must match Jwt:Audience from server configuration. |
ValidateLifetime | ✅ | Token expiry is enforced. Expiry duration is set by Jwt:ExpiresInMinutes. |
ValidateIssuerSigningKey | ✅ | Signature is verified against the HMAC SHA-256 key in Jwt:Key. |