The master data model and FHIR interoperability

What AWS HealthLake provides as a FHIR R4 store, how the four master entities map onto FHIR resources, and the master schema that has to exist outside FHIR.

markdownexamplev1J8ZS-SF0Gstage: designtrust: mixedservice: healthlakeservice: auroraservice: athenaservice: glueservice: comprehend-medicalservice: eventbridgeinterface: architectureAWS HealthLake FHIR R4 data storeFHIR Patient Practitioner Organization LocationSMART on FHIR and Bulk Data Accessmaster entity schema in Auroracrosswalk and attribute provenance tablesHealthLake integrated medical NLPFHIR Linkage resourcesOrganization partOf hierarchy limits

Created 21 Oct 2026 · Modified 23 Oct 2026 · 1 version

A healthcare master needs two data models, not one. FHIR is the interoperability model — the shape in which clinical systems exchange information. The master model is the governance shape, carrying survivorship decisions, provenance per attribute and the crosswalk. Conflating them is the most common design error in this pattern.

What HealthLake gives you

AWS describes it as "a HIPAA eligible service for storing, analyzing, and sharing health data in the cloud using the Fast Healthcare Interoperability Resources (FHIR) R4 specification". The version is stated unambiguously and repeatedly: FHIR R4.

The capabilities that matter for a master:

CapabilityWhat the documentation states
Transactional FHIR server"FHIR APIs for standard resource validation, SMART on FHIR authorization"
ImportNative import "from an Amazon S3 bucket to an HealthLake data store"
Export"Bulk data FHIR API export capabilities"
Chronological patient view"creates a complete view of each patient's medical history"
Integrated NLPExtracts entities and PHI, "stored as native FHIR R4 resources"
SQL accessNLP entities "accessed through FHIR R4 APIs or Amazon Athena (SQL)"
Duplicate detection"automatically detects and links duplicate records (Preview)"
Legacy conversionData Transformation Agent for C-CDA and CSV (Preview)

The standards conformance claim is specific, and it is the sentence that matters for any 21st Century Cures Act discussion: HealthLake "supports customer conformity to the latest ONC and CMS regulatory standards including: HL7 FHIR R4 APIs, FHIR Bulk Data Access, US Core IG STU, HL7 SMART App Launch Framework IG, OAuth 2.0, and OpenID Connect."

Two constraints belong next to that list. The clinical disclaimer is explicit — HealthLake "is not a substitute for professional medical advice, diagnosis, or treatment" and "should only be used in patient care or clinical scenarios after review by trained medical professionals applying sound medical judgment". And the two most MDM-relevant features, resource matching and the Data Transformation Agent, are both labelled Preview, which raises the eligibility question set out in document 04.

Mapping the four master entities

Master entityFHIR R4 resourceNatural identifiers
PatientPatientMRN per assigning system, SSN, member id
ProviderPractitioner, plus PractitionerRoleNPI, DEA, state licence
OrganisationOrganizationNPI type 2, tax id, CCN
LocationLocationFacility id, NPI where applicable

FHIR's identifier element is the reason HealthLake's matching works at all, and its semantics line up exactly with how healthcare identity actually behaves. HealthLake distinguishes "globally unique identifiers" such as an NPI or SSN, "matched on value", from "scoped identifiers" such as an MRN, which are "only unique within a namespace (a hospital, a state, a manufacturer)" and are "matched on the combination of the identifying system and value, so that MRN 456 at one hospital is never linked to MRN 456 at another". It also normalises identifier system URIs, treating an SSN under http://hl7.org/fhir/sid/us-ssn and urn:oid:2.16.840.1.113883.4.1 as the same identifier.

Design consequence: get the identifier.system URIs right at ingestion. A per-source registry of assigning authority to canonical system URI is small, dull and completely load-bearing. If two hospitals' MRNs arrive under the same system URI, you will create false links that no amount of downstream logic can repair.

When HealthLake finds a match it "creates a FHIR Linkage resource that points to the linked resources and leaves the originals unchanged". A Linkage is a first-class FHIR resource, so consumers that understand FHIR can traverse it. It also means the duplicates remain visible, which is correct for clinical safety and inconvenient for naive consumers — another reason the master needs its own resolved view.

The master schema outside FHIR

FHIR has no construct for "this attribute came from the registration system, was last confirmed on this date, won under this survivorship rule, and was overridden by this steward". That lives in Aurora PostgreSQL. A minimal but sufficient shape:

master_entity
  master_id            uuid   PK   -- yours, minted here, never a vendor match ID
  entity_type          text        -- patient | provider | organization | location
  status               text        -- active | merged_into | retired
  merged_into          uuid        -- set when a steward merges two masters
  created_at, updated_at, version  -- version increments on any attribute change

master_attribute
  master_id            uuid   FK
  attribute_name       text        -- family_name, birth_date, primary_address ...
  attribute_value      jsonb
  source_system        text        -- which source won
  source_record_id     text        -- the record in that source
  raw_object_key       text        -- the immutable S3 object it came from
  survivorship_rule    text        -- which rule selected this value
  confidence           numeric
  effective_from       timestamptz
  steward_override     boolean
  PK (master_id, attribute_name, effective_from)

