Skip to main content

06 โ€” Authentication Flow

Status: ๐Ÿ”ง Partial โ€” confirmed sections complete; C-001 sections pending ITS Technical session
Prerequisite: TD2, TD3, 01 โ€” Service Decomposition
Next: 07 โ€” Authorization Model

End-to-end authentication design โ€” how a request from a module reaches a Core engine with verified identity. Covers the two-identity model, the Identity Bridge, ITS SSO token flow, API key validation, token lifecycle, and sequence diagrams.

Sections marked โณ are blocked on the ITS Technical session (C-001). Everything else is confirmed from TD2 and TD3.


1. The Two-Identity Modelโ€‹

Every request that reaches Core carries one of two identity types. There is no third option.

Identity typeWho uses itCredentialSet by
Human identityA Mumin taking an action in a module UIITS bearer token (JWT)Module โ€” attaches the user's ITS session token
System identityA module background process, batch job, or automated workflowAPI keyModule โ€” uses the key issued by Platform Admin at onboarding

The Identity Bridge at the API Gateway determines which identity type is present based on the Authorization header, validates it, and strips the credential before routing the request downstream. Core engines never see the raw token or API key โ€” they only see the clean headers the Bridge sets.

Confirmed in TD3: ITS is the only identity provider on the platform. Core does not maintain its own user database. Core does not handle login or session management. A module's users are always ITS users.


2. Identity Bridgeโ€‹

The Identity Bridge is the authentication layer inside the API Gateway. It runs before every request reaches any Core engine.

What it doesโ€‹

Module request
โ”‚
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Identity Bridge โ”‚
โ”‚ โ”‚
โ”‚ 1. Detect credential type โ”‚
โ”‚ (ITS token vs API key) โ”‚
โ”‚ โ”‚
โ”‚ 2. Validate credential โ”‚
โ”‚ (signature, expiry, revocation) โ”‚
โ”‚ โ”‚
โ”‚ 3. Extract identity โ”‚
โ”‚ (itsId or moduleId) โ”‚
โ”‚ โ”‚
โ”‚ 4. Strip credential from request โ”‚
โ”‚ โ”‚
โ”‚ 5. Set clean headers โ”‚
โ”‚ X-Its-Id, X-Module-Id, โ”‚
โ”‚ X-Correlation-Id โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ”‚
โ–ผ
Core engine receives clean headers only

What the engine seesโ€‹

After the Bridge processes a user-initiated request:

X-Module-Id: vms
X-Its-Id: ITS-1234567
X-Correlation-Id: 550e8400-e29b-41d4-a716-446655440000

After the Bridge processes a system-initiated request:

X-Module-Id: vms
X-Correlation-Id: 6ba7b810-9dad-11d1-80b4-00c04fd430c8
(no X-Its-Id)

Engines that require a human context check for the presence of X-Its-Id. If it is absent on an endpoint that requires it, the engine returns AUTH_ITS_ID_REQUIRED (403).

X-Correlation-Id lifecycleโ€‹

The module generates a UUID and sends it as X-Request-Id. The Bridge copies this value into X-Correlation-Id and forwards it downstream. From that point:

  • Every engine writes it to its logs on every log line for that request
  • If an engine makes an internal call to another engine, it forwards the same X-Correlation-Id so the chain stays traceable
  • The engine echoes it back as requestId in the response envelope โ€” the module receives the same UUID it sent
  • The value has no storage lifecycle โ€” it exists only in logs and the in-flight request

This means a single UUID traces a user action from the module โ†’ Bridge โ†’ engine โ†’ any internal engine calls โ†’ back to the module. If something fails anywhere in that chain, the requestId in the error response is enough to pull the full trace from logs.

What the Bridge rejects before routingโ€‹

ConditionError returned to module
Authorization header missing entirelyAUTH_INVALID_API_KEY (401)
ITS token signature invalidAUTH_ITS_TOKEN_INVALID (401)
ITS token expiredAUTH_ITS_TOKEN_EXPIRED (401)
API key not recognisedAUTH_INVALID_API_KEY (401)
API key revoked in Platform AdminAUTH_API_KEY_REVOKED (401)
Module API key calling a write endpointAUTH_MODULE_NOT_PERMITTED (403)
X-Module-Id header missing or not matching the keyAUTH_INVALID_API_KEY (401)

Rejected requests never reach the Core engine โ€” the Bridge returns the error directly.


3. User-Initiated Flow (ITS SSO Token)โ€‹

A human user takes an action in a module UI. The module calls Core with the user's ITS session token.

Sequenceโ€‹

Key pointsโ€‹

  • The module backend attaches the user's ITS token to its Core call โ€” the user is not calling Core directly
  • The ITS token is a short-lived JWT. The module is responsible for managing token refresh in its own session handling
  • The Bridge validates the token on every request โ€” there is no session state in the Bridge itself
  • X-Its-Id is set by the Bridge, not by the module. A module that passes X-Its-Id in its own headers has it overwritten by the Bridge

4. System-Initiated Flow (API Key)โ€‹

An automated module process calls Core without a human user in context โ€” batch jobs, scheduled syncs, background workflows.

Sequenceโ€‹

Key pointsโ€‹

  • API keys are issued per module at onboarding โ€” one key per module, managed in Platform Admin
  • API keys are read-only by default. Write endpoint calls with a module API key are rejected at the Bridge before reaching the engine
  • A revoked API key is rejected immediately โ€” no grace period
  • There is no X-Its-Id on system-initiated calls. Engines that require human context reject these with AUTH_ITS_ID_REQUIRED (403)

5. API Key Managementโ€‹

