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 type | Who uses it | Credential | Set by |
|---|---|---|---|
| Human identity | A Mumin taking an action in a module UI | ITS bearer token (JWT) | Module โ attaches the user's ITS session token |
| System identity | A module background process, batch job, or automated workflow | API key | Module โ 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-Idso the chain stays traceable - The engine echoes it back as
requestIdin 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โ
| Condition | Error returned to module |
|---|---|
Authorization header missing entirely | AUTH_INVALID_API_KEY (401) |
| ITS token signature invalid | AUTH_ITS_TOKEN_INVALID (401) |
| ITS token expired | AUTH_ITS_TOKEN_EXPIRED (401) |
| API key not recognised | AUTH_INVALID_API_KEY (401) |
| API key revoked in Platform Admin | AUTH_API_KEY_REVOKED (401) |
| Module API key calling a write endpoint | AUTH_MODULE_NOT_PERMITTED (403) |
X-Module-Id header missing or not matching the key | AUTH_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-Idis set by the Bridge, not by the module. A module that passesX-Its-Idin 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-Idon system-initiated calls. Engines that require human context reject these withAUTH_ITS_ID_REQUIRED (403)
5. API Key Managementโ
| Concern | Detail |
|---|---|
| Issuance | Platform Admin issues one API key per module at onboarding |
| Scope | Read-only access to all module-facing Core endpoints. Write endpoints require Platform Admin credentials. |
| Rotation | Module 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. |
| Revocation | Platform Admin can revoke a key immediately. Revoked keys fail at the Bridge โ no grace period. |
| Storage | Module 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:
| Claim | Expected value | Notes |
|---|---|---|
sub or itsId | ITS-1234567 | The Mumin's ITS identifier โ exact claim name TBC in C-001 |
exp | Unix timestamp | Token expiry โ Bridge checks this on every request |
iss | ITS issuer URL | Bridge validates the issuer matches the configured ITS endpoint โ exact URL TBC |
Expected validation stepsโ
- Parse JWT header to identify signing algorithm
- Fetch ITS public key (via JWKS endpoint or pre-configured public key โ TBC in C-001)
- Verify signature
- Check
expโ reject if expired - Check
issโ reject if not the configured ITS issuer - Extract
itsIdclaim โ set asX-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โ
- A Platform Admin user logs in to the Platform Admin console via ITS SSO
- The console receives their ITS bearer token
- When the console calls Core APIs, it attaches the token โ same flow as any module
- The Identity Bridge validates the token and sets
X-Its-Idto their itsId - The Gateway checks whether that itsId holds the
PLATFORM_ADMINrole in Core's RBAC - If the role is confirmed, the request is routed โ including to write endpoints and internal-only endpoints
- If not, the request is rejected with
AUTH_MODULE_NOT_PERMITTED (403)regardless of token validity
What the PLATFORM_ADMIN role grantsโ
| Access | Regular module user | PLATFORM_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โ
| Question | Blocked On |
|---|---|
Exact ITS JWT claim name for itsId | C-001 โ ITS Technical session |
| ITS JWKS endpoint URL and key rotation policy | C-001 |
| Token TTL and refresh mechanism | C-001 |
| Whether Bridge caches JWKS or fetches per request | Infrastructure session (performance trade-off) |
| Internal engine-to-engine credential model | Infrastructure session |
| Token revocation โ does ITS support token introspection for mid-session revocation? | C-001 |
| PLATFORM_ADMIN seed process tooling and who runs it at deployment | Infrastructure session |
| Minimum Platform Admin count enforcement โ warn vs hard block on last-admin self-revoke | Architecture decision |