crosswalk
  master_id            uuid   FK
  source_system        text
  source_record_id     text
  match_id             text        -- the Entity Resolution match ID for this run
  match_rule           text        -- rule number, or null for ML
  confidence           numeric     -- 0.0-1.0 for ML matches
  linkage_id           text        -- the HealthLake Linkage, where one exists
  first_seen, last_seen timestamptz
  PK (source_system, source_record_id)
  -- current state only; per-run history lives in an append-only journal (see document 06)

steward_decision
  decision_id          uuid   PK
  decision_type        text        -- merge | split | attribute_override | reject_match
  subject_master_ids   uuid[]
  payload              jsonb
  decided_by           text        -- the federated identity, never a shared account
  decided_at           timestamptz
  rationale            text

Four properties make this schema do its job.

master_id is yours. The Entity Resolution glossary defines a match ID only as "the ID generated by AWS Entity Resolution and applied to each matched record set ... part of the matching workflow metadata". It is run output. master_id is the identifier consumers see, and the crosswalk is what reconciles the two on every run.

Provenance is per attribute, not per record. A golden patient routinely has a surname from the EHR and an address from registration. Auditing "where did this value come from" only works at attribute granularity, with raw_object_key pointing back into the Object Lock bucket.

master_attribute is append-only. effective_from in the key gives history for free, which is both the audit trail and the ability to answer "what did we believe on this date".

steward_decision is an input, not a log. It is replayed after every match run, which is what stops reprocessing from reversing human judgement. See document 05.

Keep the source's own Unique ID discipline in mind on the way in: Entity Resolution requires "a unique identifier that you designate ... assigned to each row of input data", unique within a table, "maximum Unique ID length is 38 for a matching workflow". A composite of source system and record id can exceed 38 characters; hash it if so.

Which store answers which question

QuestionStoreWhy
Who is this patient, resolved?AuroraThe golden record with provenance
What is this patient's clinical history?HealthLakeFHIR R4, chronological
Which source records map to this master?Aurora crosswalkThe mapping is governance data
Give me a FHIR Bundle for an external appHealthLakeFHIR APIs, SMART on FHIR
How many duplicates did we resolve last month?Athena over S3Cheap analytics over match output
What changed in the master, and when?Aurora historyAppend-only attribute versions

Both directions of flow are legitimate. HealthLake can be a source — its Patient resources are input to the curated zone and then to matching. It can also be a consumer — the resolved master writes back a canonical Patient plus Linkage resources. A mature deployment does both, and the order matters: match in the resolve account, then write the resolved view to HealthLake, so the FHIR store reflects governed decisions rather than competing with them.

Unstructured text

Both HealthLake's integrated NLP and Comprehend Medical can mine free text. HealthLake's is the better fit when the text already lives in the FHIR store, because extracted entities "are stored as native FHIR R4 resources within a HealthLake data store". Comprehend Medical is the better fit in the pipeline, before data lands, and offers ontology linking: InferICD10CM links conditions to ICD-10-CM codes (the page names "the 2021 version"), InferRxNorm links medications to RxNorm, and InferSNOMEDCT links concepts to SNOMED CT.

Its DetectPHI operation detects the entity types AGE, DATE, NAME, PHONE_OR_FAX, EMAIL, ID, URL, ADDRESS and PROFESSION, all under the category PROTECTED_HEALTH_INFORMATION and each with a confidence score; document 04 covers what that does and does not amount to under HIPAA.

For a master specifically, the realistic use is narrow: recovering demographics from unstructured registration notes to improve match coverage, and detecting PHI that arrived in a field where it should not be. It is English-only — Comprehend Medical "only detects medical entities in English language (US-EN) texts" — and its confidence scores need a threshold you choose and defend.

Where FHIR is the wrong model

FHIR does model organisational structure, and getting this wrong is an easy way to lose a healthcare audience. The R4 specification states that "The Organization resource often exists as a hierarchy of organization resources, using the _part-of_ property to provide the association of the child to its parent organization", and Organization.partOf is defined as "The organization of which this organization forms a part". A separate OrganizationAffiliation resource exists alongside it.

The real limitation is narrower and more interesting, and the cardinality is the evidence: partOf is 0..1, one parent per organisation, with no element for effective dating. A health system needs several simultaneous rollups over the same organisations — legal entity, billing and TIN, service-line reporting — each with dates on it, so that "this rollup was true until April" is answerable. That is what an MDM hierarchy manager supplies and FHIR does not.

What FHIR genuinely has no concept of is a survivorship rule, a trust score or a steward. Linkage records that two resources are related; it does not express which attribute of which resource prevails. None of that is a defect — FHIR is an exchange format, not a governance model.

The practical division follows. Master lookups belong in Aurora, because the governance data they need — provenance, survivorship rationale, steward decisions, the crosswalk — exists only there. HealthLake serves exchange: FHIR APIs, Bulk Data export, SMART on FHIR. Its cost shape is worth knowing when sizing that role: a standing $0.27 per data store hour, roughly $197 per month per store, plus storage, with FHIR queries beyond 3,500 per hour charged at $0.015 per 10,000 on the Standard tier.

Read this document as markdown — the same bytes an agent receives.