Recipe 5.9 Architecture and Implementation: National-Scale Patient Matching (TEFCA)

Companion to Recipe 5.9: National-Scale Patient Matching (TEFCA). This page covers the AWS architecture, services, prerequisites, and pseudocode. For the problem framing and the conceptual approach, start with the main recipe.


The AWS Implementation

Why These Services

Amazon API Gateway plus AWS WAF for the inbound TEFCA gateway. The TEFCA gateway exposes endpoints for the cross-network patient-discovery and document-query operations. API Gateway with WAF provides the public-facing endpoint with the appropriate authentication (mTLS for QHIN-to-participant authentication, signed-request validation for the QHIN's request signature), the appropriate rate limiting (per-QHIN rate limits to handle the federation's projected inflow), and the appropriate audit logging. The WAF rules block obvious abuse patterns (request-flooding from a single source, malformed request payloads) before the requests reach the application layer.

AWS Lambda for the per-query handler logic. Each inbound federated query is handled by a Lambda invocation that authenticates the request, validates the exchange-purpose and authorization context, and dispatches to the local matcher. Each outbound federated query is similarly handled by a Lambda that formulates the query, attaches the authorization context, and submits to the QHIN. The per-Lambda execution role is least-privileged: the inbound handler can read the local MPI but cannot mutate it; the outbound handler can submit to the QHIN through a designated Secrets-Manager-managed credential but cannot access any other federation endpoint.

Amazon DynamoDB for the federation-attribution and audit metadata. The full attribution chain (originating user, originating sub-participant, originating QHIN, routing path, responding sub-participant, responding source organization) for every query and every response is stored in DynamoDB with customer-managed KMS encryption, point-in-time recovery, and DynamoDB Streams to drive the cross-recipe event fan-out. The table's keying scheme (query_id as partition key, attribution_event_id as sort key) supports per-query queries and per-response audit reconstruction.

Amazon RDS for Aurora PostgreSQL or Amazon Aurora Serverless for the local MPI. The local MPI is the participant's master patient index that the cross-network matcher consults. The MPI is typically a relational store (the institution's existing MPI vendor's product, an Aurora-backed custom implementation, or an Aurora-fronted view over the participant's existing MPI). The MPI's matching logic is in scope for recipe 5.1; the cross-network-tolerance variant is in scope for this recipe.

Amazon ElastiCache for Redis for the candidate-set caching. Cross-network queries have a long tail of repeat queries from the same source against the same patient (the same patient is queried multiple times across her care episode); caching the candidate set in Redis reduces the local-matcher load and improves the response-time consistency. The cache is keyed on the query's normalized demographic-feature payload (with appropriate cryptographic salting to prevent cross-query inference) and is TTL'd to the use-case-appropriate freshness (treatment queries cache for minutes; payment queries cache for hours; population-health queries cache for days).

AWS Step Functions for the document-query-and-retrieval orchestration. The document-query-and-retrieval flow is multi-step: receive the candidate selection, formulate document-query requests for each candidate, submit through the QHIN federation, consume the responses, consolidate the documents into the user's view. Step Functions orchestrates the flow with per-step retries, per-step error routing to DLQs, parallel execution across candidates, and explicit synchronization at the consolidation step.

Amazon S3 for the document-store substrate. The retrieved documents are persisted to S3 with SSE-KMS encryption, lifecycle to S3 Glacier for the audit-retention floor, and Object Lock in Compliance mode for the audit-archive bucket. The per-document attribution metadata is stored alongside the document (with the originating-source attribution, the retrieval-context attribution, the consent-context attribution).

Amazon EventBridge for the federation-event fan-out. When a cross-network query completes, when a dispute is raised, when a governance change is processed, when a consent withdrawal is recorded, an event flows out to the per-participant operational systems, the cross-recipe consumers, and the analytics consumers. EventBridge rules route events to the right consumer with DLQs for failed deliveries.

Amazon Cognito for the patient-portal authentication on patient-mediated flows. Where the cross-network query is patient-mediated (the patient is the originator through a personal-health-record app), Cognito provides the patient-portal authentication. The personal-health-record app exchanges the patient's credentials for an OAuth token; the token carries the patient-mediated attribution that subsequent hops in the federation honor.

AWS Secrets Manager for the QHIN credentials and the cryptographic-signing keys. The participant's QHIN-facing credentials (mTLS certificates, signing keys, OAuth client credentials) are stored in Secrets Manager with customer-managed KMS encryption and rotation. The signing keys for outbound query signing and inbound response validation are loaded into the Lambda execution context per-invocation; the keys themselves never leave the Secrets Manager context.

AWS KMS and AWS CloudHSM for the cryptographic-key custody. Customer-managed KMS keys for the audit metadata, the federation attribution, the document store, and the Secrets Manager secrets. CloudHSM where the institutional security posture or the federation's framework requires single-tenant HSM-backed key custody (some federal participants and some high-assurance state HIEs operate under this requirement).

Amazon SageMaker for the cross-network-tolerance calibration and the cohort-stratified-accuracy reporting. The cross-network matching tolerance is calibrated against a curated calibration set (synthetic data plus opt-in pilot data from collaborating participants) using SageMaker training jobs. The cohort-stratified-accuracy reports run as SageMaker Processing jobs against the federated-discovery-response audit data, stratified by the cohort axes (geographic cohort, age cohort, sex/gender cohort, name-tradition cohort, jurisdictional-overlay cohort).

Amazon Athena, AWS Glue Data Catalog, and AWS Lake Formation for the audit-and-analytics surface. The federation attribution data, the per-query audit-event log, and the per-participant performance metrics surface through Athena queries with Lake Formation column-level and row-level access controls. Treatment-context users see the institution's own portion of the attribution chain; cross-QHIN-coordination users see the full attribution chain for dispute resolution; audit-and-compliance users see the full audit-event log; the institutional governance committee sees the federation-level metrics.

AWS PrivateLink for the QHIN-to-participant private network path. Where the QHIN and the participant operate in the same cloud and the participant's security posture requires private-network exchange, PrivateLink endpoints between the QHIN's VPC and the participant's VPC provide the private network path. The PrivateLink configuration is paired with VPC endpoint policies that enumerate the specific cross-account roles authorized to invoke the endpoint.

Amazon CloudWatch and AWS CloudTrail. CloudWatch metrics on per-source query rate, per-source response latency, per-source error rate, per-cohort match-rate disparity, dispute-resolution backlog, capacity-reservation utilization, federation-event throughput. CloudWatch alarms on rate-limit breaches, response-latency breaches, error-rate spikes, capacity-reservation breaches. CloudTrail data events on every audit-event read, every federation-attribution read, every secret-access, every KMS-key-use. Same chapter pattern as 5.1, 5.4, 5.5, 5.6, 5.7, 5.8.

Amazon QuickSight for operational and quality dashboards. Per-source query rate, per-source response latency, per-cohort match-rate trend, per-jurisdictional-overlay applicability rate, dispute-resolution-backlog trend, capacity-utilization trend, governance-event-volume trend.

Architecture Diagram

