Skip to main content

How a record travels

In ABDM the request goes through the gateway and the HIE-CM, because that is where consent is checked and routing lives. The record itself goes straight from the system that holds it to a URL the requester nominated, encrypted so only the requester can open it.

The two sides

RoleWho takes itWhat it does hereMilestone
HIUThe organisation or citizen askingHolds a granted consent artefact, asks for the records it covers, receives them and decrypts themM3
HIPThe citizen or facility holding the recordHolds the records, validates the consent, packages, encrypts, signs and pushesM2

The HIE-CM sits between them for the request and the notifications, and never sees a record.

The whole path

Stage 1: the request

The HIU sends a health information request through the gateway, quoting a consent artefact the patient granted. It carries four things.

  • The consent id, the artefact that authorises the request.
  • The data push URL, where the HIP sends the records. It may differ from the HIU's registered gateway URL, which improves privacy and anonymity.
  • The date and time range of records wanted.
  • The encryption parameters: the HIU's public key and its nonce.

The HIE-CM generates a transaction id and gives it to both sides, which is how you correlate a push arriving later with a request you sent earlier.

Stage 2: validation, then transfer

Before the HIP retrieves anything it runs three checks.

  1. The consent id is valid and active. Not expired, not paused, not revoked.
  2. The requested date and time range falls inside the range the consent artefact permits. A wider window is refused, not trimmed.
  3. The encryption parameters are correct and compatible.

Only then does it package the records as FHIR bundles, encrypt, sign with its long term private key, and send with the transaction id to the data push URL.

Two failures land here: ABDM-1062, consent not granted, and ABDM-1063, date range given is invalid. Both codes also appear against a linking message, so read the code with the message.

Stage 3: the notifications that close it

Both sides call health-information/notify: the HIP to say the data was transmitted, the HIU to report success or failure on its side. Neither carries the record. They carry the fact that a transfer happened, which is what makes the exchange auditable for the patient.

Timing and size

ConstraintRule
Timeout20 minutes from the start of the request
Large datasetsSplit into multiple parts, for example CT or MRI images running to hundreds of megabytes
Very large filesStream rather than sending one payload

Treat retrieval and encryption as a background job, not work inside a web request.

The encryption

The scheme is Elliptic Curve Diffie-Hellman key exchange on Curve25519, with AES-GCM for the payload and HKDF to derive the session key. Only the HIU holding valid consent can read the data, and the design gives perfect forward secrecy: key material compromised later does not expose data exchanged earlier.

Who holds which key

Key materialGenerated byWhere it goes
Short term private key, DHSK(U)HIUNever leaves the HIU
Short term public key, DHPK(U)HIUSent with the request
Nonce, RAND(U), 32 bytesHIUSent with the request
Short term private key, DHSK(P)HIPNever leaves the HIP
Short term public key, DHPK(P)HIPSent with the encrypted data
Nonce, RAND(P), 32 bytesHIPSent with the encrypted data
Shared key, DHK(U,P)Computed independently by bothNever transmitted
Session key, SK(U,P), 256 bit AES-GCMDerived independently by bothNever transmitted
Long term private keyHIPNever leaves the HIP. Signs the encrypted payload.

A new key pair per exchange is what buys forward secrecy.

What the HIP does, step by step

Six steps, once consent has validated.

  1. Generate a key pair, DHSK(P) and DHPK(P), in the group the HIU specified.
  2. Generate a 32 byte random value, RAND(P).
  3. Compute the shared key DHK(U,P) from the HIU's public key DHPK(U) and the HIP's own private key DHSK(P).
  4. Derive the salt and IV by XOR of RAND(P) and RAND(U). The first 20 bytes are the salt for HKDF, the last 12 bytes the IV.
  5. Compute a 256 bit AES-GCM session key SK(U,P) with HKDF, from the shared key and that salt.
  6. Encrypt the data with that key and that IV.

The HIP then sends DHPK(P), RAND(P) and the encrypted data. The HIU derives the same session key from its own private key DHSK(U) and the HIP's public key DHPK(P), with salt and IV from the same XOR.

Build the shared key from the HIU's public key and the HIP's private key. That is the pairing that makes the Diffie-Hellman exchange work.

Do not write this yourself

Two reference implementations exist. Fidelius, at github.com/sukreet/fidelius, and the Fidelius CLI, which is Java, with worked examples for Node.js, Python, Ruby and PHP at github.com/mgrmtech/fidelius-cli that run the binary as a subprocess. A webinar covers the CLI from both sides, at youtu.be/rSir2gbkEmk from 2:33:52.

Where this is implemented