ConcernDetail
IssuancePlatform Admin issues one API key per module at onboarding
ScopeRead-only access to all module-facing Core endpoints. Write endpoints require Platform Admin credentials.
RotationModule teams request key rotation through Platform Admin. Old key is valid for a 24-hour overlap window to allow the module to deploy the new key without downtime.
RevocationPlatform Admin can revoke a key immediately. Revoked keys fail at the Bridge โ€” no grace period.
StorageModule teams must store API keys in their secrets management system. Keys must not be committed to source code or placed in environment files that are checked in.

6. ITS Token Validationโ€‹

โณ Blocked on C-001 โ€” ITS Technical session

The exact validation mechanism depends on how ITS issues and signs its tokens. The following describes the expected pattern โ€” to be confirmed and completed after the ITS Technical session.

Expected token formatโ€‹

ITS tokens are expected to be JWTs (JSON Web Tokens) carrying claims that include at minimum:

ClaimExpected valueNotes
sub or itsIdITS-1234567The Mumin's ITS identifier โ€” exact claim name TBC in C-001
expUnix timestampToken expiry โ€” Bridge checks this on every request
issITS issuer URLBridge validates the issuer matches the configured ITS endpoint โ€” exact URL TBC

Expected validation stepsโ€‹

  1. Parse JWT header to identify signing algorithm
  2. Fetch ITS public key (via JWKS endpoint or pre-configured public key โ€” TBC in C-001)
  3. Verify signature
  4. Check exp โ€” reject if expired
  5. Check iss โ€” reject if not the configured ITS issuer
  6. Extract itsId claim โ€” set as X-Its-Id

Token lifecycleโ€‹

โณ TBC in C-001

  • Whether ITS issues refresh tokens alongside access tokens
  • Whether Core needs to handle token refresh on behalf of modules, or whether modules handle this in their own session management
  • Maximum token TTL and whether it can be configured per Miqaat

7. Platform Admin Authenticationโ€‹

Platform Admin users are Mumineen โ€” they have ITS IDs. They authenticate via ITS SSO exactly like any other user. There is no separate credential system for Platform Admin.

How it worksโ€‹

  1. A Platform Admin user logs in to the Platform Admin console via ITS SSO
  2. The console receives their ITS bearer token
  3. When the console calls Core APIs, it attaches the token โ€” same flow as any module
  4. The Identity Bridge validates the token and sets X-Its-Id to their itsId
  5. The Gateway checks whether that itsId holds the PLATFORM_ADMIN role in Core's RBAC
  6. If the role is confirmed, the request is routed โ€” including to write endpoints and internal-only endpoints
  7. If not, the request is rejected with AUTH_MODULE_NOT_PERMITTED (403) regardless of token validity

What the PLATFORM_ADMIN role grantsโ€‹

AccessRegular module userPLATFORM_ADMIN role holder
Read endpoints (C-010 to C-019)โœ…โœ…
Write endpoints (POST /v1/miqaat, POST /v1/rbac/assign, etc.)โŒโœ…
Internal-only endpoints (GET /v1/audit/query, GET /v1/its/mumin/{itsId}, etc.)โŒโœ…
Module API key issuance and revocationโŒโœ…
Role assignment for all other rolesโŒโœ…

PLATFORM_ADMIN is a platform-level role โ€” not Miqaat-scopedโ€‹

All other RBAC roles in Core are scoped to a miqaatId (e.g. VMS_Coordinator for MQ-1447-KHI). PLATFORM_ADMIN is different โ€” it is scoped at the platform level, not per Miqaat. A Platform Admin user has elevated access across all Miqaats.

Bootstrapping โ€” the first Platform Adminโ€‹

PLATFORM_ADMIN role assignment normally goes through the RBAC Engine write endpoint (POST /v1/rbac/assign). But that endpoint itself requires a PLATFORM_ADMIN role to call. This is a bootstrapping problem โ€” who assigns the first Platform Admin?

This requires a seed process at Core deployment: a one-time script run during initial infrastructure setup that directly writes the first PLATFORM_ADMIN role assignment into the RBAC data store, bypassing the API layer. Only the Core technical team runs this, once, at deployment. All subsequent Platform Admin assignments go through the normal API flow by an existing Platform Admin.

โณ Exact seed process and tooling โ€” Infrastructure session

Multiple Platform Adminsโ€‹

More than one itsId can hold PLATFORM_ADMIN. Each holds it as an individual โ€” there is no shared account. Audit logs record which itsId performed each write operation, so every Platform Admin action is attributable to a specific person.

PLATFORM_ADMIN can be revoked by any other active Platform Admin via POST /v1/rbac/revoke. The platform must always have at least one active Platform Admin โ€” the system should warn (not block) if the last Platform Admin attempts to self-revoke.


8. Internal Engine-to-Engine Callsโ€‹

Core engines occasionally call each other during request processing โ€” for example, the Allocation Engine calling the Rule Engine before confirming an allocation.

These internal calls do not pass through the Identity Bridge. They use internal network credentials scoped to the Core infrastructure. The originating itsId is propagated through the X-Correlation-Id header for tracing โ€” not through a new token.

โณ Exact internal credential model TBC โ€” Infrastructure session


9. Open Questionsโ€‹

QuestionBlocked On
Exact ITS JWT claim name for itsIdC-001 โ€” ITS Technical session
ITS JWKS endpoint URL and key rotation policyC-001
Token TTL and refresh mechanismC-001
Whether Bridge caches JWKS or fetches per requestInfrastructure session (performance trade-off)
Internal engine-to-engine credential modelInfrastructure session
Token revocation โ€” does ITS support token introspection for mid-session revocation?C-001
PLATFORM_ADMIN seed process tooling and who runs it at deploymentInfrastructure session
Minimum Platform Admin count enforcement โ€” warn vs hard block on last-admin self-revokeArchitecture decision