Identity Service — Sync Contract
Status: populated Owner: TBD Last updated: 2026-04-17 Companion: Service Template · 16 Offline & Sync
1. Scope
identity-service is a control-plane service. It is not an end-user offline aggregate. However, several aggregates interact with the offline protocol (device binding) and some read-only projections are replicated to the patient-chart offline bundle (e.g. cached provider profile for signing clinical notes).
2. Per-aggregate conflict policy
| Aggregate | Conflict policy | Rationale |
|---|---|---|
| User | server_authoritative | Credentials, status, and email must never be client-driven. Clients cannot mutate User while offline. |
| Session | server_authoritative | Sessions issued online only. Token refresh requires server. |
| Credential | server_authoritative | Password hashes must not leave identity-service. |
| MFAFactor | server_authoritative | Enrollment requires online verification step. |
| Device | server_authoritative (with offline-emitted signals) | Registration is online. Offline device emits usage beacons consumed when back online; conflicts resolved by most-recent-server-update-wins; beacons never override server state. |
| BindingCertificate | server_authoritative; append-only on client | Client holds signed cert; server can revoke. Client cache of revocation list uses LWW on revoked_at. |
| APIKey | server_authoritative | Secrets only issued server-side. |
| ServiceAccount | server_authoritative | — |
| ExternalIdentity | server_authoritative | OIDC/SAML only meaningful online. |
| Module | server_authoritative | Global catalogue; read-only on clients. |
| LicenseAssignment | server_authoritative; client reads cached effective set | Client cannot mutate. Offline clients honour last-known effective set until absoluteExpiresAt of binding cert. |
| LicenseAssignmentHistory | append_only | Never mutated once written. |
3. Client behaviour while offline
| Behaviour | Rule |
|---|---|
| Token refresh | Impossible offline. Access JWT continues to be accepted by offline-capable services until exp. Binding cert provides stronger offline proof. |
| Session revocation | Offline revocation honoured via signed CRL-like delta shipped during next sync. |
| Licensing | Client caches last-known effective set for (tenantId, providerId, nodeId). Cache lifetime ≤ binding cert expiry. On first online contact, client refreshes. If a module was revoked while offline, client shows license.pending-sync state and blocks new mutations on that module. |
| Device binding | Client cannot issue its own binding cert offline. Certificate carries expiry ≤ 30 days; offline-only workflow is guarded by this expiry. |
4. Sync event consumption
| Event | Consumer role | Effect |
|---|---|---|
identity.device.revoked.v1 | offline-capable clients via sync channel | Delete local binding cert; prompt re-auth on return to online |
identity.license.assignment.status_changed.v1 | offline-capable clients | Invalidate cached effective set; recompute after next sync |
identity.user.suspended.v1 | offline-capable clients | On next online ping, server rejects all further syncs and surfaces account-suspended screen |
5. Conflict examples
| Scenario | Resolution |
|---|---|
Client refreshes cached effective set while server has flipped diag.laboratory to suspended | Server wins. Client accepts new set; any queued actions against diag.laboratory created offline are marked license-revoked and require supervisor override or are discarded per tenant policy. |
| Client holds a binding cert revoked by admin | Next online call rejects with IDENT_DEVICE_REVOKED; device must re-register (requires MFA). |
Server side User.status changes to suspended while offline client has queued logins | Queued login attempts fail on sync; client clears local session tokens. |
6. Cross-reference
- 16 Offline-first and sync — global patterns.
- patient-chart-service/SYNC_CONTRACT — consumer of binding events.
- document-service/SYNC_CONTRACT — consumer of binding events.