flowchart LR
    subgraph QHIN_External
      Q1[Other QHIN<br/>Federation Routes]
      Q2[Participant's QHIN<br/>Cross-Network Router]
    end

    subgraph Participant_VPC
      AG1[API Gateway<br/>+ WAF<br/>TEFCA Gateway]
      L1[Lambda<br/>inbound-query-handler]
      L2[Lambda<br/>outbound-query-formulator]
      L3[Lambda<br/>response-consolidator]
      L4[Lambda<br/>sensitivity-overlay-applicator]
      EC1[(ElastiCache Redis<br/>candidate-cache)]
      RDS1[(Aurora PostgreSQL<br/>Local MPI)]
      SF1[Step Functions<br/>document-query-orchestrator]
      L5[Lambda<br/>document-retrieval-handler]
    end

    subgraph Federation_Substrate
      DDB1[(DynamoDB<br/>federation-attribution)]
      DDB2[(DynamoDB<br/>audit-event-log)]
      DDB3[(DynamoDB<br/>jurisdictional-overlay-config)]
      DDB4[(DynamoDB<br/>consent-state)]
      S3D[(S3 document-store<br/>SSE-KMS)]
      S3A[(S3 audit-archive<br/>Object Lock Compliance)]
    end

    subgraph Identity_Substrate
      SM1[(Secrets Manager<br/>QHIN credentials,<br/>signing keys)]
      KMS1[(AWS KMS<br/>customer-managed keys)]
      HSM1[(AWS CloudHSM<br/>high-assurance custody)]
      COG1[Cognito<br/>patient-portal IdP]
    end

    subgraph Operational_Substrate
      EB1[EventBridge<br/>federation-events-bus]
      SQS1[SQS<br/>dispute-queue]
      SQS2[SQS<br/>governance-evolution-queue]
      SM2[SageMaker<br/>cross-network-tolerance<br/>calibration]
      SM3[SageMaker<br/>cohort-stratified-accuracy]
    end

    subgraph Analytics_Substrate
      AT1[Athena]
      LF1[Lake Formation<br/>column-and-row access]
      QS1[QuickSight<br/>operational and quality<br/>dashboards]
      CW1[CloudWatch<br/>metrics and alarms]
      CT1[CloudTrail<br/>audit logs]
    end

    Q1 -->|cross-QHIN routing| Q2
    Q2 -->|inbound query| AG1
    AG1 --> L1
    L1 --> L4
    L4 --> RDS1
    L4 --> EC1
    L4 --> DDB3
    L4 --> DDB4
    L4 --> DDB1
    L4 --> DDB2
    L4 -->|signed response| Q2

    COG1 -->|patient auth| L2
    L2 --> SM1
    L2 -->|outbound query| Q2
    Q2 -->|outbound response| L3
    L3 --> SF1
    SF1 --> L5
    L5 --> S3D
    L5 --> DDB1
    L5 --> DDB2

    SM1 --> KMS1
    HSM1 --> KMS1
    KMS1 --> RDS1
    KMS1 --> DDB1
    KMS1 --> DDB2
    KMS1 --> S3D
    KMS1 --> S3A

    DDB1 --> EB1
    EB1 --> SQS1
    EB1 --> SQS2
    EB1 -->|FanOut| C5[Recipe 5.5<br/>cross-facility matcher]
    EB1 -->|FanOut| C6[Recipe 5.6<br/>claims-clinical linkage]
    EB1 -->|FanOut| C7[Recipe 5.7<br/>longitudinal name-change]
    EB1 -->|FanOut| C8[Recipe 5.8<br/>privacy-preserving linkage]
    EB1 -->|FanOut| C9[Internal operational<br/>systems]

    DDB2 --> AT1
    DDB1 --> AT1
    S3A --> AT1
    AT1 --> LF1
    AT1 --> QS1
    SM2 --> RDS1
    SM3 --> DDB2
    L1 --> CW1
    L2 --> CW1
    L3 --> CW1
    AG1 --> CT1
    L1 --> CT1
    L2 --> CT1

    style RDS1 fill:#9ff,stroke:#333
    style DDB1 fill:#9ff,stroke:#333
    style DDB2 fill:#9ff,stroke:#333
    style DDB3 fill:#9ff,stroke:#333
    style DDB4 fill:#9ff,stroke:#333
    style S3D fill:#cfc,stroke:#333
    style S3A fill:#cfc,stroke:#333
    style SM1 fill:#fc9,stroke:#333
    style HSM1 fill:#fc9,stroke:#333
    style EB1 fill:#f9f,stroke:#333

Prerequisites

Requirement Details
AWS Services Amazon API Gateway, AWS WAF, AWS Lambda, Amazon DynamoDB, Amazon RDS for Aurora PostgreSQL (or the participant's existing MPI), Amazon ElastiCache for Redis, AWS Step Functions, Amazon S3, Amazon EventBridge, Amazon SQS, Amazon Cognito, AWS Secrets Manager, AWS KMS, AWS CloudHSM (where the higher-assurance custody is required), Amazon SageMaker, Amazon Athena, AWS Glue Data Catalog, AWS Lake Formation, AWS PrivateLink, Amazon QuickSight, Amazon CloudWatch, AWS CloudTrail.
External Inputs The participant's local MPI (the canonical patient identity store from recipe 5.1). The participant's QHIN's operational endpoints (the cross-QHIN router URL, the QHIN's signing certificate, the QHIN-issued participant credentials). The Common Agreement and the QHIN-Technical-Framework specifications. The participant's exchange-purpose authorization scope (which exchange purposes the participant is authorized to operate under). The participant's jurisdictional-overlay configuration (the per-jurisdiction overlay rules the participant honors). The participant's consent-state store (the per-patient consent posture for cross-network disclosure). Cross-recipe dependencies: recipe 5.1 local MPI, recipe 5.3 address standardization, recipe 5.5 cross-facility matching for the within-HIE matching, recipe 5.7 longitudinal-name-change for the time-varying-name handling, recipe 5.8 privacy-preserving linkage for the privacy-preserving-cross-organization use cases.
IAM Permissions Per-Lambda least-privilege: scoped dynamodb:GetItem / PutItem / Query on the federation-attribution and audit-event-log tables, secretsmanager:GetSecretValue on the QHIN-credentials-and-signing-keys secrets pinned to the current rotation, kms:Decrypt on the audit-and-attribution KMS keys, s3:PutObject / GetObject on the document-store and audit-archive buckets with prefix scoping, events:PutEvents on the federation-events bus, sqs:SendMessage on the dispute and governance-evolution queues. The inbound-query-handler Lambda has read-only access to the local MPI; mutations to the local MPI are explicitly out of scope for the cross-network handler. The outbound-query-formulator Lambda has signing-credential access through the per-rotation Secrets Manager secret; the credential is rotated on the framework-specified cadence. The patient-portal Cognito-authenticated flow has a separate IAM context that distinguishes patient-mediated queries from staff-initiated queries in the audit log. Per-step-function execution-role binding so Step Functions invokes only the role appropriate for the current document-query stage. Never use * actions or * resources in production.
BAA, Common Agreement, and QHIN Membership AWS BAA signed. Common Agreement signed (or, more typically, the participant signs a Participant or Sub-Participant Agreement with a designated QHIN, which has signed the Common Agreement with the RCE). Per-QHIN Participant Agreement that authorizes the participant for specific exchange purposes and specifies the operational requirements (uptime, response-time, capacity, audit retention). Per-jurisdiction overlay-rule agreements where the participant operates across multiple jurisdictions (post-Dobbs state laws, gender-affirming-care state laws, 42 CFR Part 2, HIV-and-genetic-information state-specific rules). Patient consent for cross-network disclosure where the institutional policy or the regulatory framework requires it.
Encryption API Gateway: TLS 1.2 or higher, mTLS for QHIN-to-participant authentication. Lambda log groups: KMS-encrypted. DynamoDB tables: customer-managed KMS at rest. Aurora PostgreSQL: customer-managed KMS at rest, TLS in transit. ElastiCache Redis: customer-managed KMS at rest, TLS in transit, AUTH-token-protected. S3 buckets: SSE-KMS with customer-managed keys. Audit-archive S3: SSE-KMS with customer-managed keys, Object Lock in Compliance mode. Secrets Manager: KMS-encrypted with the customer-managed key. CloudHSM (where used) for the higher-assurance signing-key custody. KMS key policies enforce least-privilege access; the inbound-query-handler Lambda role can decrypt audit-and-attribution data but cannot decrypt the signing-key material; the outbound-query-formulator Lambda role can use the signing key for signing operations but cannot export the key material. mTLS for QHIN-to-participant transport; mTLS for the cross-recipe EventBridge consumers where the consumer is in a different account.
VPC Production: all Lambdas in VPC. API Gateway with VPC endpoint where the participant's QHIN supports PrivateLink. VPC endpoints for DynamoDB, S3, Secrets Manager, KMS, CloudWatch Logs, EventBridge, SQS, Step Functions, Athena, STS, SageMaker. PrivateLink for the QHIN-to-participant exchange where the QHIN supports it. NAT Gateway for outbound HTTPS to the QHIN where PrivateLink is not used; outbound proxy with allow-list. Aurora PostgreSQL in a private subnet with no public-network reachability; security group enumerates the specific Lambda execution-role-bound ENIs authorized to connect. ElastiCache Redis in a private subnet with the same security-group discipline.
CloudTrail Enabled with data events on the federation-attribution and audit-event-log DynamoDB tables, the audit-archive S3 bucket, the document-store S3 bucket, the QHIN-credentials Secrets Manager secrets, the signing-key KMS keys. Lambda invocations logged. Step Functions executions logged. EventBridge events logged. CloudTrail logs encrypted with KMS and retained for the longest of: (1) HIPAA 7-year minimum, (2) the QHIN's Common-Agreement-specified audit-retention floor (the QTF specifies a minimum that participants must honor), (3) state medical-records-retention for the jurisdictions the participant operates in, (4) the participant's institutional retention floor, (5) the cross-jurisdictional retention overlay where the participant operates across borders, and (6) the cross-recipe coordination retention floor (events that interact with recipes 5.5 / 5.7 / 5.8 may impose a longer floor than the standalone TEFCA framework). For QHIN-credential and signing-key audit events specifically, store in a separately access-controlled S3 bucket with the framework's specified retention floor plus an additional period for post-deployment audit reconstruction, with access limited to the institutional security team and the compliance team. Audit logs in a dedicated S3 bucket with Object Lock in Compliance mode and lifecycle to S3 Glacier Deep Archive after 90 days; CloudTrail data events forwarded to a dedicated audit AWS account. Same chapter pattern as 5.1, 5.4, 5.5, 5.6, 5.7, 5.8.
Reference Data and Federation Configuration A versioned reference-data store with: the participating QHIN's operational endpoints, the QHIN's public-signing-key version (rotated per framework cadence), the participant's QHIN-issued credentials (rotated per framework cadence), the cross-network-matching-tolerance configuration (per use case: treatment, payment, healthcare operations, public health, individual access services), the per-jurisdiction overlay rules, the participant's exchange-purpose authorization scope. The reference data refreshes on a regular cadence and is versioned so each query references the configuration version active at the query time.
Sample Data Synthetic data with modeled cross-organizational and cross-jurisdictional populations. Synthea generates synthetic patient populations; extending Synthea to produce a federation-modeled population (the same synthetic patients appearing across multiple synthetic participants with appropriate demographic-feature variation) is feasible. The RCE may publish reference test data for QHIN designation; the participant's QHIN may have its own onboarding test data. Pilot federation testing against a curated cohort of opt-in patients (with explicit consent for the pilot) provides the operational validation. Never use real PHI in development environments.
Cost Estimate At a participant operating at a national-medical-center scale (one million patients in the local MPI, ten thousand cross-network queries per day, integration with two QHINs): API Gateway plus WAF typically $200-800 per month; Lambda invocations typically $100-400 per month at this volume; DynamoDB for federation-attribution and audit typically $300-1,200 per month; Aurora PostgreSQL for the local MPI typically $1,000-3,000 per month (depends on the existing MPI substrate); ElastiCache Redis for candidate caching typically $150-500 per month; S3 storage for documents and audit typically $200-1,000 per month; KMS, Secrets Manager, EventBridge, SQS, Step Functions, SageMaker, Athena, QuickSight in aggregate typically $500-1,500 per month; CloudHSM (where used) typically $1,500-2,500 per month for the dedicated HSM. Total AWS infrastructure typically $3,500-11,000 per month at this scale, dominated by Aurora PostgreSQL and CloudHSM (where used). The QHIN participation fees are separate and are paid to the QHIN under the Participant Agreement; the fees vary by QHIN.

Ingredients

AWS Service Role
Amazon API Gateway TEFCA gateway endpoint for inbound cross-network queries from the participant's QHIN; outbound query submission endpoint to the QHIN
AWS WAF Public-endpoint protection for the TEFCA gateway: rate limiting per-QHIN, malformed-payload blocking, abuse-pattern detection
AWS Lambda Per-query handler logic: inbound-query-handler, outbound-query-formulator, response-consolidator, sensitivity-overlay-applicator, document-retrieval-handler, dispute-handler, governance-evolution-handler
Amazon DynamoDB Federation-attribution table (per-query attribution chain), audit-event-log table (per-query and per-response audit), jurisdictional-overlay-config table (versioned overlay rules), consent-state table (per-patient consent posture)
Amazon RDS for Aurora PostgreSQL Local MPI for the participant; the cross-network matcher consults the MPI under the cross-network tolerance
Amazon ElastiCache for Redis Candidate-set cache for repeat queries; TTL'd to the use-case-appropriate freshness
AWS Step Functions Document-query-and-retrieval orchestration with per-step retries, error routing to DLQs, parallel execution across candidates
Amazon S3 Document-store bucket for retrieved documents (SSE-KMS, lifecycle to Glacier); audit-archive bucket (SSE-KMS, Object Lock in Compliance mode, lifecycle to Glacier Deep Archive)
Amazon EventBridge Federation-event fan-out: tefca_query_completed, tefca_dispute_raised, tefca_dispute_resolved, tefca_governance_event_received, tefca_consent_withdrawn, tefca_credential_rotated
Amazon SQS Dispute queue (incoming and outgoing disputes), governance-evolution queue (Common Agreement updates, QTF updates, QHIN-framework updates)
Amazon Cognito Patient-portal authentication for patient-mediated cross-network queries
AWS Secrets Manager QHIN-issued credentials, signing keys, OAuth client credentials with rotation per framework cadence
AWS KMS Customer-managed encryption keys for the federation-attribution and audit-event-log tables, the local MPI, the candidate-set cache, the document-store and audit-archive buckets, the Secrets Manager secrets
AWS CloudHSM Single-tenant hardware-security-module for the high-assurance signing-key custody (where the institutional security posture or the federation's framework requires it)
Amazon SageMaker Cross-network-tolerance calibration over the curated calibration set; cohort-stratified-accuracy reports against the federated-discovery-response audit data
Amazon Athena and AWS Glue Data Catalog SQL access to the federation attribution, audit event log, and cohort-stratified-accuracy snapshots
AWS Lake Formation Column-level and row-level access controls for the differentiated audiences (treatment, cross-QHIN coordination, audit, governance, analytics)
AWS PrivateLink Private network path for the QHIN-to-participant exchange where the QHIN supports it
Amazon QuickSight Operational and quality dashboards (per-source query rate, per-source response latency, per-cohort match-rate trend, per-jurisdictional-overlay applicability rate, dispute-resolution-backlog trend, capacity-utilization trend, governance-event-volume trend)
Amazon CloudWatch Operational metrics and alarms (rate-limit breaches, response-latency breaches, error-rate spikes, capacity-reservation breaches)
AWS CloudTrail Audit logging for all API calls on the federation-attribution and audit-event-log tables, the audit-archive and document-store buckets, the QHIN-credentials Secrets Manager secrets, the signing-key KMS keys

Code

Reference implementations: Useful patterns and reference materials for this recipe:

  • The Sequoia Project operates the Recognized Coordinating Entity for TEFCA and publishes the QHIN-Technical-Framework specifications and the Standard Operating Procedures.
  • The Office of the National Coordinator for Health Information Technology (ONC) publishes the Common Agreement and the regulatory baseline that TEFCA operates under.
  • IHE International publishes the integration profiles (XCPD for cross-community patient discovery, XCA for cross-community access) that the QTF references.
  • HL7 FHIR publishes the FHIR specification including the Patient $match operation and the Bulk FHIR specification used in TEFCA's emerging FHIR-based exchange patterns.
  • The Carequality framework is a related pre-TEFCA national framework whose patterns inform some of TEFCA's operational specifications.

Walkthrough

Step 1: Handle the inbound federated patient-discovery query. A query from the participant's QHIN arrives at the TEFCA gateway. The query carries the originating-attribution chain, the exchange-purpose claim, the demographic-feature payload, and the QHIN's request signature. The gateway authenticates the request, validates the attribution chain, validates the exchange-purpose claim against the participant's authorization scope, and dispatches the query to the local matcher with the appropriate authorization context. Skip the authentication-and-validation step and you accept malformed or unauthorized queries that produce wrong-record disclosures with audit-trail attribution to the QHIN that did not actually originate them.

FUNCTION handle_inbound_patient_discovery_query(
    request_payload, request_signature, request_metadata):

    // Step 1A: validate the QHIN's request signature.
    // The signature is verified against the QHIN's
    // current public-signing-key version. Rotation of
    // the signing key is coordinated through the QHIN's
    // operational interface; the participant maintains
    // both the current and the previous public-signing-key
    // version during the rotation window.
    qhin_id = request_metadata.qhin_id
    qhin_public_keys =
        load_qhin_public_keys(qhin_id,
                              include_previous_during_rotation=
                                  TRUE)

    IF NOT verify_signature_against_any(
            request_payload,
            request_signature,
            qhin_public_keys):
        audit_log({
            event_type:
                "TEFCA_INBOUND_QUERY_SIGNATURE_REJECTED",
            qhin_id: qhin_id,
            request_metadata: request_metadata,
            rejected_at: current UTC timestamp
        })
        RAISE InvalidQHINSignatureError()

    // Step 1B: validate the originating-attribution chain.
    // The chain identifies the originating user, the
    // originating sub-participant, the originating QHIN,
    // and the routing path. The participant honors only
    // chains from QHINs the participant has reciprocal
    // exchange relationships with.
    attribution_chain =
        request_payload.originating_attribution_chain

    IF NOT validate_attribution_chain(
            attribution_chain,
            participant_authorized_qhins=
                load_participant_authorized_qhins()):
        audit_log({
            event_type:
                "TEFCA_INBOUND_QUERY_ATTRIBUTION_REJECTED",
            attribution_chain: attribution_chain,
            rejected_at: current UTC timestamp
        })
        RAISE InvalidAttributionChainError()

    // Step 1C: validate the exchange-purpose claim. The
    // participant honors only the exchange purposes the
    // participant has authorized; treatment is the
    // dominant authorization, but other purposes (payment,
    // operations, public health, individual access
    // services, government benefits determination) require
    // explicit authorization.
    exchange_purpose = request_payload.exchange_purpose

    IF exchange_purpose NOT IN
        load_participant_authorized_exchange_purposes():
        audit_log({
            event_type:
                "TEFCA_INBOUND_QUERY_PURPOSE_REJECTED",
            exchange_purpose: exchange_purpose,
            rejected_at: current UTC timestamp
        })
        RETURN build_purpose_denied_response(
            attribution_chain, exchange_purpose)

    // Step 1D: build the authorization context that the
    // local matcher consults. The context combines the
    // exchange-purpose claim, the originating-attribution
    // chain (which sub-participant is requesting and what
    // its authorization is), the patient-mediated flag (if
    // the originating attribution is a patient), and the
    // applicable jurisdictional overlay rules.
    authorization_context = build_authorization_context(
        exchange_purpose=exchange_purpose,
        originating_attribution=attribution_chain,
        is_patient_mediated=
            attribution_chain.is_patient_mediated,
        jurisdictional_overlay_rules=
            load_jurisdictional_overlay_rules(
                requesting_jurisdiction=
                    attribution_chain.requesting_jurisdiction,
                participant_jurisdiction=
                    load_participant_jurisdiction()))

    // Step 1E: log the inbound query with the full
    // attribution chain.
    query_id = generate_query_id()
    audit_log({
        event_type: "TEFCA_INBOUND_QUERY_ACCEPTED",
        query_id: query_id,
        qhin_id: qhin_id,
        attribution_chain: attribution_chain,
        exchange_purpose: exchange_purpose,
        demographic_payload_summary:
            summarize_payload_for_audit(
                request_payload.demographic_features),
        accepted_at: current UTC timestamp
    })

    // Dispatch to the local matcher (Step 2).
    candidate_set = run_local_matcher_under_cross_network_tolerance(
        request_payload.demographic_features,
        authorization_context,
        query_id)

    // Apply the sensitivity overlay (Step 3).
    filtered_candidate_set = apply_sensitivity_overlay(
        candidate_set,
        authorization_context,
        query_id)

    // Build and return the response (Step 4).
    response = build_signed_federation_response(
        candidate_set=filtered_candidate_set,
        query_id=query_id,
        attribution_chain=attribution_chain,
        participant_signing_key=
            load_participant_signing_key())

    audit_log({
        event_type: "TEFCA_INBOUND_RESPONSE_DELIVERED",
        query_id: query_id,
        candidate_count: len(filtered_candidate_set),
        delivered_at: current UTC timestamp
    })

    RETURN response

Step 2: Run the local matcher under the cross-network tolerance. The local matcher consults the local MPI with a tolerance calibrated for cross-network use cases. The cross-network tolerance is typically higher-recall than the internal-application tolerance: the federation's queries that the participant should respond to are not silently dropped by an over-tight tolerance. Skip the dual-calibration and the federation's queries that the participant should respond to are silently dropped, which is an information-blocking compliance concern.

FUNCTION run_local_matcher_under_cross_network_tolerance(
    demographic_features, authorization_context, query_id):

    // Step 2A: load the cross-network matching tolerance
    // for the use case. The tolerance is calibrated
    // separately from the internal-application tolerance.
    matching_tolerance = load_cross_network_tolerance(
        exchange_purpose=
            authorization_context.exchange_purpose)

    // The tolerance includes:
    // - per-feature similarity-score weights
    // - per-feature missing-feature weights
    // - candidate-acceptance threshold (the score above
    //   which a candidate is included in the response)
    // - candidate-confidence threshold (the score above
    //   which a candidate is reported as high-confidence)
    // - max-candidate-count (the maximum number of
    //   candidates to include in the response, to bound
    //   the response size and to defeat deliberate-
    //   over-broadening attacks)

    // Step 2B: normalize the demographic features for
    // matching against the local MPI. The normalization
    // is the same as the internal-application matcher's
    // normalization plus any cross-network-specific
    // standardization (USPS for addresses, e164 for
    // phones, the QTF-specified date format for DOB).
    normalized_features = normalize_for_cross_network(
        demographic_features)

    // Step 2C: candidate-generation step (blocking).
    // The local MPI's blocking key generates candidate
    // identifiers; the matcher then evaluates each
    // candidate against the query.
    candidate_record_ids = local_mpi.block(
        normalized_features,
        matching_tolerance.blocking_strategy)

    // Step 2D: per-candidate scoring under the cross-
    // network tolerance.
    scored_candidates = []
    FOR EACH candidate_id IN candidate_record_ids:
        candidate_record = local_mpi.get(candidate_id)

        // Apply the consent-and-sensitivity filter at
        // candidate-evaluation time. Records the patient
        // has not consented to disclose for this exchange
        // purpose are excluded; records under
        // jurisdiction-specific suppression are excluded;
        // records under sensitivity-flag suppression
        // (gender-affirming-care, witness-protection)
        // are excluded.
        IF NOT consent_and_sensitivity_permits_disclosure(
                candidate_record,
                authorization_context):
            CONTINUE

        per_feature_similarity_scores =
            compute_per_feature_similarities(
                normalized_features,
                candidate_record.normalized_features,
                matching_tolerance)

        match_score = combine_with_fellegi_sunter(
            per_feature_similarity_scores,
            matching_tolerance.feature_weights,
            matching_tolerance.missing_feature_weights)

        IF match_score >= matching_tolerance
                            .candidate_acceptance_threshold:
            // Build the candidate envelope. The envelope
            // carries the demographic-feature subset that
            // the participant is willing to disclose for
            // cross-network discovery (typically a subset
            // of the local record's features), the
            // participant's local record identifier (an
            // opaque token that does not encode the
            // local record_id), the source-organization
            // attribution, and the match confidence.
            candidate_envelope = {
                opaque_record_token:
                    generate_opaque_record_token(
                        candidate_record.local_record_id,
                        query_id),
                disclosable_demographic_features:
                    extract_disclosable_features(
                        candidate_record,
                        authorization_context),
                source_organization_attribution:
                    candidate_record
                      .source_organization_attribution,
                match_score: match_score,
                match_confidence_tier:
                    classify_confidence_tier(
                        match_score, matching_tolerance),
                consent_posture_summary:
                    summarize_consent_for_candidate(
                        candidate_record,
                        authorization_context)
            }

            scored_candidates.append(candidate_envelope)

    // Step 2E: limit the candidate count to the per-query
    // max. If the candidate count exceeds the max, return
    // the highest-confidence subset and emit an audit
    // event indicating the truncation.
    IF len(scored_candidates) >
        matching_tolerance.max_candidate_count:
        scored_candidates = sort_by_confidence_desc(
            scored_candidates)
        scored_candidates = scored_candidates[
            0:matching_tolerance.max_candidate_count]
        audit_log({
            event_type:
                "TEFCA_INBOUND_QUERY_CANDIDATES_TRUNCATED",
            query_id: query_id,
            original_count: original_count,
            returned_count:
                matching_tolerance.max_candidate_count,
            truncated_at: current UTC timestamp
        })

    RETURN scored_candidates

Step 3: Apply the per-record-type sensitivity overlay and the jurisdictional overlay. The candidate set is filtered through the applicable overlay rules before disclosure. The overlay rules are versioned and per-jurisdiction; the participant's overlay-rule engine consults the patient's residence jurisdiction, the requesting participant's jurisdiction, the use case's authorization scope, and the record-type sensitivity classification to produce a per-candidate disclosure decision. Skip the overlay step and you disclose records that the applicable jurisdictional rule would have suppressed, which is a regulatory violation.

FUNCTION apply_sensitivity_overlay(
    candidate_set, authorization_context, query_id):

    // Step 3A: load the applicable overlay rule set. The
    // rule set is the union of rules applicable to:
    // - the patient's residence jurisdiction (which
    //   jurisdictions' overlay rules attach to the
    //   patient's data)
    // - the requesting participant's jurisdiction (which
    //   jurisdictions' overlay rules attach to the
    //   requesting context)
    // - the participant's own jurisdiction (which
    //   jurisdictions' overlay rules attach to the
    //   responding context)
    // - the use case's authorization scope (which
    //   exchange purpose constrains which overlays
    //   apply)
    overlay_rule_set = load_applicable_overlay_rules(
        patient_jurisdiction=
            extract_patient_jurisdiction(candidate_set),
        requesting_jurisdiction=
            authorization_context.requesting_jurisdiction,
        responding_jurisdiction=
            authorization_context.responding_jurisdiction,
        exchange_purpose=
            authorization_context.exchange_purpose,
        rule_version_active_at=
            current UTC timestamp)

    // Step 3B: per-candidate overlay-rule evaluation.
    filtered_candidates = []
    FOR EACH candidate IN candidate_set:
        // Apply the 42 CFR Part 2 substance-use-treatment
        // record overlay. Records under Part 2 are
        // excluded from the candidate set unless the
        // patient's consent posture explicitly authorizes
        // the disclosure for this exchange purpose.
        IF candidate.has_part_2_record AND NOT
            authorization_context.consent_posture
              .permits_part_2_disclosure_for(
                authorization_context.exchange_purpose):
            audit_log({
                event_type:
                    "TEFCA_OVERLAY_PART_2_SUPPRESSED",
                query_id: query_id,
                candidate_token:
                    candidate.opaque_record_token,
                suppressed_at: current UTC timestamp
            })
            CONTINUE

        // Apply the post-Dobbs reproductive-health-care
        // overlay. Records under post-Dobbs state-law
        // overlay are excluded from cross-jurisdiction
        // disclosure where the requesting jurisdiction's
        // posture is incompatible with the patient's
        // residence-jurisdiction overlay.
        IF candidate.has_reproductive_health_record AND
            overlay_rule_set
              .post_dobbs_overlay_applicable(
                authorization_context):
            audit_log({
                event_type:
                    "TEFCA_OVERLAY_POST_DOBBS_SUPPRESSED",
                query_id: query_id,
                candidate_token:
                    candidate.opaque_record_token,
                suppressed_at: current UTC timestamp
            })
            CONTINUE

        // Apply the gender-affirming-care overlay. Records
        // under gender-affirming-care state-law overlay
        // or under sensitivity-flag suppression (recipe
        // 5.7) are excluded per the applicable rule.
        IF candidate.has_gender_affirming_care_record AND
            overlay_rule_set
              .gender_affirming_care_overlay_applicable(
                authorization_context):
            audit_log({
                event_type:
                    "TEFCA_OVERLAY_GENDER_AFFIRMING_CARE_SUPPRESSED",
                query_id: query_id,
                candidate_token:
                    candidate.opaque_record_token,
                suppressed_at: current UTC timestamp
            })
            CONTINUE

        // Apply additional overlays as the rule set
        // specifies (HIV-and-genetic-information,
        // mental-health, juvenile, witness-protection,
        // and others as the jurisdictional overlay
        // landscape evolves).
        FOR EACH additional_overlay IN
            overlay_rule_set.additional_overlays:
            IF additional_overlay.suppresses(
                    candidate, authorization_context):
                audit_log({
                    event_type:
                        "TEFCA_OVERLAY_" +
                        additional_overlay.identifier +
                        "_SUPPRESSED",
                    query_id: query_id,
                    candidate_token:
                        candidate.opaque_record_token,
                    suppressed_at: current UTC timestamp
                })
                CONTINUE_OUTER_LOOP

        // The candidate passes all applicable overlay
        // rules. Apply the per-candidate disclosure-form
        // decision (full demographic disclosure for high-
        // confidence treatment-purpose queries vs
        // suppressed-demographic disclosure for queries
        // with re-identification-risk concerns).
        candidate_with_disclosure_form =
            apply_disclosure_form_decision(
                candidate, authorization_context)

        filtered_candidates.append(
            candidate_with_disclosure_form)

    audit_log({
        event_type: "TEFCA_OVERLAY_APPLIED",
        query_id: query_id,
        original_count: len(candidate_set),
        filtered_count: len(filtered_candidates),
        applied_at: current UTC timestamp
    })

    RETURN filtered_candidates

Step 4: Originate an outbound federated patient-discovery query. A local user or patient initiates a cross-network query. The query-formulation logic balances recall (sending enough demographic features that the federation can match the patient under plausible variation) with the per-feature suppression-for-sensitivity discipline. The signed query is submitted to the participant's QHIN, which routes it through the federation. Skip the query-formulation discipline and the outbound query produces either insufficient recall (the federation does not match the patient because too few features were sent) or excessive disclosure (the query exposes more demographic data than the use case requires).

FUNCTION originate_outbound_patient_discovery_query(
    user_or_patient_identity,
    requested_demographics,
    exchange_purpose,
    use_case_context):

    // Step 4A: authenticate the originator. For staff-
    // initiated queries, authenticate through the
    // institution's IAM. For patient-mediated queries,
    // authenticate through the patient-portal Cognito
    // and validate the patient's authorization scope.
    IF user_or_patient_identity.is_patient_mediated:
        authentication_result =
            authenticate_patient_mediated(
                user_or_patient_identity,
                use_case_context)
    ELSE:
        authentication_result =
            authenticate_staff_initiated(
                user_or_patient_identity,
                use_case_context)

    IF NOT authentication_result.is_authenticated:
        audit_log({
            event_type:
                "TEFCA_OUTBOUND_QUERY_AUTH_REJECTED",
            user_or_patient_identity:
                summarize_for_audit(
                    user_or_patient_identity),
            rejected_at: current UTC timestamp
        })
        RAISE AuthenticationFailedError()

    // Step 4B: map the user's request to the appropriate
    // exchange purpose. The mapping is institutional and
    // explicit; ambiguous mappings are routed to a
    // governance-defined default with the explicit-mapping
    // pattern as the audit-tracked alternative.
    mapped_exchange_purpose = map_to_exchange_purpose(
        exchange_purpose, use_case_context)

    // Step 4C: validate the participant's authorization
    // for the mapped exchange purpose.
    IF mapped_exchange_purpose NOT IN
        load_participant_authorized_exchange_purposes():
        audit_log({
            event_type:
                "TEFCA_OUTBOUND_QUERY_PURPOSE_DENIED",
            mapped_exchange_purpose: mapped_exchange_purpose,
            denied_at: current UTC timestamp
        })
        RAISE ExchangePurposeNotAuthorizedError()

    // Step 4D: formulate the federated query payload.
    // The formulation balances recall and suppression.
    formulated_payload = formulate_federated_query(
        requested_demographics,
        exchange_purpose=mapped_exchange_purpose,
        suppress_features_per_sensitivity=
            apply_sensitivity_suppression(
                requested_demographics,
                use_case_context),
        normalize_features_per_qtf=
            normalize_per_qtf(requested_demographics))

    // Step 4E: build the originating-attribution chain.
    attribution_chain = build_attribution_chain(
        originating_user_or_patient=
            authentication_result.principal_id,
        is_patient_mediated=
            user_or_patient_identity.is_patient_mediated,
        originating_sub_participant=
            load_participant_id(),
        originating_qhin=
            load_participant_qhin_id(),
        requesting_jurisdiction=
            extract_user_jurisdiction(
                authentication_result))

    // Step 4F: sign the query under the participant's
    // signing credential.
    query_id = generate_query_id()
    signed_query = sign_query(
        query_id=query_id,
        formulated_payload=formulated_payload,
        attribution_chain=attribution_chain,
        signing_key=load_participant_signing_key())

    // Step 4G: log the outbound query.
    audit_log({
        event_type: "TEFCA_OUTBOUND_QUERY_SUBMITTED",
        query_id: query_id,
        attribution_chain: attribution_chain,
        exchange_purpose: mapped_exchange_purpose,
        demographic_payload_summary:
            summarize_payload_for_audit(
                formulated_payload),
        submitted_at: current UTC timestamp
    })

    // Step 4H: submit to the QHIN.
    qhin_endpoint = load_participant_qhin_endpoint()
    submission_result = submit_to_qhin(
        signed_query, qhin_endpoint)

    // The submission returns a federation handle that
    // the response-consolidator listens against for
    // incoming responses.
    RETURN submission_result.federation_handle

Step 5: Consume and consolidate the federated-discovery responses. Responses arrive asynchronously. The consolidation logic validates each response, normalizes the demographic-feature representations across responders, groups candidates by patient identity, applies the use-case-specific presentation filter, and presents the consolidated view to the user. Partial results are presented when the response window expires before all responses have arrived. Skip the per-response signature validation and you accept malformed or unauthorized responses that produce wrong-record disclosures.

FUNCTION consume_and_consolidate_responses(
    federation_handle, query_id,
    response_window_seconds, use_case_context):

    // Step 5A: subscribe to the federation handle for
    // incoming responses. The QHIN delivers responses
    // as they arrive from the responding participants.
    received_responses = []
    response_deadline = current UTC timestamp +
        response_window_seconds

    WHILE current UTC timestamp < response_deadline:
        response = receive_next_response_with_timeout(
            federation_handle,
            timeout_seconds=
                min(remaining_window_seconds(), 30))

        IF response IS NULL:
            BREAK

        // Step 5B: validate the responder's signature.
        responder_id = response.responder_id
        responder_public_keys =
            load_responder_public_keys(
                responder_id,
                include_previous_during_rotation=TRUE)

        IF NOT verify_signature_against_any(
                response.payload,
                response.signature,
                responder_public_keys):
            audit_log({
                event_type:
                    "TEFCA_OUTBOUND_RESPONSE_SIGNATURE_REJECTED",
                query_id: query_id,
                responder_id: responder_id,
                rejected_at: current UTC timestamp
            })
            CONTINUE

        // Step 5C: validate the responder's attribution
        // chain (which sub-participant responded, which
        // QHIN routed) and reconcile with the originating
        // query.
        IF NOT validate_response_attribution(
                response.attribution_chain,
                originating_query_id=query_id):
            audit_log({
                event_type:
                    "TEFCA_OUTBOUND_RESPONSE_ATTRIBUTION_REJECTED",
                query_id: query_id,
                responder_id: responder_id,
                rejected_at: current UTC timestamp
            })
            CONTINUE

        // Step 5D: log the received response and add to
        // the consolidation set.
        audit_log({
            event_type:
                "TEFCA_OUTBOUND_RESPONSE_RECEIVED",
            query_id: query_id,
            responder_id: responder_id,
            candidate_count: len(response.candidates),
            received_at: current UTC timestamp
        })

        received_responses.append(response)

    // Step 5E: normalize the candidate-record
    // representations across responders. Different
    // responders may use slightly different demographic-
    // feature normalizations; the consolidation step
    // brings them into a consistent representation.
    normalized_candidates = normalize_candidates_across_responders(
        received_responses)

    // Step 5F: group candidates by patient identity. A
    // federated-resolution matcher runs against the
    // candidate set to identify which candidates appear
    // to refer to the same patient (the candidates that
    // are likely the same person but came from different
    // responders).
    grouped_candidates = federated_resolution_matcher(
        normalized_candidates)

    // Step 5G: apply the use-case-specific presentation
    // filter.
    presentation_view = apply_presentation_filter(
        grouped_candidates,
        use_case_context)

    // Step 5H: indicate response completeness to the
    // presentation layer.
    completeness_indicator = compute_completeness_indicator(
        received_responses,
        expected_responder_count=
            estimate_expected_responder_count_for_query(
                query_id),
        deadline_reached=
            (current UTC timestamp >= response_deadline))

    presentation_view.completeness_indicator =
        completeness_indicator

    audit_log({
        event_type: "TEFCA_OUTBOUND_VIEW_CONSOLIDATED",
        query_id: query_id,
        responder_count: len(received_responses),
        candidate_count: len(normalized_candidates),
        grouped_count: len(grouped_candidates),
        completeness_summary:
            summarize_completeness(completeness_indicator),
        consolidated_at: current UTC timestamp
    })

    RETURN presentation_view

Step 6: Handle document-query and retrieval for selected candidates. The user reviews the consolidated view and selects candidates for document retrieval. The document-query orchestrator formulates per-candidate document-query requests, routes them through the QHIN federation, consumes the document responses, and consolidates them into the user's longitudinal-record view. Skip the per-document attribution discipline and the consolidated record loses the source attribution that subsequent operational concerns (dispute resolution, downstream analytics, regulatory reporting) depend on.

FUNCTION execute_document_query_and_retrieval(
    selected_candidates, user_or_patient_identity,
    use_case_context, query_id):

    // Step 6A: per-candidate document-query formulation.
    // Each selected candidate produces a document-query
    // request that is routed back to the responding
    // source through the QHIN federation. The document-
    // query carries the opaque record token (which the
    // responding source can resolve back to the local
    // record under its own access controls) and the
    // exchange-purpose claim that the original discovery
    // query operated under.
    document_query_requests = []
    FOR EACH candidate IN selected_candidates:
        request = formulate_document_query_request(
            opaque_record_token=
                candidate.opaque_record_token,
            exchange_purpose=
                use_case_context.exchange_purpose,
            requested_document_types=
                use_case_context.requested_document_types,
            attribution_chain=
                build_attribution_chain_for_doc_query(
                    user_or_patient_identity,
                    use_case_context,
                    query_id))

        document_query_requests.append(request)

    // Step 6B: parallel submission to the QHIN federation.
    // The Step Functions orchestrator handles the parallel
    // submissions with per-step retries and per-step
    // error routing.
    document_responses = parallel_submit_to_qhin(
        document_query_requests,
        max_parallel=use_case_context.max_parallel)

    // Step 6C: per-response document-content
    // consolidation.
    consolidated_documents = []
    FOR EACH response IN document_responses:
        // Validate the responder's signature on the
        // document response.
        IF NOT validate_response_signature(response):
            audit_log({
                event_type:
                    "TEFCA_DOC_RESPONSE_SIGNATURE_REJECTED",
                query_id: query_id,
                responder_id: response.responder_id,
                rejected_at: current UTC timestamp
            })
            CONTINUE

        // Persist each document to the document-store
        // S3 bucket with the per-document attribution
        // metadata.
        FOR EACH document IN response.documents:
            persisted_document = persist_to_document_store(
                document=document,
                source_organization_attribution=
                    response.source_organization_attribution,
                retrieval_context_attribution={
                    query_id: query_id,
                    user_or_patient_identity:
                        summarize_for_audit(
                            user_or_patient_identity),
                    exchange_purpose:
                        use_case_context.exchange_purpose,
                    retrieved_at: current UTC timestamp
                },
                consent_context_attribution=
                    response.consent_context_attribution)

            consolidated_documents.append(
                persisted_document)

    // Step 6D: log the document retrieval with the full
    // attribution chain.
    audit_log({
        event_type: "TEFCA_DOCUMENTS_RETRIEVED",
        query_id: query_id,
        candidate_count: len(selected_candidates),
        document_count: len(consolidated_documents),
        retrieved_at: current UTC timestamp
    })

    // Step 6E: emit the cross-recipe event.
    EventBridge.PutEvents([{
        source: "tefca-national-scale-matching",
        detail_type: "tefca_query_completed",
        detail: {
            query_id: query_id,
            candidate_count: len(selected_candidates),
            document_count: len(consolidated_documents),
            user_or_patient_summary:
                summarize_for_audit(
                    user_or_patient_identity),
            exchange_purpose:
                use_case_context.exchange_purpose,
            completed_at: current UTC timestamp
        }
    }])

    RETURN consolidated_documents

Curious how this looks in Python? The pseudocode above covers the concepts. If you'd like to see sample Python code that demonstrates these patterns using boto3, check out the Python Example. It walks through each step with inline comments and notes on what you'd need to change for a real deployment.


Expected Results

Sample inbound federated patient-discovery query (illustrative; actual payload follows the QTF specification):

{
  "query_id": "tefca-inbound-2026-q2-3387221",
  "qhin_id": "qhin-example-national-network",
  "request_metadata": {
    "qhin_id": "qhin-example-national-network",
    "request_timestamp": "2026-04-22T14:33:11Z",
    "request_signature": "<base64-encoded-signature>"
  },
  "originating_attribution_chain": {
    "originating_user_id": "user-emergency-department-attending-44211",
    "is_patient_mediated": false,
    "originating_sub_participant_id": "sub-regional-trauma-center-east",
    "originating_qhin_id": "qhin-example-eastern-network",
    "requesting_jurisdiction": "state-of-virginia",
    "routing_path": [
      "qhin-example-eastern-network",
      "qhin-example-national-network"
    ]
  },
  "exchange_purpose": "treatment",
  "demographic_features": {
    "given_name": "Sarah",
    "family_name": "Mitchell",
    "dob": "1984-08-17",
    "sex_or_gender": "F",
    "address_line_1": "1247 Oak Street",
    "city": "Richmond",
    "state": "VA",
    "zip_code": "23220",
    "phone": null,
    "ssn_last_4": null
  }
}

Sample outbound federation response (illustrative):

{
  "query_id": "tefca-inbound-2026-q2-3387221",
  "responder_id": "participant-academic-medical-center-richmond",
  "response_signature": "<base64-encoded-signature>",
  "candidates": [
    {
      "opaque_record_token": "tok-amc-richmond-2026-q2-08847221",
      "disclosable_demographic_features": {
        "given_name": "Sarah",
        "family_name": "Mitchell",
        "dob": "1984-08-17",
        "sex_or_gender": "F",
        "city": "Richmond",
        "state": "VA",
        "zip_code": "23220"
      },
      "source_organization_attribution": {
        "source_organization_id": "amc-richmond-cardiology-clinic",
        "source_organization_name": "Academic Medical Center Richmond - Cardiology",
        "source_organization_npi": "1234567890"
      },
      "match_score": 0.96,
      "match_confidence_tier": "high",
      "consent_posture_summary": {
        "consent_for_treatment_purpose": true,
        "consent_for_individual_access_services": true,
        "jurisdictional_overlay_applicable": "none"
      }
    }
  ],
  "candidate_count_returned": 1,
  "candidate_count_truncated": false,
  "responded_at": "2026-04-22T14:33:14Z"
}

Sample consolidated cross-network presentation view (after consolidating responses from multiple participants):

{
  "query_id": "tefca-outbound-2026-q2-9921144",
  "originating_user": "user-emergency-department-attending-44211",
  "exchange_purpose": "treatment",
  "completeness_indicator": {
    "expected_responder_count_estimate": 12,
    "received_responder_count": 9,
    "completeness_pct": 75,
    "deadline_reached": true,
    "longest_tail_responders_pending": [
      "responder-rural-hospital-network",
      "responder-state-immunization-registry",
      "responder-state-prescription-monitoring-program"
    ]
  },
  "candidate_groupings": [
    {
      "grouping_id": "group-2026-q2-9921144-001",
      "consolidated_demographic_view": {
        "given_name": "Sarah",
        "family_name": "Mitchell",
        "dob": "1984-08-17",
        "sex_or_gender": "F",
        "city": "Richmond",
        "state": "VA",
        "zip_code": "23220"
      },
      "candidates_in_grouping": [
        {
          "opaque_record_token": "tok-amc-richmond-2026-q2-08847221",
          "responder_id": "participant-academic-medical-center-richmond",
          "source_organization_id": "amc-richmond-cardiology-clinic",
          "match_confidence_tier": "high"
        },
        {
          "opaque_record_token": "tok-rx-data-2026-q2-44912988",
          "responder_id": "participant-national-pharmacy-data-network",
          "source_organization_id": "regional-pharmacy-chain-mid-atlantic",
          "match_confidence_tier": "high"
        },
        {
          "opaque_record_token": "tok-virginia-hie-2026-q2-77221334",
          "responder_id": "participant-virginia-hie",
          "source_organization_id": "primary-care-clinic-richmond-west",
          "match_confidence_tier": "high"
        }
      ],
      "grouping_match_confidence": "high"
    }
  ]
}

Sample document-retrieval result (illustrative):

{
  "query_id": "tefca-outbound-2026-q2-9921144",
  "documents_retrieved": [
    {
      "document_id": "doc-amc-cardiology-consult-2025-11-04",
      "document_type": "consultation_note",
      "source_organization_id": "amc-richmond-cardiology-clinic",
      "responder_id": "participant-academic-medical-center-richmond",
      "document_date": "2025-11-04",
      "retrieved_at": "2026-04-22T14:33:18Z"
    },
    {
      "document_id": "doc-rx-warfarin-active-prescription",
      "document_type": "active_medication",
      "source_organization_id": "regional-pharmacy-chain-mid-atlantic",
      "responder_id": "participant-national-pharmacy-data-network",
      "document_date": "2026-03-12",
      "retrieved_at": "2026-04-22T14:33:19Z"
    },
    {
      "document_id": "doc-radiology-contrast-allergy-note-2023-09",
      "document_type": "allergy_note",
      "source_organization_id": "imaging-center-northern-virginia",
      "responder_id": "participant-virginia-hie",
      "document_date": "2023-09-21",
      "retrieved_at": "2026-04-22T14:33:21Z"
    }
  ]
}

Performance benchmarks (illustrative, your mileage varies):

Metric Internal cross-facility (recipe 5.5) National-scale TEFCA (recipe 5.9)
Match rate at fixed false-acceptance threshold (FAR=0.005) 92-96% 75-92% (varies by responder data quality)
End-to-end query latency (median) 200-800 ms 2-12 seconds (longest-tail responder dominates)
End-to-end query latency (p95) 1-3 seconds 8-30 seconds
End-to-end query latency (p99) 3-10 seconds 15-60 seconds (response-window expirations common)
Per-cohort linkage-rate disparity (best vs worst) 0.05-0.10 0.10-0.20 (heterogeneous-participant penalty)
Inbound query throughput per participant (sustained) 100-500 QPS 50-300 QPS at scale (the participant has to handle the federation's growing inflow)
Outbound query response-window completeness n/a 70-90% of expected responders within window
Audit-event volume per query 10-30 (per-query audit) 30-150 (per-hop audit including federation routing)
Per-jurisdiction overlay-rule applicability rate n/a 5-25% of candidate records (varies by use case and patient population)
Cross-QHIN dispute rate n/a 0.001-0.01% of queries (highly variable based on participant maturity)

Where it struggles:

  • Heterogeneous responder quality is the dominant accuracy determinant. The federation's overall match rate is bounded above by the data quality of the constituent records, which at national scale includes the worst-quality participant. The mitigation is per-responder match-quality monitoring with explicit degradation alerts and a cross-QHIN escalation path for chronically-low-quality responders. The participant cannot fix another participant's data quality but can choose to weight the candidates by responder quality in the consolidated view.
  • Response-window expirations produce silent partial-record presentation. A user who initiates a cross-network query and receives a partial response (because some responders timed out) sees an incomplete longitudinal record without explicit knowledge of what is missing. The presentation layer's completeness indicator is the architectural mitigation; the operational discipline is making sure the user actually sees and understands the indicator. The mitigation includes user-experience-design discipline around the partial-result state and explicit re-query mechanisms when the user needs the missing data.
  • Cross-jurisdictional overlay rules accumulate operational complexity. Each jurisdiction's overlay rules add a per-record evaluation at every hop in the routing layer. The cumulative overhead grows with the jurisdictional-overlay landscape and with the federation's geographic scope. The mitigation is the versioned overlay-rule engine with explicit rule-evaluation metrics and an institutional regulatory-monitoring function that consumes the rule changes; without it, the rule landscape outpaces the participant's operational capacity to honor the rules.
  • The federation's matching tolerance is the loosest tolerance any participant honors. The federation operates at the loosest tolerance because participants whose tolerances are tighter silently drop queries the looser-tolerance participants would respond to. The federation's effective tolerance is the loosest, with the consequent false-positive-rate penalty. The mitigation is explicit cross-network-tolerance calibration coordinated through the QHIN's framework and operational-coordination forums, with periodic re-calibration as the federation's overall data quality evolves.
  • Patient-mediated flows have additional authentication complexity that the framework does not fully standardize. The patient's authentication is performed at the participant's patient-portal IdP; the federation's framework specifies the patient-mediated attribution flow but does not standardize the participant-side authentication mechanisms. Different participants implement patient-mediated authentication differently (different IdP technologies, different multi-factor authentication policies, different authentication-event-retention rules), and the cross-participant audit reconstruction has to handle the heterogeneity. The mitigation is institutional documentation of the participant's patient-mediated authentication mechanism and explicit accommodation in the audit-and-attribution layer.
  • Information-blocking compliance creates response-time pressure. The information-blocking rule's exception framework has timing requirements that the local matcher's response has to satisfy. A query that the local matcher cannot resolve confidently in the response window has to be either responded to with a "no-confident-match" indication or escalated to a slower-tier review process that produces a response within the rule-specified timeline. Silent drops are operationally non-compliant. The mitigation is the explicit no-confident-match response pattern and the slower-tier review escalation, with operational metrics on both.
  • Cross-QHIN attribution chain reconstruction is operationally non-trivial. When a dispute requires reconstructing the full attribution chain across multiple QHINs, the audit-log joining has to operate across the participating QHINs' separate audit substrates, each with its own retention policy, its own access controls, and its own attribution-data model. The dispute-resolution timelines are long (weeks to months) because the attribution-chain reconstruction is a coordinated effort across the QHIN's framework. The mitigation is per-query attribution-chain capture in the local audit at the design stage, and operational discipline in maintaining the audit's consistency with the framework's specifications.
  • Capacity events at the federation level cascade to participants. A capacity event at one QHIN (a high-volume cross-QHIN-query spike, an outage at one participant, a misconfigured retry pattern at one participant that produces a query flood) cascades to other participants whose infrastructure consumes the federation's traffic. The mitigation is per-source rate limiting on the inbound query handler with explicit fail-fast semantics, per-source error-rate monitoring with explicit escalation thresholds, and federation-wide capacity coordination through the QHIN's operational interface.
  • The framework's evolution outpaces the participant's adoption rate. Changes to the Common Agreement, the QTF, and the SOPs evolve on the framework's cadence; the participant's adoption is bounded by the participant's operational capacity to absorb the changes. The participants that fall behind the framework's evolution can lose their participation status under the framework's governance. The mitigation is the governance-evolution program with named owners, named processes, and explicit timeline-tracking against the framework's mandates.
  • Cross-recipe coordination at the architectural level introduces non-obvious dependencies. The PPRL flow from recipe 5.8 may use the federation's routing layer; the longitudinal name-change handling from recipe 5.7 affects the cross-network matching tolerance; the claims-clinical linkage from recipe 5.6 may operate through the federation for cross-payer use cases. The mitigation is explicit cross-recipe event handling with the federation-events bus and explicit cross-recipe ownership in the institutional governance.
  • The institutional learning curve is substantial. Operating a TEFCA participant well requires institutional capabilities (federation-aware engineering, federation-aware compliance, federation-aware operations, federation-aware governance) that most institutions are still building. The institutions that operate TEFCA well have invested in the institutional capabilities deliberately, often through a multi-year program with explicit milestones and explicit named ownership. The institutions that have not made the investment discover, during the first year of operation, that their existing capabilities are not sufficient for the federation's operational demands. The mitigation is treating TEFCA participation as a multi-year program with explicit institutional-capability development.

Why This Isn't Production-Ready

The pseudocode and architecture above demonstrate the pattern. A production deployment needs to close several gaps that are intentionally out of scope for a recipe.

QHIN Participant Agreement and operational onboarding. The institution has to negotiate and sign a Participant Agreement with the QHIN, complete the QHIN's onboarding (technical certification, governance review, operational testing), and operate continuously under the agreement's terms. The Participant Agreement is the load-bearing contractual artifact for the institution's TEFCA participation; the operational onboarding is a multi-month process that the institution has to plan and resource. Plan the QHIN onboarding as a project with its own timeline, its own staffing, and its own iteration discipline. Different QHINs have different onboarding processes; the institution's choice of QHIN affects the onboarding timeline and the operational specifics.

QHIN-credential and signing-key rotation ceremony. The participant's QHIN-issued credentials (mTLS certificates, OAuth client credentials) and the participant's signing keys are rotated on the framework's specified cadence (typically annual for credentials, more frequent for signing keys depending on the QHIN's policy). Rotation is a coordinated event between the participant and the QHIN. The architectural specification:

  • Dual-control approval pattern. Two operators from non-overlapping organizational units must approve a rotation operation through a separate approval-workflow Lambda. The approval workflow operates in a cross-account configuration where the institutional security team is in a separate AWS account from the operations team. Single-actor approvals are rejected; the approval workflow's rejection semantics produce a structured denial event with the requesting-actor identity and the denial reason.
  • Audit-log schema for credential-related operations. Every credential operation records: calling principal, operation type, timestamp, credential-version (old and new), dual-control approver identities (both operators), and post-operation verification status. The credential-audit events are stored in a separately access-controlled S3 bucket with the framework's specified retention floor (typically the longest of HIPAA 7-year minimum, the QHIN's Common-Agreement-specified audit-retention floor, the state medical-records-retention, the participant's institutional retention floor, the cross-jurisdictional retention overlay, and the cross-recipe coordination retention floor where events that interact with recipes 5.5 / 5.7 / 5.8 impose a longer floor, plus an additional period for post-deployment audit reconstruction).
  • Catch-up-window policy. An explicit duration (aligned with the QHIN's specified rotation window, typically 24-72 hours) during which the prior credential-version remains valid for in-flight operations. Access to the prior credential-version during the catch-up window is read-only with audit logging on every read. The catch-up-window access-control constraint binds to a time-expiring IAM policy condition that the rotation-coordinator Step Functions workflow manages.
  • Post-rotation operational-verification SLA. After the rotation completes, CloudWatch metrics track per-credential-version usage. An alarm fires on degradation (traffic still using the expired credential-version after the catch-up window closes). The response-protocol includes explicit catch-up-window-extension authority for the on-call security engineer, with the extension itself audit-logged under the dual-control framework.
  • Monitoring of rotation completion against the framework's deadline. A CloudWatch alarm fires if the rotation has not completed by the framework-specified deadline minus a buffer (typically 7 days before the deadline). The alarm routes to both the operations team and the institutional security officer.

Build the rotation capability as a deliberate operational program with named owners, named processes, and named review committees. Skip this and the rotation is custodied informally, the audit trail is inconsistent, and the trust framework's authentication claim is operationally unsupported.

Cross-network-tolerance calibration and approval governance. The cross-network matching tolerance is calibrated against a curated calibration set (synthetic data plus opt-in pilot data from collaborating participants) using SageMaker training jobs. Re-calibration runs periodically and on detection of cohort-stratified disparity above the institutional threshold. Re-calibration produces a candidate tolerance set; institutional review (analytics governance committee, compliance, clinical informatics, privacy team, equity-monitoring committee) reviews the confusion matrix and the cohort-disparity impact before promoting the candidate to production. Each query references the configuration version active at decision time. Same chapter pattern as 5.1, 5.4, 5.5, 5.6, 5.7, 5.8.

The calibration governance infrastructure:

  • Versioned configuration table. A DynamoDB table (or dedicated configuration store) holds the cross-network-tolerance per use case: per-feature weights, missing-feature weights, per-jurisdiction overlay rules that interact with matching thresholds, and the candidate-acceptance and candidate-confidence thresholds. Each configuration version is immutable once active; the linkage-cycle references the configuration version active at decision time.
  • SageMaker calibration job. Produces the candidate tolerance set against the curated calibration data. The calibration data infrastructure is separately governed: separate AWS account, separate access controls, separate audit posture, separate retention rules. The calibration data never co-mingles with production query data.
  • Per-cohort impact-analysis requirement. Before a candidate tolerance is promoted to production, the analytics team runs an impact analysis stratified across explicit cohort axes: geographic cohort, age-decade cohort, sex-or-gender cohort, name-tradition cohort, jurisdictional-overlay cohort, patient-consent-for-fairness-monitoring cohort. The impact analysis produces a per-cohort confusion matrix comparing the candidate tolerance against the current production tolerance.
  • Privacy-team inclusion in the review committee. The privacy team has explicit re-identification-risk review authority over the candidate tolerance. The privacy team evaluates whether the proposed tolerance change alters the re-identification risk for any cohort, particularly for cohorts with small population sizes in the federation.
  • Configuration-version binding at decision time. Each linkage cycle (each query's resolution) records the configuration version active at decision time in the federation-attribution table. Post-hoc audit reconstruction can identify which tolerance produced a given decision.

Three review queues with cohort-and-cycle-aware tooling. The cross-network-match-review queue surfaces medium-confidence candidates that the federation's response presented for review (the consolidated-presentation view's medium-confidence groupings); reviewers see the consolidated-view candidates with the per-source attribution and (under appropriate authorization) the underlying records at each responder. The dispute-review queue surfaces incoming and outgoing disputes for cross-QHIN coordination; reviewers see the dispute artifacts with the full attribution chain. The governance-evolution queue surfaces framework changes (Common Agreement updates, QTF updates, SOP updates, jurisdictional-overlay-rule updates); reviewers from compliance, privacy, legal, and operations evaluate the operational impact and plan the institutional response. Each review tool emits the reviewer's decision back into the operational training signal.

Per-queue audit posture:

  • All queues. Every reviewer action records: reviewer identity (with two-factor authentication), decision, stated reason, configuration version active at the time, threshold or tolerance version active at the time, any reviewer-supplied additional context. The reviewer identity is authenticated through the institutional IdP with MFA.
  • Dispute-review queue. Cross-QHIN attribution-chain reconstruction with the full audit-log joining across the participating QHINs' separate audit substrates. Per-dispute reviewer training and conflict-of-interest screening (reviewers with a relationship to the disputing parties are excluded). Reviewer actions are dual-controlled: two reviewers from non-overlapping organizational units must approve high-impact dispute decisions (decisions that would alter the attribution chain, retract a prior disclosure, or escalate to the RCE).
  • Governance-evolution queue. Multi-disciplinary review with explicit named ownership: compliance, privacy, legal, operations, and clinical informatics each have a named reviewer. Per-change operational-impact-analysis with explicit timeline-against-framework-deadline tracking. Reviewer actions are dual-controlled for high-impact governance changes (changes that alter the participant's exchange-purpose scope, alter the consent-posture defaults, or alter the jurisdictional-overlay rules). Two reviewers from non-overlapping organizational units must approve.

Patient-consent capture and withdrawal pathways. The TEFCA deployment assumes that the patient has been asked (and has consented or declined) for cross-network disclosure under the applicable jurisdictional and use-case framework. The mechanism for asking is not the matcher's job; it is the registration workflow's, the patient-portal app's, and (for clinical-care contexts) the institutional consent-management workflow's. Build the consent-capture and withdrawal-pathway as a deliberate workflow with appropriate framing, training for the staff who solicit the information, and patient-facing communication about what cross-network disclosure does and what consent withdrawal means at federation scale (the retrospective limits are real; the institution can stop future disclosures but cannot retract records already disclosed to other participants). Skip this and the consent posture is operating on default values that may not match the patient's actual preferences, with predictable trust failures when patients discover their records were disclosed in cross-network queries they did not consent to.

Information-blocking compliance posture. The 21st Century Cures Act information-blocking provisions create an obligation to share patient records on request, with specific exceptions defined by the rule. The architecture has to handle the information-blocking compliance as an operational concern: the local matcher's response has to be either a confident match, a no-confident-match indication, or a denied-under-exception response with the exception code; silent drops are operationally non-compliant. Build the information-blocking-compliance pipeline with explicit handling of the rule's exceptions (Privacy Exception, Security Exception, Infeasibility Exception, Health IT Performance Exception, Content and Manner Exception, Fees Exception, Licensing Exception) and explicit operational metrics on each exception's invocation rate.

The information-blocking-exception handling pipeline:

  • Per-exception evaluation Lambda. Invoked at the response-formulation stage for every query where the local matcher cannot produce a confident match within the response window. The Lambda evaluates the applicable exceptions against the query's circumstances and produces a structured "denied-under-exception" response carrying the rule-specified exception code, rationale, and timing.
  • Per-exception CloudWatch metrics and alarm thresholds. Infeasibility-Exception invocation rate > 5% of queries = MEDIUM alarm. Privacy-Exception invocation rate > 10% = MEDIUM alarm. Content-and-Manner-Exception invocation rate > 1% = HIGH alarm. Aggregate exception rate > 20% = HIGH alarm. The alarms route to the compliance team and the operations team jointly.
  • Slower-tier review escalation pathway. A Step Functions workflow with response-window-tracking and rule-specified-timing as the workflow's deadline. When the standard response window expires without a confident match, the workflow escalates to the slower-tier review process. If the slower-tier review cannot produce a response within the rule-specified timeline, the workflow produces a structured Health-IT-Performance-Exception response.
  • Audit logging on every exception invocation. The inputs that drove the exception decision (query demographics summary, exchange purpose, applicable overlay rules, matcher confidence scores, timeout status) are recorded in the audit-event-log table. The exception-invocation audit events are separately reportable for ONC enforcement-inquiry responses.

Cross-jurisdictional overlay automation. The per-jurisdiction overlay rules accumulate as the framework's geographic scope grows. The architectural extension is an overlay-rules engine that consumes the patient's residence jurisdiction, the requesting participant's jurisdiction, the responding participant's jurisdiction, the use case's authorization scope, and the record-type sensitivity classification, and produces a per-record disclosure decision. The overlay rules are versioned and reviewed on a regulatory-monitoring cadence (post-legislative-session and post-court-decision are the typical triggers). The pattern is operationally important for participants operating across multiple states with diverging post-Dobbs, post-Bostock, and gender-affirming-care state-law overlays.

The overlay-rules engine architecture:

  • Versioned rule store. A DynamoDB table (or dedicated configuration store) holding the per-jurisdiction overlay rules, versioned so each query references the rule version active at query time. Rules specify: jurisdiction identifier, record-type sensitivity classification, applicable exchange purposes, disclosure decision (permit, suppress, require-additional-consent), effective date, and expiration date.
  • Rule-evaluation Lambda. Invoked at both query-formulation time (outbound queries) and query-handling time (inbound queries). Inputs: the patient's residence jurisdiction, the requesting-participant's jurisdiction, the use case's authorization scope, the record-type sensitivity classification, and the participating organizations' jurisdictional postures. Output: per-record disclosure-decision metadata stored on the response envelope.
  • Regulatory-monitoring function. Shared between privacy and compliance teams. Inputs: legislative-session feeds with explicit per-state subscription, regulatory-bulletin subscriptions from ONC and the RCE, court-decision tracking for relevant precedents. Trigger thresholds: when a monitored jurisdiction issues a new rule, court decision, or regulatory bulletin that may affect the overlay-rule applicability, the monitoring function produces a governance-evolution event with relevance-evaluation criteria for the governance committee.
  • Per-query disclosure-decision audit trail. Every overlay-rule application is audit-logged with: inputs (jurisdictions, exchange purpose, record-type classification, rule version active), output decision (permit/suppress/require-consent), and the rule identifier that produced the decision.
  • Framework-update pathway. Regulatory-change-detection through the regulatory-monitoring function triggers a governance-evolution event. The institutional governance committee reviews and approves the rule change. Coordinated re-deployment across the participant's TEFCA gateway with explicit version promotion. Downstream-consumer notification through the EventBridge fan-out so consumers operating under the prior rule version are aware of the change.

Idempotency and retry semantics. The pipeline must handle duplicate-event delivery, partner-side retries, and Lambda re-runs without producing duplicate audit events, duplicate document-store persistences, or scrambled attribution chains. The recipe-specific per-stage idempotency keys:

  • Inbound-query-handler Lambda: (query_id, hop_id)
  • Outbound-query-formulator Lambda: (query_id, attribution_chain_hash)
  • Response-consolidator Lambda: (query_id, responder_id)
  • Document-retrieval-handler Lambda: (query_id, candidate_token, document_id)
  • Dispute-handler Lambda: (dispute_id, escalation_event_id)
  • Governance-evolution-handler Lambda: (governance_change_id, evaluation_event_id)
  • QHIN-credential-rotation-coordinator Step Functions: (rotation_id, hop_id)

Configure a DLQ on every Lambda path and every Step Functions stage. Step Functions Catch states distinguish retriable infrastructure failures from terminal logic failures and route terminal failures to the DLQ so stuck workflows are visible. CloudWatch alarms on DLQ depth: > 0 records = MEDIUM (for dispute and governance queues) or LOW (for query-handler queues); > 15 minutes of records stuck in DLQ = HIGH (for any queue, indicating a stuck workflow that needs human investigation). Same chapter pattern as 5.3, 5.4, 5.5, 5.6, 5.7, 5.8.

Cohort-stratified accuracy monitoring discipline. The CloudWatch metrics with cohort-axis dimensions, the QuickSight dashboard, the institutional review cadence, and the disparity-alarm thresholds are architecture-level commitments, not bolt-ons.

The recipe-specific cohort axis enumeration (inherited from 5.7 and 5.8 plus federation-specific extensions): geographic-region cohort, age-decade cohort, sex-or-gender cohort, name-tradition cohort, jurisdictional-overlay cohort, responder-quality-tier cohort, patient-consent-for-fairness-monitoring cohort, cross-jurisdictional-overlay cohort.

  • Disparity-calculation method. Absolute difference between highest and lowest cohort, computed per-metric per-cycle. The disparity is not the variance; it is the max-minus-min across cohorts, which surfaces the worst-case disparity that the review committee needs to investigate.
  • Per-metric emission cadence. Match rate: weekly. False-acceptance rate: weekly. Response-time aging (per-cohort p50/p95): weekly. Sampled error rate (from the review queue's resolved cases): monthly.
  • Alarm thresholds. Cohort-stratified match-rate disparity > 0.10 = MEDIUM alarm. Cohort-stratified false-acceptance-rate disparity > 0.02 = HIGH (because false acceptances at federation scale produce wrong-record disclosures that the originating participant cannot retract from the consumer).
  • Privacy-team routing. The privacy team has explicit federation-equity-evaluation authority. Disparity alerts route to both the analytics-governance committee and the privacy team. The privacy team evaluates whether the disparity constitutes a framework-equity concern (cohort disparities at federation scale are simultaneously fairness signals and framework-compliance signals).
  • Framework-equity translation. Cohort disparities at federation scale map to TEFCA's participation requirements. Persistent cohort disparities above the institutional threshold are reported to the QHIN as a framework-equity concern and may trigger the QHIN's cross-participant coordination process.
  • Remediation pathway. Alert routing to the analytics-governance committee and the privacy team. Investigation with a 5-business-day SLA for initial assessment. Post-mortem retention in the audit-archive bucket. Quarterly review by the federation-participation steering committee with privacy-team co-chair. The quarterly review evaluates whether the remediation closed the disparity and whether the remediation introduced new disparities on other cohort axes.

Same chapter pattern as 5.1, 5.4, 5.5, 5.6, 5.7, 5.8.

Compliance and operational ownership. TEFCA participation sits at the intersection of analytics, clinical operations, compliance, privacy, security, IT, legal, and patient-advocacy. Establish clear operational ownership: who tunes the cross-network tolerance, who reviews the cohort-disparity reports, who owns the QHIN-credential rotations, who handles the dispute-resolution coordination, who responds to consent withdrawals, who negotiates Participant Agreement changes, who owns the framework-evolution program. The pipeline works only when the operational ownership is clear and funded across the institution, not just within the IT or analytics organization.

Identity-boundary requirements at the architectural level. Every consequential path through the architecture has explicit identity-boundary requirements:

  • Inbound-query-handler Lambda. Receives a QHIN-signed request envelope containing: originating_user_id, originating_sub_participant_id, originating_qhin_id, exchange_purpose, signed_payload, and qhin_signature. Consumer-side signature validation verifies the envelope against the QHIN's known public key (rotated on the framework's cadence; the prior key retained during the rotation window).
  • Outbound-query-formulator Lambda. Formulates a request envelope signed under the participant's signing credential. Validates the QHIN's response signature against the QHIN's public key before processing the response payload. Signing and validation use the current credential-version from Secrets Manager.
  • Patient-mediated flow authentication chain. The patient's authentication-event-id (from the participant-level Cognito federation) is propagated explicitly through the audit log. The patient-portal session-id (from the patient-portal app's session store) is retained alongside the authentication-event-id so post-hoc audit can reconstruct the full patient-mediated attribution from portal session through federation response.
  • QHIN-credential rotation dual-control. Two operators from non-overlapping organizational units must approve a rotation operation. The rotation is audit-logged with both operator identities. The rotation-coordinator Step Functions workflow enforces the dual-control constraint by requiring two separate approval events before proceeding.
  • Cross-recipe EventBridge fan-out identity discipline. The fan-out validates producer-signed envelopes at consumers. Access-control-envelope-aware routing ensures consumers in different trust tiers receive different event detail levels (standard channel for treatment-context consumers; restricted channel for analytics consumers that receive only differentially-private-aggregate or encrypted-match-indicator disclosure forms).

The recipe-specific extensions to the chapter pattern are the QHIN-credential rotation's federation-trust-anchor stakes (a mis-rotated credential breaks the federation's authentication chain, not just the participant's), the patient-mediated-attribution stakes (a mis-attributed patient-mediated query exposes the patient's query history to the wrong attribution chain), and the cross-QHIN-dispute-resolution attribution stakes (a disputed attribution that cannot be reconstructed undermines the federation's trust framework).

Network isolation and PrivateLink configuration. The QHIN-to-participant exchange operates over PrivateLink where both parties support it. The architectural specification:

  • Per-QHIN PrivateLink endpoint configuration. Each QHIN the participant integrates with gets a dedicated VPC endpoint. The VPC endpoint policy enumerates the specific cross-account roles authorized to invoke the endpoint. The endpoint's security group restricts inbound traffic to the QHIN's known IP ranges (or, for PrivateLink, the QHIN's VPC endpoint service).
  • Per-rotation network-policy expiration. The network policy on the PrivateLink endpoint aligns with the QHIN-credential rotation cadence. When the credential rotates, the network policy is updated to reflect the new credential's associated network-identity claims. The prior network policy expires at the end of the catch-up window.
  • Audit-and-monitoring discipline on the QHIN-to-participant exchange. VPC Flow Logs on the PrivateLink endpoint's ENIs. CloudWatch metrics on per-QHIN traffic volume, per-QHIN error rate, per-QHIN latency. CloudTrail data events on every PrivateLink invocation.
  • Patient-portal network isolation. The patient-portal Cognito flow operates through a separate API Gateway endpoint with its own WAF rule set. Rate limiting on the patient-portal endpoint is per-patient-session and per-patient-id, set below the staff-initiated query rate limits to prevent abuse (a compromised patient credential should not be able to generate federation-scale query floods). The patient-portal WAF rules are stricter than the QHIN-facing WAF rules: tighter request-rate limits, stricter payload-size limits, geographic restrictions where the institutional policy requires them.

Cross-recipe event contract for the EventBridge fan-out. The federation-events bus reaches recipes 5.5, 5.6, 5.7, 5.8, and per-participant operational systems. The event contract:

  • Chapter-wide event schema. Every event carries: source (the producing recipe or system), detail_type (the event classification), detail.query_id, detail.event_id, detail.attribution_chain, detail.exchange_purpose, detail.qhin_credential_version, detail.responder_quality_tier, detail.cohort_stratified_summary, detail.consent_posture_summary, detail.jurisdictional_overlay_applicability, detail.detected_at.
  • Access-control-envelope-aware routing. Standard channel carries full event detail for treatment-context consumers. Restricted channel carries only differentially-private-aggregate or encrypted-match-indicator disclosure forms for analytics and research consumers. EventBridge rules distinguish the channels by consumer trust-tier tags on the target.
  • Consumer-side signature validation. Each consumer validates the producer's signature on the event envelope before processing. The producer's signing key is the participant's current signing-key version; consumers that fail validation reject the event and emit a CloudWatch metric.
  • Schema-versioning policy. The event schema is versioned with explicit backward-compatibility guarantees. Consumers that encounter an unrecognized schema version route the event to a DLQ rather than silently dropping it. Schema-version bumps are coordinated through the governance-evolution queue.
  • Per-event-source allow-list. Each event type has an explicit set of allowed producers. EventBridge rules enforce the allow-list; events from unauthorized producers are rejected and audit-logged.

Patient-mediated TEFCA flow architecture. The patient-mediated path operates alongside the staff-initiated path with distinct authentication, authorization, and audit disciplines:

  • Patient-authentication path. The patient authenticates through the participant's patient-portal IdP (Cognito federation). Per-patient authentication-to-source-record-id binding through Lambda authorizers: the authorizer consults the participant's local authorization store to confirm the patient is authorized to query records associated with their identity. Rejection on binding-failure (a patient cannot query records they are not bound to).
  • Abuse-prevention rate-limiting. Rate limiting at the API Gateway layer is per-patient-session and per-patient-id, set below the staff-initiated query rate limits. The patient-portal endpoint's WAF rules are distinct from the QHIN-facing endpoint's rules.
  • Patient-mediated audit-attribution discipline. Patient-mediated queries are audit-logged with explicit "patient-mediated" attribution, distinct from staff-initiated queries. The audit log captures the patient's authentication-event-id, the patient-portal session-id, and the patient's authorization scope.
  • Per-patient audit summary delivery. The patient may opt to receive periodic summaries of queries against their record, delivered to the patient's chosen channel (patient-portal notification, email, or FHIR-based audit-event feed).
  • Rejection-on-attribution-failure semantics. If the patient-mediated attribution chain cannot be constructed (because the patient's authentication failed, the binding lookup failed, or the authorization scope is insufficient), the query is rejected with a structured denial and the denial is audit-logged.

Cross-QHIN attribution-chain reconstruction workflow. When a dispute requires reconstructing the full attribution chain across multiple QHINs:

  • Dispute-intake mechanism. A dedicated API endpoint with QHIN-credential authentication. A dispute-tracking DynamoDB table keyed on (dispute_id, escalation_event_id). An audit-archive S3 bucket for dispute artifacts with Object Lock in Compliance mode.
  • Cross-QHIN audit-log-export interface. Per-dispute access-control envelope with time-bound and scope-bound authorization (the requesting QHIN can access only the audit events related to the disputed query, not the participant's full audit log). Per-QHIN audit-log-export Lambda invoked through Step Functions cross-QHIN orchestration. Audit logging on every cross-QHIN audit-log-export (who requested, what scope, what was returned).
  • Dispute-resolution-outcome propagation. Outcome propagated through the EventBridge fan-out with explicit dispute-outcome event-types: tefca_dispute_resolved, tefca_dispute_held, tefca_dispute_escalated. Each outcome event carries the dispute-id, the resolution summary, the responsible parties, and the remediation actions.

Federation-scale capacity coordination. The federation's capacity dynamics require participant-side tooling:

  • Participant-side capacity-reservation tooling. A capacity-coordination event consumer Lambda monitors the QHIN's capacity-coordination signals. A per-source rate-limit configuration store in DynamoDB holds the current rate limits per source QHIN and per source participant. A rate-limit-update Lambda adjusts the configuration in response to capacity-coordination events. CloudWatch metrics on per-source rate-limit utilization.
  • Per-source rate-limiting discipline. Per-source quota in DynamoDB (queries per second per source). A rate-limit-evaluation Lambda at inbound-query-handling time checks the current rate against the quota. Rejection semantics for rate-limit breaches: explicit fail-fast with a structured rate-limit-exceeded response and audit logging on every rejection.
  • QHIN operational-interface integration. Participant-to-QHIN capacity-status emission per-cycle (the participant reports its current capacity posture to the QHIN). QHIN-to-participant capacity-coordination signal consumption (the QHIN notifies the participant of federation-wide capacity events). Audit-and-monitoring discipline on both directions.
  • Federation-wide capacity-coordination cascade-mitigation. Per-source error-rate monitoring with escalation thresholds (error rate > 10% from a single source = MEDIUM alarm; > 25% = HIGH). Per-source automatic-circuit-breaker (the inbound-query-handler stops accepting queries from the degraded source for a configurable backoff period). Priority routing for capacity-coordination events (capacity events bypass the standard event processing queue).

Variations and Extensions

QHIN-operator architecture. Rather than operating as a participant in someone else's QHIN, the institution operates its own QHIN, signing the Common Agreement directly and providing federation services to its own participants and to other QHINs. The architectural extension is the cross-QHIN router (the inverse of the participant-side query handler: the router accepts queries from external QHINs and routes them to the QHIN's participants), the QHIN's operational interface (governance and dispute coordination with other QHINs), and the QHIN's participant-onboarding pipeline (each new participant is onboarded with technical certification, governance review, operational testing). The QHIN role is a substantially larger operational program than the participant role; the institutions that succeed as QHINs are typically established health-information networks, vendor-mediated networks, or large integrated-delivery networks with the operational maturity to absorb the role's demands.

FHIR-based exchange migration. As the framework's FHIR-based exchange patterns mature, the participant migrates from IHE-based exchange (XCPD for patient discovery, XCA for cross-community access) to FHIR-based exchange (the Patient $match operation, the Bulk FHIR specification for population-scale queries). The architectural extension is a parallel FHIR-based gateway that operates alongside the IHE-based gateway during the migration window, with explicit cross-format compatibility (queries arriving in one format produce responses in either format depending on the responder's capability). The migration is operational rather than just technical: the FHIR-based exchange has different audit-and-attribution conventions, different authentication patterns, different error semantics, and the institution's operational discipline has to span both formats during the migration.

Patient-mediated access through the Patient Access API. The CMS Patient Access API rule and the ONC information-blocking rule have created regulatory pressure for patient-mediated access. The architectural extension is a patient-mediated query path that operates alongside the staff-initiated path: the patient's personal-health-record app authenticates the patient through the participant's patient-portal IdP, the app initiates the cross-network query under the patient's authorization, the federation's responses are consolidated and returned to the app, and the app presents the unified longitudinal view to the patient. The pattern is becoming a non-trivial fraction of cross-network query traffic at the QHINs that have integrated it, and the institutional integration is a separate operational program with its own technical specifications, its own user-experience considerations, and its own audit-and-attribution requirements.

Federated analytics extension. TEFCA's primary focus is record exchange for treatment-and-operational use cases; federated analytics (queries that aggregate across participants without retrieving individual records) is a natural extension that leverages the same federation routing infrastructure for population-scale queries. The architectural extension is an analytics-query handler that consumes federated-aggregate queries from research consortia, public-health agencies, or other authorized analytic consumers, runs the aggregate computation against the participant's local data under the appropriate authorization framework, and returns the aggregated results without exposing the individual records. The pattern complements the privacy-preserving record linkage from recipe 5.8 and provides a population-scale analytic substrate that does not require record-level disclosure.

Privacy-preserving cross-organizational matching through TEFCA's routing layer. Recipe 5.8's privacy-preserving record linkage operates between two or more participating organizations under a multi-party trust framework. The architectural extension is to leverage TEFCA's routing layer for the cross-organizational exchange portion of the PPRL pipeline: the encoded payloads route through the QHIN's federation rather than through a separate point-to-point exchange. The pattern reduces the operational overhead of bilateral exchange relationships and lets the PPRL pipeline operate at federation scale; the trade-off is that the QHIN's framework's authentication and authorization layer has to accommodate the PPRL-specific data flows (which are not standard TEFCA exchange purposes as of writing).

Cross-recipe coordination with longitudinal name-change handling. Recipe 5.7's longitudinal-name-change handling produces an identity-history representation that the participant maintains for its own MPI. The architectural extension is propagating the identity-history representation into the cross-network matcher's tolerance: a query that arrives under a patient's prior name should match against the identity's prior name (with the appropriate temporal weighting) rather than only against the current name. The cross-network response includes the per-record identity-history attribution where the framework's specifications permit; the federation as a whole evolves toward identity-history-aware matching as the participating MPIs mature.

Sensitivity-flag coordination across the federation. Recipe 5.7 introduces sensitivity flags for gender-affirming-care records, witness-protection records, and other sensitivity-classified records. The architectural extension is propagating the sensitivity flags through the cross-network response (the responder indicates the candidate is sensitivity-flagged without exposing the underlying classification reason; the originating participant honors the flag in the consolidated view by suppressing the candidate's demographic features or by routing the candidate to a more-restrictive disclosure form). The framework as a whole evolves toward sensitivity-aware matching, with the per-jurisdiction overlay rules providing the regulatory baseline.

Information-blocking-exception handling automation. The information-blocking rule's exceptions (Privacy Exception, Security Exception, Infeasibility Exception, Health IT Performance Exception, Content and Manner Exception, Fees Exception, Licensing Exception) provide structured ways for the participant to decline a query without violating the rule. The architectural extension is an exception-handling pipeline that evaluates each query's circumstances against the applicable exceptions, returns a structured "denied-under-exception" response with the exception code, and audit-logs the denial decision with the inputs that led to the exception's invocation. The pattern is operationally important for participants whose queries cannot be handled in the standard response window or whose policy excludes specific record types from the standard exchange purposes.

Capacity coordination across QHINs. The federation-wide capacity dynamics are coordinated through the QHIN's operational interface. The architectural extension is participant-side capacity-reservation tooling that consumes the QHIN's capacity-coordination signals, adjusts the participant's local rate-limiting and capacity-reservation in response, and emits the participant's capacity status back to the QHIN. The pattern is becoming operationally important as the federation's volume grows and as the cascade dynamics of capacity events become more visible.

Active-learning-driven cross-network-tolerance tuning. As the cross-network-match-review queue resolves cases, the labels feed a periodic re-training of the cross-network tolerance and the per-feature weights. Active learning concentrates the review effort on the cases that most improve the downstream accuracy and the cohort fairness; over time, the review queue depth decreases as the matcher absorbs the labeled cases. The active-learning pattern is constrained by the cross-network-data limitation (the labels are on the federation's responses, not on the responder's underlying records; the calibration has to be careful about which signals it can extract from the federation's response without overstepping the framework's specifications).

Audit-summary delivery to the patient. As part of the patient-experience layer, the patient may opt to receive periodic summaries of how her record has been queried across the federation, with the queries, the requesting participants, the use cases, the disclosure forms, and the responding sources identified. The architectural extension is a patient-portal summary-delivery service that aggregates the per-query inclusion records (filtered to the patient's own data) and delivers them on the patient's chosen cadence. The pattern is becoming an expected disclosure for patients in jurisdictions with strong data-rights regulations and is consistent with the framework's individual-access-services exchange purpose.

Cross-jurisdictional overlay-rule federation. Rather than each participant maintaining its own overlay-rule engine independently, a shared overlay-rule federation lets participants subscribe to a common rule store with explicit per-jurisdiction subscriptions. The architectural extension is the rule-federation publisher (which curates the per-jurisdiction overlay rules from the regulatory-monitoring function and publishes them to subscribers), the rule-federation subscriber (which consumes the published rules and integrates them with the participant's local overlay-rule engine), and the rule-version-coordination layer (which ensures the rule versions across the federation are consistent). The pattern reduces the per-participant overhead of maintaining the overlay-rule engine independently and produces a more consistent overlay-rule application across the federation.


Additional Resources

AWS Documentation:

AWS Sample Repos:

AWS Solutions and Blogs:

External References (Standards and Frameworks):

External References (Industry):


Estimated Implementation Time

Tier Scope Time
Basic Single-QHIN participant integration with one exchange purpose (treatment), IHE-based exchange (XCPD and XCA), basic cross-network-tolerance calibration, standard authentication and authorization, basic audit-and-attribution layer, single-jurisdiction-overlay handling 9-15 months (including QHIN onboarding)
Production-ready Multi-QHIN participant integration with multiple exchange purposes (treatment, payment, operations, individual access services), IHE-and-FHIR-based exchange with parallel gateway support, dual-calibrated tolerances per use case, full authentication-and-authorization framework with QHIN-credential rotation ceremony, full audit-and-attribution layer with cross-QHIN attribution chain capture, multi-jurisdiction-overlay engine with regulatory-monitoring function, three-queue review tooling (cross-network-match-review, dispute-review, governance-evolution), patient-mediated access through Patient Access API, information-blocking-exception handling, complete CloudTrail and audit-retention posture, consent-capture and consent-withdrawal pathways with patient-facing communication, capacity-coordination tooling 18-36 months (including QHIN onboarding and federation-participation program ramp)
With variations Add QHIN-operator architecture, FHIR-based exchange migration, federated analytics extension, PPRL-and-TEFCA integration, identity-history-aware cross-network matching, sensitivity-flag coordination, capacity-coordination across QHINs, active-learning-driven tolerance tuning, audit-summary delivery to patient, cross-jurisdictional overlay-rule federation 12-24 months beyond production-ready


โ† Main Recipe 5.9 ยท Python Example ยท Chapter Preface