Skip to main content

Identity Service — Event Schemas

Status: populated Owner: TBD Last updated: 2026-04-17 Companion: Service Template · 04 EDA · NAMING

All events ride the platform envelope (@ghasi/event-envelope v1). NATS JetStream transport. Event type = NATS subject. Format: identity.{aggregate}.{event}.v{N}.

1. Envelope (reference)

{
"specversion": "1.0",
"id": "evt_01H...",
"type": "identity.user.registered.v1",
"source": "ghasi-ehealth/identity-service",
"subject": "usr_01H...",
"time": "2026-04-17T09:00:00.000Z",
"datacontenttype": "application/json",
"traceparent": "00-...",
"tenantid": "ten_01H...",
"data": { "...": "event specific" }
}

2. Events produced

2.1 User & session

Event typeSubject (NATS)Retention classAvg. volumeSchema highlights
identity.user.registered.v1identity.user.registered.v17y (audit)lowuserId, tenantId, email, locale, backend, isProvider, createdAt
identity.user.email_verified.v1same7ylowuserId, tenantId, verifiedAt
identity.user.suspended.v1same7ylowuserId, tenantId, reason, suspendedBy, suspendedAt
identity.user.reactivated.v1same7ylowuserId, tenantId, reactivatedBy, reactivatedAt
identity.user.deactivated.v1same7ylowuserId, tenantId, reason, deactivatedBy, deactivatedAt
identity.user.password_changed.v1same7ymediumuserId, tenantId, changedBy (self|admin), changedAt
identity.user.mfa_enrolled.v1same7ylowuserId, tenantId, factorType (totp|webauthn|recovery), factorId, enrolledAt
identity.user.mfa_challenge_failed.v1same1y (security)mediumuserId, tenantId, factorType, reason
identity.user.logged_in.v1same1yhighuserId, tenantId, sessionId, deviceId, backend, vendor, amr[], ip, at
identity.session.created.v1same1yhighsessionId, userId, tenantId, deviceId, createdAt, absoluteExpiresAt
identity.session.revoked.v1same1ymediumsessionId, userId, tenantId, reason (user|admin|refresh_replay|suspend), revokedAt

Example — identity.user.suspended.v1

{
"userId": "usr_01H...",
"tenantId": "ten_01H...",
"reason": "security policy violation",
"suspendedBy": "usr_01admin...",
"suspendedAt": "2026-04-17T10:00:00Z"
}

2.2 Devices

Event typeRetentionHighlights
identity.device.registered.v17ydeviceId, userId, tenantId, fingerprintHash, ua, registeredAt
identity.device.bound_for_offline.v17ydeviceId, userId, tenantId, certId, publicKey, expiresAt, boundAt
identity.device.revoked.v17ydeviceId, userId, tenantId, reason, revokedAt

2.3 API keys & service accounts

Event typeRetentionHighlights
identity.api_key.issued.v17yapiKeyId, tenantId, userId, scopes[], issuedAt
identity.api_key.revoked.v17yapiKeyId, tenantId, revokedBy, revokedAt
identity.service_account.created.v17yserviceAccountId, clientId, tenantId?, createdBy, createdAt
identity.service_account.revoked.v17yserviceAccountId, clientId, revokedBy, revokedAt

2.4 Federated identity

Event typeRetentionHighlights
identity.external_identity.linked.v17yexternalIdentityId, userId, tenantId, issuer, subject, linkedAt

2.5 Licensing (merged module)

Event typeRetentionHighlights
identity.license.module.created.v17ymoduleId, code, name, category, dependencies[], isAlwaysOn, createdBy
identity.license.module.updated.v17ymoduleId, code, before{...}, after{...}, updatedBy
identity.license.assignment.created.v17yassignmentId, moduleCode, nodeId, tenantId, scope, status, effectiveFrom, effectiveTo, assignedBy, constraints
identity.license.assignment.status_changed.v17yassignmentId, moduleCode, nodeId, tenantId, previousStatus, newStatus, reason, changedBy
identity.license.assignment.constraints_updated.v17yassignmentId, moduleCode, nodeId, tenantId, before, after, updatedBy
identity.license.assignment.expired.v17yassignmentId, moduleCode, nodeId, tenantId, expiredAt (effective_to)

Example — identity.license.assignment.status_changed.v1

{
"assignmentId": "lic_01H...",
"moduleCode": "diag.laboratory",
"nodeId": "node_01H...",
"tenantId": "ten_01H...",
"previousStatus": "active",
"newStatus": "suspended",
"reason": "Payment pending",
"changedBy": "usr_superadmin_01H..."
}

3. Events consumed

EventProducerReaction
tenant.tenant.activated.v1tenant-serviceProvision Keycloak group bindings; enqueue Tenant Admin invite
tenant.tenant.suspended.v1tenant-serviceRevoke all sessions for tenant within TTL; emit session.revoked events
tenant.tenant.terminated.v1tenant-serviceMark users deactivated; revoke devices; terminate all license assignments
tenant.tenant.config.changed.v1tenant-serviceRefresh session/MFA policy cache when relevant key changes
tenant.user.invited.v1tenant-serviceCreate shadow user in pending_verification; send invite email
tenant.node.created.v1tenant-serviceEvict ancestor-chain cache for child nodes
tenant.node.moved.v1tenant-serviceEvict all licn:{tenantId}:*:node:* keys in affected subtree
audit.gdpr.subject_request.received.v1audit-serviceParticipate in erasure saga

4. Consumer reaction map (external)

EventConsumerReaction
identity.user.suspended.v1tenant-serviceEvict evaluation caches for user; mark memberships inactive
identity.user.deactivated.v1tenant-servicePurge role assignments; emit own cascade
identity.user.logged_in.v1audit-serviceAppend immutable audit log
identity.device.bound_for_offline.v1patient-chart-service, document-serviceDerive encryption keys for device
identity.license.assignment.status_changed.v1Kong edge pluginRefresh tenant module set for MODULE_NOT_ACTIVE enforcement
identity.license.assignment.status_changed.v1frontend shellToggle navigation items on next page load
identity.service_account.revoked.v1all servicesReject any active tokens from this client
Allaudit-servicePersist to audit log

5. Schema governance

ControlRule
Schema location@ghasi/api-contracts/events/identity/*.schema.json
Breaking changeForbidden on vN — introduce vN+1 with dual-publish overlap ≥ 2 releases
Registryschemas published to Confluent-compat registry on CI, schema-id included in envelope header schemaId
Conformance teststest/contract/*.schema.spec.ts — validate every emitted event against registered schema
Ordering guaranteeNATS JetStream per-subject FIFO; subject header = aggregate id for partitioning

6. Retention classes

ClassRetentionApplies to
audit-7y7 yearsUser lifecycle, licensing, service accounts, devices, external identity
security-1y1 yearLogins, MFA failures, session creations/revocations
ephemeral-30d30 days(none currently — reserved for future identity.rate_limit_hit.v1)