Language: English Español
This document is retained as a structural reference for the original graph shape. The current client contract is the semantic-first payload documented in Semantic Auth Graph Client Contract.
The canonical JSON Schema contract between the UMS server and SDK runtimes is now the semantic-first contract.
For the full runtime example and authorization semantics, see auth-graph.md. This page focuses on the schema shape, types, and contract guarantees.
For the semantic-first client contract that removes GUID dependence from the default surface, see Semantic Auth Graph Client Contract.
| Artifact | Path |
|---|---|
| JSON Schema | src/libs/sdk/contracts/auth-graph.schema.json |
| Error codes catalog | src/libs/sdk/contracts/error-codes.yaml |
| Golden fixtures | src/libs/sdk/contracts/fixtures/*.json |
| Versioning policy | src/libs/sdk/contracts/SCHEMA_VERSIONING.md |
The schema is JSON Schema 2020-12.
{
"schemaVersion": "1.0.0", // semver, required, governed by ADR-0074
"context": { ... }, // who is the principal, in what tenant/branch/role
"authentication": { ... }, // how was identity verified
"actions": [ ... ], // full action catalog of the SystemSuite
"menuAccess": [ ... ], // UI navigation tree with resolved permissions
"domainPermissions": [ ... ], // domain resources (Aggregate/Entity) with resolved permissions
"featureFlags": [ ... ], // flags evaluated at auth-time
"effectiveConfig": { ... }, // tenant-resolved parameters
"scopes": [ ... ], // OAuth2-style "RESOURCE.ACTION" strings
"generatedAt": "...", // ISO-8601 UTC
"validUntil": "..." // ISO-8601 UTC; = generatedAt + sessionTimeoutMinutes
}
All fields above are required at v1.0.0. Adding optional fields in the future is a MINOR bump per ADR-0074.
schemaVersion (string, required)MAJOR.MINOR.PATCH^\d+\.\d+\.\d+$"1.0.0"context (object, required)"context": {
"user": { "id": "uuid", "email": "string", "username": "string",
"displayName": "string", "status": "ACTIVE|PENDING|BLOCKED" },
"tenant": { "id": "uuid", "code": "string", "name": "string",
"status": "ACTIVE|SUSPENDED|ARCHIVED" },
"systemSuite": { "id": "uuid", "code": "string", "name": "string",
"status": "DRAFT|PUBLISHED|RETIRED" },
"role": { "id": "uuid", "code": "string", "name": "string",
"hierarchyLevel": 0, "parentRoleId": "uuid|null" },
"profile": { "id": "uuid", "scope": "OrgWide|BranchScoped", "isActive": true },
"branch": { "id": "uuid", "code": "string", "name": "string" } | null
}
Notes:
branch is null when the profile scope is OrgWide.authentication (object, required)"authentication": {
"method": "Local" | "IDP",
"provider": { "name": "string", "code": "string", "strategy": "string" } | null,
"mfaRequired": true|false,
"issuedAt": "ISO-8601",
"sessionExpiresAt": "ISO-8601"
}
provider is null when method = "Local". When method = "IDP", provider is required and strategy matches a value of IdpStrategyHint from BC-A (e.g., AZURE_AD, OKTA, SAML2, GENERIC_OIDC).
The SDK does NOT receive IDP tokens — see Security Notes in auth-graph.md §10.
actions (array, required, may be empty)Catalog of all Action entities registered in the SystemSuite. Used by clients to resolve actionCode references in menuAccess and domainPermissions.
"actions": [
{ "id": "uuid", "code": "VIEW", "name": "View" }
]
menuAccess (array, required, may be empty)UI navigation tree: Module → Menu → SubMenu → Option, with the resolved AccessEffect and source at the leaf level.
"menuAccess": [
{
"module": { "id": "uuid", "code": "string", "name": "string",
"sortOrder": 0, "status": "PUBLISHED" },
"menus": [
{
"id": "uuid", "code": "string", "label": "string", "sortOrder": 0,
"subMenus": [
{
"id": "uuid", "code": "string", "label": "string", "sortOrder": 0,
"options": [
{
"id": "uuid", "code": "string", "label": "string",
"actionCode": "VIEW",
"effect": "Allow" | "Deny" | "NotGranted",
"source": "Template" | "Override"
}
]
}
]
}
]
}
]
domainPermissions (array, required, may be empty)Domain resources (Aggregate or Entity) with resolved permissions per action.
"domainPermissions": [
{
"resource": { "id": "uuid", "type": "Aggregate" | "Entity",
"code": "string", "name": "string", "moduleId": "uuid|null" },
"actions": [
{ "actionId": "uuid", "actionCode": "string", "actionName": "string",
"effect": "Allow" | "Deny" | "NotGranted",
"source": "Template" | "Override" }
]
}
]
featureFlags (array, required, may be empty)Feature flags evaluated at auth-time against the user’s full context.
"featureFlags": [
{
"flagCode": "string",
"systemSuiteId": "uuid",
"isEnabled": true|false,
"matchedCriteriaType": "TenantId|BranchId|UserProfileId|RoleCode|Environment|DateRange|PercentageHash|CustomRule" | null
}
]
isEnabled = false and matchedCriteriaType = null means the flag exists but no criteria matched the context (false-on-missing-context per ADR-0068).
effectiveConfig (object, required)Tenant-resolved configuration parameters from the ParameterCatalog.
"effectiveConfig": {
"sessionTimeoutMinutes": 60,
"maxLoginAttempts": 5,
"minPasswordLength": 12,
"mfaRequiredForAdmin": true,
"accessTokenDurationMs": 3600000,
"authUseExternalIdp": false
}
This is not the full ParameterCatalog — only the parameters relevant to client-side authentication, authorization and session management. Sensitive parameters (connection strings, secrets) are never included.
scopes (array of strings, required, may be empty)OAuth2-style scopes derived from the Allow entries in menuAccess and domainPermissions. Format: "{resourceCode}.{actionCode}".
"scopes": ["STOCK_VIEW.VIEW", "STOCK_ADJUST.UPDATE", "PURCHASE_ORDER.VIEW"]
Deny entries are not present in scopes — they are exposed only via the resolved trees so the SDK can apply deny-precedence. Some SDKs surface a derived denies list for ergonomic checks (see runtime guides).
generatedAt / validUntil (string, required)ISO-8601 UTC timestamps. The SDK MUST check validUntil > now before applying any authorization decision; if validUntil <= now, the decision is Expired and the client should re-authenticate.
The schema treats enumerations in two categories:
| Closed (rejection on unknown) | Open (preserved with warning) |
|---|---|
effect: Allow/Deny/NotGranted |
tenant.status, user.status (can add categories) |
source: Template/Override |
authentication.method (Local/IDP today, more future) |
profile.scope: OrgWide/BranchScoped |
resource.type (Aggregate/Entity today) |
Closed enumerations affect authorization decisions directly — an unknown value would be unsafe to interpret. Open enumerations are informational; unknown values are preserved and surfaced via UnknownFieldsObservedEvent.
Every fixture under src/libs/sdk/contracts/fixtures/ must:
auth-graph.schema.json.CI enforces this on every PR — see fixtures.md.