Contrôler l'accès aux ressources FHIR dans l'API Cloud Healthcare

Cette page explique comment utiliser les ressources de consentement FHIR pour déterminer l'accès aux données des stores FHIR dans l'API Cloud Healthcare.

Pour configurer un store FHIR avec application du consentement, procédez comme suit:

  1. Créez un store FHIR si vous n'en avez pas encore un.

  2. Définissez les paramètres ConsentConfig du store FHIR suivant pour activer l'application du consentement:

    • version: spécifie la version d'application du consentement utilisée pour le store FHIR. Cette valeur ne peut être définie qu'une seule fois avec CreateFhirStore ou UpdateFhirStore. Une fois cette option définie, vous devez appeler ApplyConsents ou ApplyAdminConsents pour modifier la version.

    • access_enforced: si la valeur est true, lors de l'accès aux ressources FHIR, les en-têtes de consentement fournis seront vérifiés par rapport aux instructions de consentement données par les consommateurs.

    • consent_header_handling : si la valeur est PERMIT_EMPTY_SCOPE (par défaut), le serveur autorise les requêtes sans en-tête X-Consent-Scope (ou vide). S'il est défini sur REQUIRED_ON_READ et que access_enforced = true, le serveur rejette toutes les requêtes sans en-tête X-Consent-Scope (ou vide).

Configurer un nouveau store FHIR avec ConsentConfig

curl -X POST \
    -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
    -H "Content-Type: application/json" \
    --data "{
      'version': 'R4',
      'enableUpdateCreate': true,
      'consentConfig': {
        'version': 'V1',
        'accessEnforced': true
      }
    }" "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores?fhirStoreId=FHIR_STORE_ID"

Vous devriez recevoir une réponse JSON de ce type :

{
  "name": "projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID",
  "version": "R4",
  "enableUpdateCreate": true,
  "consentConfig": {
    "version": "V1"
  }
}

Si vous disposez déjà d'un magasin, utilisez UpdateFhirStore pour définir ConsentConfig avec la version d'application du consentement sur V1 et accessEnforced sur true.

curl -X PATCH \
    -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
    -H "Content-Type: application/json" \
    --data "{
      'consentConfig': {
        'version': 'V1',
        'accessEnforced': true
      }
    }" "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID?update_mask=consentConfig"

Les règles sont représentées via la ressource de consentement. L'objectif et l'utilisation des champs de ressources sont décrits dans la documentation sur les modèles de données.

Voici un exemple de toutes les ressources qui peuvent être créées pour cet exemple.

Créer des ressources FHIR

L'exemple suivant montre comment exécuter un [bundle FHIR](/Health-api/docs/how-tos/fhir-bundles) pour remplir les ressources suivantes:

  • Une ressource de type Professionnel portant le nom Jeffrey Brown
  • Une ressource de type Patient portant le nom Darcy Smith
  • Ressource Observation montrant la mesure de l'hémoglobine de Darcy (LOINC718-7) qui a été collectée par l'hôpital Happy Hospital
  • Ressource "Observation" affichant la mesure du glucose par Darcy (LOINC15074-8).
  • Autorisation de Darcy à autoriser Jeffrey Brown à utiliser l'application App/123 pour accéder aux données collectées par l'hôpital Happy Hospital
  • Consentement de Darcy autorisant Jeffrey Brown à accéder à toutes ses données pour des traitements d'urgence (ETREAT)
  • Autorisation de l'hôpital Happy Hospital autorisant Jeffrey Brown à accéder à toutes les données lors de ses recherches biomédicales (BIORCH) avec l'application App/golden

cat > bundle.json << 'EOF'
{
  "resourceType": "Bundle",
  "type": "transaction",
  "entry": [
    {
      "request": {"method": "PUT", "url": "Practitioner/12942879-f89f-41ae-aa80-0b911b649833"},
      "resource": {
        "active": true,
        "birthDate": "1970-05-23",
        "gender": "male",
        "id": "12942879-f89f-41ae-aa80-0b911b649833",
        "name": [{
            "family": "Brown",
            "given": ["Jeffrey"],
            "use": "official"
        }],
        "resourceType": "Practitioner"
      }
    },
    {
      "request": {"method": "PUT", "url": "Patient/3c6aa096-c054-4c22-b2b4-1e4a4d203de2"},
      "resource": {
        "active": true,
        "birthDate": "1990-01-01",
        "gender": "female",
        "id": "3c6aa096-c054-4c22-b2b4-1e4a4d203de2",
        "name": [{
            "family": "Smith",
            "given": ["Darcy"],
            "use": "official"
        }],
        "meta": {
          "tag": [{
            "system": "http://terminology.hl7.org/CodeSystem/common-tags",
            "code": "employee"
          }]
        },
        "resourceType": "Patient"
      }
    },
    {
      "request": {"method": "PUT", "url": "Observation/7473784b-46a8-470c-b9a6-fe38a01025aa"},
      "resource": {
        "id": "7473784b-46a8-470c-b9a6-fe38a01025aa",
        "meta": {"source": "http://example.com/HappyHospital"},
        "code": {
          "coding": [{
            "code": "718-7",
            "system": "http://loinc.org",
            "display": "Hemoglobin [Mass/volume] in Blood"
          }]
        },
        "effectivePeriod": {"start": "2021-12-10T05:30:10+01:00"},
        "issued": "2021-12-10T13:30:10+01:00",
        "resourceType": "Observation",
        "status": "final",
        "subject": {"reference": "Patient/3c6aa096-c054-4c22-b2b4-1e4a4d203de2"},
        "valueQuantity": {
          "code": "g/dL",
          "system": "http://unitsofmeasure.org",
          "unit": "g/dl",
          "value": 7.2
        }
      }
    },
    {
      "request": {"method": "PUT", "url": "Observation/68583624-9921-4158-8754-2a306c689abd"},
      "resource": {
        "id": "68583624-9921-4158-8754-2a306c689abd",
        "code": {
          "coding": [{
            "code": "15074-8",
            "system": "http://loinc.org",
            "display": "Glucose [Moles/volume] in Blood"
          }]
        },
        "effectivePeriod": {"start": "2021-12-01T05:30:10+01:00"},
        "issued": "2021-12-01T13:30:10+01:00",
        "resourceType": "Observation",
        "status": "final",
        "subject": {"reference": "Patient/3c6aa096-c054-4c22-b2b4-1e4a4d203de2"},
        "valueQuantity": {
          "code": "mmol/L",
          "system": "http://unitsofmeasure.org",
          "unit": "mmol/l",
          "value": 6.3
        }
      }
    },
    {
      "request": {"method": "PUT", "url": "Consent/10998b60-a252-405f-aa47-0702554ddc8e"},
      "resource": {
        "category": [{
          "coding": [{
            "code": "59284-0",
            "system": "http://terminology.hl7.org/CodeSystem/consentcategorycodes"
          }]
        }],
        "id": "10998b60-a252-405f-aa47-0702554ddc8e",
        "patient": {"reference": "Patient/3c6aa096-c054-4c22-b2b4-1e4a4d203de2"},
        "policyRule": {
          "coding": [{
            "code": "OPTIN",
            "system": "http://terminology.hl7.org/CodeSystem/v3-ActCode"
          }]
        },
        "provision": {
          "actor": [
            {
              "reference": {"reference": "Practitioner/12942879-f89f-41ae-aa80-0b911b649833"},
              "role": {
                "coding": [{
                  "code": "GRANTEE",
                  "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode"
                }]
              }
            }
          ],
          "extension": [
            {
              "url": "https://g.co/fhir/medicalrecords/Environment",
              "valueCodeableConcept": {
                "coding": [{
                  "code": "123",
                  "system": "App"
                }]
              }
            },
            {
              "url": "https://g.co/fhir/medicalrecords/DataSource",
              "valueUri": "http://example.com/HappyHospital"
            }
          ],
          "type": "permit"
        },
        "resourceType": "Consent",
        "scope": {
          "coding": [{
            "code": "patient-privacy",
            "system": "http://terminology.hl7.org/CodeSystem/consentscope"
          }]
        },
        "status": "active"
      }
    },
    {
      "request": {"method": "PUT", "url": "Consent/73c54e8d-2789-403b-9dee-13085c5d5e34"},
      "resource": {
        "category": [{
          "coding": [{
            "code": "59284-0",
            "system": "http://terminology.hl7.org/CodeSystem/consentcategorycodes"
          }]
        }],
        "id": "73c54e8d-2789-403b-9dee-13085c5d5e34",
        "patient": {"reference": "Patient/3c6aa096-c054-4c22-b2b4-1e4a4d203de2"},
        "policyRule": {
          "coding": [{
            "code": "OPTIN",
            "system": "http://terminology.hl7.org/CodeSystem/v3-ActCode"
          }]
        },
        "provision": {
          "actor": [
            {
              "reference": {"reference": "Practitioner/12942879-f89f-41ae-aa80-0b911b649833"},
              "role": {
                "coding": [{
                  "code": "GRANTEE",
                  "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode"
                }]
              }
            }
          ],
          "purpose": [{
            "code": "ETREAT",
            "system": "http://terminology.hl7.org/CodeSystem/v3-ActReason"
          }],
          "type": "permit"
        },
        "resourceType": "Consent",
        "scope": {
          "coding": [{
            "code": "patient-privacy",
            "system": "http://terminology.hl7.org/CodeSystem/consentscope"
          }]
        },
        "status": "active"
      }
    },
    {
      "request": {"method": "PUT", "url": "Consent/5c8e3f8a-9fd5-480d-a08e-f29b89feccde"},
      "resource": {
        "category": [{
          "coding": [{
            "code": "57017-6",
            "system": "http://loinc.org"
          }]
        }],
        "id": "5c8e3f8a-9fd5-480d-a08e-f29b89feccde",
        "patient": {},
        "extension": [{
          "url": "https://g.co/fhir/medicalrecords/ConsentAdminPolicy"
        }],
        "policyRule": {
          "coding": [{
            "code": "OPTIN",
            "system": "http://terminology.hl7.org/CodeSystem/v3-ActCode"
          }]
        },
        "provision": {
          "actor": [
            {
              "reference": {"reference": "Practitioner/12942879-f89f-41ae-aa80-0b911b649833"},
              "role": {
                "coding": [{
                  "code": "GRANTEE",
                  "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode"
                }]
              }
            }
          ],
          "purpose": [{
            "code": "BIORCH",
            "system": "http://terminology.hl7.org/CodeSystem/v3-ActReason"
          }],
          "extension": [
            {
              "url": "https://g.co/fhir/medicalrecords/Environment",
              "valueCodeableConcept": {
                "coding": [{
                  "code": "golden",
                  "system": "App"
                }]
              }
            }
          ],
          "type": "permit"
        },
        "resourceType": "Consent",
        "scope": {},
        "status": "active"
      }
    }
  ]
}
EOF
curl -X POST \
    -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
    -H "Content-Type: application/fhir+json; charset=utf-8" \
    --data @bundle.json \
    "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir"

Vous devriez recevoir une réponse JSON de ce type :

{
  "entry": [
    {
      "response": {
        "etag": "W/\"VERSION_ID\"",
        "lastModified": "2022-09-01T17:31:40.423469+00:00",
        "location": "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Practitioner/12942879-f89f-41ae-aa80-0b911b649833/_history/VERSION_ID",
        "status": "201 Created"
      }
    },
    {
      "response": {
        "etag": "W/\"VERSION_ID\"",
        "lastModified": "2022-09-01T17:31:40.423469+00:00",
        "location": "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Patient/3c6aa096-c054-4c22-b2b4-1e4a4d203de2/_history/VERSION_ID",
        "status": "201 Created"
      }
    },
    {
      "response": {
        "etag": "W/\"VERSION_ID\"",
        "lastModified": "2022-09-01T17:31:40.423469+00:00",
        "location": "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation/7473784b-46a8-470c-b9a6-fe38a01025aa/_history/VERSION_ID",
        "status": "201 Created"
      }
    },
    {
      "response": {
        "etag": "W/\"VERSION_ID\"",
        "lastModified": "2022-09-01T17:31:40.423469+00:00",
        "location": "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation/68583624-9921-4158-8754-2a306c689abd/_history/VERSION_ID",
        "status": "201 Created"
      }
    },
    {
      "response": {
        "etag": "W/\"VERSION_ID\"",
        "lastModified": "2022-09-01T17:31:40.423469+00:00",
        "location": "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Consent/10998b60-a252-405f-aa47-0702554ddc8e/_history/VERSION_ID",
        "status": "201 Created"
      }
    },
    {
      "response": {
        "etag": "W/\"VERSION_ID\"",
        "lastModified": "2022-09-01T17:31:40.423469+00:00",
        "location": "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Consent/73c54e8d-2789-403b-9dee-13085c5d5e34/_history/VERSION_ID",
        "status": "201 Created"
      }
    },
    {
      "response": {
        "etag": "W/\"VERSION_ID\"",
        "lastModified": "2022-09-01T17:31:40.423469+00:00",
        "location": "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Consent/5c8e3f8a-9fd5-480d-a08e-f29b89feccde/_history/VERSION_ID",
        "status": "201 Created"
      }
    }
  ],
  "resourceType": "Bundle",
  "type": "transaction-response"
}

Vous trouverez ci-dessous d'autres exemples de ressource de consentement R4 qui montrent comment des règles complexes peuvent être représentées.

{
  "resourceType": "Consent",
  "id": "patient-consent-example",
  "patient": {
    "reference": "Patient/f001"
  },
  "category": [
    {
      "coding": [
        {
          "system": "http://loinc.org",
          "code": "59284-0"
        }
      ]
    }
  ],
  "scope": {
    "coding": [
      {
        "system": "http://terminology.hl7.org/CodeSystem/consentscope",
        "code": "patient-privacy"
      }
    ]
  },
  "policyRule": {
    "coding": [
      {
        "system": "http://terminology.hl7.org/CodeSystem/v3-ActCode",
        "code": "OPTIN"
      }
    ]
  },
  "status": "active",
  "provision": {
    "type": "permit",
    "actor": [
      {
        "reference": {
          "reference": "Practitioner/f002"
        },
        "role": {
          "coding": [
            {
              "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode",
              "code": "GRANTEE"
            }
          ]
        }
      }
    ],
    "purpose": [
      {
        "system": "http://terminology.hl7.org/CodeSystem/v3-ActReason",
        "code": "TREAT"
      }
    ],
    "class": [
      {
        "system": "http://hl7.org/fhir/resource-types",
        "code": "Encounter"
      }
    ],
    "data": [
      {
        "meaning": "instance",
        "reference": {
          "reference": "Encounter/e001"
        }
      }
    ],
    "extension": [
      {
        "url": "https://g.co/fhir/medicalrecords/Environment",
        "valueCodeableConcept": {
          "coding": [
            {
              "system": "iso3166-1",
              "code": "CA"
            }
          ]
        }
      },
      {
        "url": "https://g.co/fhir/medicalrecords/DataTag",
        "valueCoding": {
          "system": "http://terminology.hl7.org/CodeSystem/common-tags",
          "code": "actionable"
        }
      },
      {
        "url": "https://g.co/fhir/medicalrecords/DataTag",
        "extension": [
          {
            "url": "https://g.co/fhir/medicalrecords/DataTag",
            "valueCoding": {
              "system": "http://example.com/custom-tags",
              "code": "archived"
            }
          },
          {
            "url": "https://g.co/fhir/medicalrecords/DataTag",
            "valueCoding": {
              "system": "http://example.com/custom-tags",
              "code": "insensitive"
            }
          }
        ]
      },
      {
        "url": "https://g.co/fhir/medicalrecords/DataSource",
        "valueUri": "http://somesystem.example.org/foo"
      }
    ],
    "securityLabel": [
      {
        "system": "http://terminology.hl7.org/CodeSystem/v3-Confidentiality",
        "code": "R"
      },
      {
        "system": "http://terminology.hl7.org/CodeSystem/v3-ActCode",
        "code": "PSY"
      }
    ]
  }
}

L'exemple précédent représente une ressource de consentement pour un patient dans laquelle un patient f001 autorise un praticien f002 dans le but de fournir un traitement régulier représenté par TREAT. Ce professionnel se trouve dans la zone géographique iso3166-1/CA. Cette ressource Consent permet au praticien d'accéder aux données du patient si celles-ci remplissent toutes les conditions suivantes.

  • Il s'agit d'un type Encounter avec l'ID Encounter/e001.
  • Elle provient de la source http://somesystem.example.org/foo.
  • Il remplit au moins l'une des conditions suivantes sur la balise (il est possible de baliser les ressources en définissant les champs system et code du fichier Meta.tag):
    • Comporte le tag (system = http://terminology.hl7.org/CodeSystem/common-tags et code = actionable)
    • Comporte les deux tags (system = http://example.com/custom-tags et code = archived) et (system = http://example.com/custom-tags et code = insensitive)
  • Il est associé à au moins l'une des étiquettes de sécurité suivantes :
    • system = http://terminology.hl7.org/CodeSystem/v3-Confidentiality et code est l'une des valeurs suivantes : R, N, M, L ou U.
    • system = http://terminology.hl7.org/CodeSystem/v3-ActCode et code = PSY.

Exemple de directive d'administration

{
  "resourceType": "Consent",
  "id": "admin-policy-example",
  "patient": {},
  "extension": [{
    "url": "https://g.co/fhir/medicalrecords/ConsentAdminPolicy"
  }],
  "category": [
    {
      "coding": [
        {
          "system": "http://loinc.org",
          "code": "57017-6"
        }
      ]
    }
  ],
  "scope": {},
  "policyRule": {
    "coding": [
      {
        "system": "http://terminology.hl7.org/CodeSystem/v3-ActCode",
        "code": "OPTIN"
      }
    ]
  },
  "status": "active",
  "provision": {
    "type": "permit",
    "actor": [
      {
        "reference": {
          "reference": "Practitioner/f002"
        },
        "role": {
          "coding": [
            {
              "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode",
              "code": "GRANTEE"
            }
          ]
        }
      }
    ],
    "purpose": [
      {
        "system": "http://terminology.hl7.org/CodeSystem/v3-ActReason",
        "code": "TREAT"
      }
    ],
    "class": [
      {
        "system": "http://hl7.org/fhir/resource-types",
        "code": "Encounter"
      }
    ],
    "data": [
      {
        "meaning": "instance",
        "reference": {
          "reference": "Encounter/e001"
        }
      }
    ],
    "extension": [
      {
        "url": "https://g.co/fhir/medicalrecords/Environment",
        "valueCodeableConcept": {
          "coding": [
            {
              "system": "iso3166-1",
              "code": "CA"
            }
          ]
        }
      },
      {
        "url": "https://g.co/fhir/medicalrecords/DataTag",
        "valueCoding": {
          "system": "http://terminology.hl7.org/CodeSystem/common-tags",
          "code": "actionable"
        }
      },
      {
        "url": "https://g.co/fhir/medicalrecords/DataTag",
        "extension": [
          {
            "url": "https://g.co/fhir/medicalrecords/DataTag",
            "valueCoding": {
              "system": "http://example.com/custom-tags",
              "code": "archived"
            }
          },
          {
            "url": "https://g.co/fhir/medicalrecords/DataTag",
            "valueCoding": {
              "system": "http://example.com/custom-tags",
              "code": "insensitive"
            }
          }
        ]
      },
      {
        "url": "https://g.co/fhir/medicalrecords/DataSource",
        "valueUri": "http://somesystem.example.org/foo"
      }
    ],
    "securityLabel": [
      {
        "system": "http://terminology.hl7.org/CodeSystem/v3-Confidentiality",
        "code": "R"
      },
      {
        "system": "http://terminology.hl7.org/CodeSystem/v3-ActCode",
        "code": "PSY"
      }
    ]
  }
}

L'exemple précédent représente une ressource de consentement pour une règle d'administration qui donne l'autorisation f002 à un professionnel dans le but de fournir un traitement régulier représenté par TREAT. Il provient de la géolocalisation iso3166-1/CA. Cette ressource Consent permet au professionnel d'accéder aux données du patient si celles-ci remplissent toutes les conditions suivantes:

  • Il s'agit d'un type Encounter avec l'ID Encounter/e001.
  • Elle provient de la source http://somesystem.example.org/foo.
  • Il remplit au moins l'une des conditions suivantes sur la balise:
    • Comporte le tag (system = http://terminology.hl7.org/CodeSystem/common-tags et code = actionable)
    • Comporte les deux tags (system = http://example.com/custom-tags et code = archived) et (system = http://example.com/custom-tags et code = insensitive)
  • Il est associé à au moins l'une des étiquettes de sécurité suivantes :
    • system = http://terminology.hl7.org/CodeSystem/v3-Confidentiality et code est l'une des valeurs suivantes : R, N, M, L ou U.
    • system = http://terminology.hl7.org/CodeSystem/v3-ActCode et code = PSY.

Exemple de directive administrateur en cascade

{
  "resourceType": "Consent",
  "id": "admin-cascading-policy-example",
  "patient": {},
  "extension": [
    { "url": "https://g.co/fhir/medicalrecords/ConsentAdminPolicy" },
    { "url": "https://g.co/fhir/medicalrecords/CascadingPolicy" }
  ],
  "category": [
    {
      "coding": [
        {
          "system": "http://loinc.org",
          "code": "57017-6"
        }
      ]
    }
  ],
  "scope": {},
  "policyRule": {
    "coding": [
      {
        "system": "http://terminology.hl7.org/CodeSystem/v3-ActCode",
        "code": "OPTIN"
      }
    ]
  },
  "status": "active",
  "provision": {
    "type": "permit",
    "actor": [
      {
        "reference": {
          "reference": "Practitioner/f002"
        },
        "role": {
          "coding": [
            {
              "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode",
              "code": "GRANTEE"
            }
          ]
        }
      }
    ],
    "purpose": [
      {
        "system": "http://terminology.hl7.org/CodeSystem/v3-ActReason",
        "code": "TREAT"
      }
    ],
    "class": [
      {
        "system": "http://hl7.org/fhir/resource-types",
        "code": "Patient"
      }
    ],
    "extension": [
      {
        "url": "https://g.co/fhir/medicalrecords/Environment",
        "valueCodeableConcept": {
          "coding": [
            {
              "system": "iso3166-1",
              "code": "CA"
            }
          ]
        }
      },
      {
        "url": "https://g.co/fhir/medicalrecords/DataTag",
        "valueCoding": {
          "system": "http://terminology.hl7.org/CodeSystem/common-tags",
          "code": "employee"
        }
      }
    ]
  }
}

L'exemple précédent représente une ressource de consentement en cascade d'une règle en cascade accordant l'autorisation f002 à un professionnel dans le but de fournir un traitement régulier représenté par TREAT. Il provient de la géolocalisation iso3166-1/CA. Cette ressource Consentement permet au praticien d'accéder aux données du compartiment des patients avec la balise employee. Tous les critères de ressource ne s'appliquent qu'aux ressources de base du compartiment, c'est-à-dire à la ressource patient, car elles contrôlent les ressources à partir desquelles effectuer la cascade d'annonces.

Appliquez des règles d'administration ou le consentement des patients

Faire respecter le consentement du patient d'ici le ApplyConsents

curl -X POST \
    -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
    -H "Content-Type: application/json" \
    --data "{'validateOnly': false}" \
    "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID:applyConsents"

Vous devriez recevoir une réponse JSON de ce type :

{
  "name": "projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID"
}

La réponse contient un nom d'opération. Pour suivre l'état de l'opération, vous pouvez utiliser la [méthode d'opération "get"](/Health-api/docs/reference/rest/v1/projects.locations.datasets.operations/get):

curl -X GET \
    -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
    "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID"

Une fois l'opération terminée, le serveur renvoie une réponse indiquant l'état de l'opération au format JSON:

{
  "name": "projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID"",
  "metadata": {
    "@type": "type.googleapis.com/google.cloud.healthcare.v1beta1.OperationMetadata",
    "apiMethodName": "google.cloud.healthcare.v1beta1.fhir.FhirStoreService.ApplyConsents",
    "createTime": "CREATE_TIME",
    "endTime": "END_TIME",
    "logsUrl": "https://console.cloud.google.com/logs/query/CLOUD_LOGGING_URL",
    "counter": {
      "success": "2",
      "secondarySuccess": "5"
    }
  },
  "done": true,
  "response": {
    "@type": "type.googleapis.com/google.cloud.healthcare.v1beta1.fhir.ApplyConsentsResponse",
    "consentApplySuccess": "2",
    "affectedResources": "5"
  }
}

Cette réponse indique que le serveur a traité avec succès deux autorisations et mis à jour l'accès consensuel de cinq ressources (1 patient, 2 autorisations et 2 observations).

Appliquez la règle d'administration d'ici le ApplyAdminConsents

curl -X POST \
    -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
    -H "Content-Type: application/json" \
    --data "{
      'validateOnly': false,
      'newConsentsList': {
        'names': ['projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Consent/5c8e3f8a-9fd5-480d-a08e-f29b89feccde/_history/VERSION_ID']
      }
    }" \
    "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID:applyAdminConsents"

Vous devriez recevoir une réponse JSON de ce type :

{
  "name": "projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID"
}

La réponse contient un nom d'opération. Pour suivre l'état de l'opération, vous pouvez utiliser la [méthode d'opération "get"](/Health-api/docs/reference/rest/v1/projects.locations.datasets.operations/get):

curl -X GET \
    -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
    "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID"

Une fois l'opération terminée, le serveur renvoie une réponse indiquant l'état de l'opération au format JSON:

{
  "name": "projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID"",
  "metadata": {
    "@type": "type.googleapis.com/google.cloud.healthcare.v1beta1.OperationMetadata",
    "apiMethodName": "google.cloud.healthcare.v1beta1.fhir.FhirStoreService.ApplyAdminConsents",
    "createTime": "CREATE_TIME",
    "endTime": "END_TIME",
    "logsUrl": "https://console.cloud.google.com/logs/query/CLOUD_LOGGING_URL",
    "counter": {
      "success": "1",
      "secondarySuccess": "7"
    }
  },
  "done": true,
  "response": {
    "@type": "type.googleapis.com/google.cloud.healthcare.v1beta1.fhir.ApplyAdminConsentsResponse",
    "consentApplySuccess": "1",
    "affectedResources": "7"
  }
}

Cette réponse indique que le serveur a traité avec succès une règle d'administration et mis à jour l'accès consensuel de sept ressources (1 praticien, 1 patient, 2 observations, 2 consentements des patients et 1 règle d'administration).

L'application des autorisations stockées dans un store FHIR n'entrera en vigueur que lorsque ApplyConsents (pour les consentements des patients) ou ApplyAdminConsents (pour les règles d'administration et les règles en cascade d'administration) aura été appelé et abouti. Si vous ajoutez, modifiez ou supprimez des autorisations après avoir exécuté ApplyConsents ou ApplyAdminConsents, vous devez l'exécuter à nouveau pour qu'ils soient inclus dans le modèle d'application.

Les ressources FHIR sont indexées de manière asynchrone. Il peut donc y avoir un léger décalage entre le moment où ApplyConsents ou ApplyAdminConsents se termine et le moment où le modèle d'application est reflété dans les résultats de recherche. Ce délai n'est attendu que pour les requêtes de recherche.

Si c'est la première fois que vous configurez l'application du consentement sur le store FHIR, attendez la fin de l'opération de longue durée ApplyConsents ou ApplyAdminConsents avant d'effectuer des requêtes compatibles avec le consentement.

Pour appeler ApplyConsents sur un sous-ensemble de patients, vous pouvez utiliser les filtres suivants:

  • PatientScope : pour exécuter ApplyConsents sur une liste d'ID de patients contenant jusqu'à 10 000 patients

  • TimeRange : pour exécuter ApplyConsent sur une liste d'ID de ressources patient dont les ressources Consentement sont mises à jour pendant une certaine période.

Pour appeler ApplyAdminConsents, vous devez fournir la liste complète de toutes les règles que vous souhaitez appliquer (et non une liste incrémentielle). Par conséquent, une liste vide annulera l'application de toutes les règles d'administration du magasin. Chaque stratégie doit correspondre à un nom de version de ressource si le magasin FHIR utilise la gestion des versions, ou à un nom de ressource dans le cas contraire.

Vous pouvez utiliser operations.get pour récupérer la valeur ProgressCounter de l'opération. Une fois l'opération terminée, une réponse ApplyConsentsResponse est incluse dans le Operation.response. Les compteurs dans ProgressCounter et ApplyConsentsResponse ou ApplyAdminConsentsResponse sont décrits dans le tableau suivant.

ProgressCounter ApplyConsentsResponse ou ApplyAdminConsentsResponse Description
success consentApplySuccess Nombre de ressources de consentement pour lesquelles l'opération a bien été traitée.
failure consentApplyFailure Nombre de ressources de consentement non compatibles ou non valides. Vous pouvez afficher les journaux d'erreurs dans Cloud Logging ou, lorsque validateOnly est défini sur false, vérifier l'état de l'application du consentement à l'aide de CheckConsentEnforcementStatus ou de CheckPatientConsentEnforcementStatus pour récupérer les détails des erreurs.
secondarySuccess affectedResources Lorsque validateOnly est défini sur false, il représente le nombre de ressources FHIR qui ont bien été réindexées en raison des effets de la modification du consentement.
secondaryFailure failedResources Lorsque validateOnly est défini sur false, il représente le nombre de ressources FHIR qui peuvent avoir un changement de consentement, mais qui n'ont pas pu être réindexées. Cela peut affecter la recherche en fonction du contexte de consentement, mais pas les autres méthodes. Pour afficher les détails des erreurs, vous pouvez afficher les journaux d'erreurs dans Cloud Logging.

Lors du traitement des ressources de consentement FHIR, vous pouvez utiliser les API suivantes pour vérifier l'état de l'application pour un seul consentement ou pour tous les consentements d'un patient:

Pour une règle d'administration, CheckConsentEnforcementStatus ne peut être utilisé que pour vérifier l'état d'application d'une seule règle d'administration de consentement. Vous pouvez également utiliser fhirStores.get pour afficher toutes les règles d'administration actives appliquées au magasin.

Le consent-enforcement-status peut avoir l'une des valeurs suivantes:

  • OFF: représente l'état d'application par défaut d'une nouvelle ressource de consentement dans laquelle la ressource Consent n'a jamais été traitée.

  • ENFORCEABLE: état dans lequel la ressource d'autorisation a été traitée.

  • INACTIVE: état inactif dans lequel la ressource d'autorisation est ignorée.

  • UNSUPPORTED: état d'une ressource de consentement qui peut être conforme aux spécifications FHIR, mais qui n'est pas applicable. Cela est dû à la mise en œuvre limitée de l'application du consentement FHIR avec le niveau actuel de compatibilité des fonctionnalités.

  • ENFORCEMENT_LIMIT_EXCEEDED: état lorsque le format de la ressource de consentement FHIR et le niveau de compatibilité de la ressource sont exempts d'erreur, mais une ou plusieurs des conditions suivantes sont remplies:

    • Le patient dispose d'un large ensemble de ressources d'autorisation.

    • La taille des instructions d'autorisation pour toutes les autorisations actives est supérieure à la taille maximale autorisée pour appliquer les instructions d'autorisation d'un serveur FHIR.

L'API Cloud Healthcare permet de rechercher des ressources FHIR dans un magasin FHIR donné avec actor, purpose et environment comme paramètres de requête. La réponse ne contient que les ressources autorisées.

  1. Le praticien Jeffrey Brown (identifié par Practitioner/12942879-f89f-41ae-aa80-0b911b649833) utilisant une application fiable App/123 recherche toutes les observations avec status=final.
  2. curl -X GET \
        -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
        -H "X-Consent-Scope: actor/Practitioner/12942879-f89f-41ae-aa80-0b911b649833 env/App/123" \
        "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation?status=final"
    

    Vous devriez recevoir une réponse JSON de ce type :

    {
      "entry": [
        {
          "fullUrl": "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION_ID/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation/7473784b-46a8-470c-b9a6-fe38a01025aa",
          "resource": {
            "code": {
              "coding": [
                {
                  "code": "718-7",
                  "display": "Hemoglobin [Mass/volume] in Blood",
                  "system": "http://loinc.org"
                }
              ]
            },
            "effectivePeriod": {
              "start": "2021-12-10T05:30:10+01:00"
            },
            "id": "7473784b-46a8-470c-b9a6-fe38a01025aa",
            "issued": "2021-12-10T13:30:10+01:00",
            "meta": {
              "lastUpdated": "2022-09-01T17:31:40.423469+00:00",
              "source": "http://example.com/HappyHospital",
              "versionId": "VERSION_ID"
            },
            "resourceType": "Observation",
            "status": "final",
            "subject": {
              "reference": "Patient/3c6aa096-c054-4c22-b2b4-1e4a4d203de2"
            },
            "valueQuantity": {
              "code": "g/dL",
              "system": "http://unitsofmeasure.org",
              "unit": "g/dl",
              "value": 7.2
            }
          },
          "search": {
            "mode": "match"
          }
        }
      ],
      "link": [
        {
          "relation": "search",
          "url": "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation/?status=final"
        },
        {
          "relation": "first",
          "url": "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation/?status=final"
        },
        {
          "relation": "self",
          "url": "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation/?status=final"
        }
      ],
      "resourceType": "Bundle",
      "total": 1,
      "type": "searchset"
    }
    
  3. Le praticien Jeffrey Brown (identifié par Practitioner/12942879-f89f-41ae-aa80-0b911b649833) utilisant l'application App/123 recherche toutes les observations du patient Darcy.
  4. curl -X GET \
        -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
        -H "X-Consent-Scope: actor/Practitioner/12942879-f89f-41ae-aa80-0b911b649833 env/App/123" \
        "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation?subject:Patient.name=Darcy"
    

    Vous devriez recevoir une réponse JSON de ce type :

    {
      "link": [
        {
          "relation": "search",
          "url": "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation/?subject%3APatient.name=Darcy"
        },
        {
          "relation": "first",
          "url": "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation/?subject%3APatient.name=Darcy"
        },
        {
          "relation": "self",
          "url": "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation/?subject%3APatient.name=Darcy"
        }
      ],
      "resourceType": "Bundle",
      "total": 0,
      "type": "searchset"
    }
    

    La requête précédente est une recherche en chaîne. Étant donné que le scénario de consentement actor/Practitioner/12942879-f89f-41ae-aa80-0b911b649833 env/App/123 se voit refuser l'accès à la ressource Patient Darcy (identifiée par Patient/3c6aa096-c054-4c22-b2b4-1e4a4d203de2), le serveur FHIR ne renvoie aucune observation du patient, comme si le patient n'existait pas.

  5. Le praticien Jeffrey Brown (identifié par Practitioner/12942879-f89f-41ae-aa80-0b911b649833) utilisant l'application App/123 recherche toutes les observations du patient Darcy à des fins de traitement d'urgence.
  6. curl -X GET \
        -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
        -H "X-Consent-Scope: actor/Practitioner/12942879-f89f-41ae-aa80-0b911b649833 purp/v3/ETREAT env/App/123" \
        "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation?subject:Patient.name=Darcy"
    

    Vous devriez recevoir une réponse JSON de ce type :

    {
      "entry": [
        {
          "fullUrl": "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation/68583624-9921-4158-8754-2a306c689abd",
          "resource": {
            "code": {
              "coding": [
                {
                  "code": "15074-8",
                  "display": "Glucose [Moles/volume] in Blood",
                  "system": "http://loinc.org"
                }
              ]
            },
            "effectivePeriod": {
              "start": "2021-12-01T05:30:10+01:00"
            },
            "id": "68583624-9921-4158-8754-2a306c689abd",
            "issued": "2021-12-01T13:30:10+01:00",
            "meta": {
              "lastUpdated": "2022-09-01T17:31:40.423469+00:00",
              "versionId": "VERSION_ID"
            },
            "resourceType": "Observation",
            "status": "final",
            "subject": {
              "reference": "Patient/3c6aa096-c054-4c22-b2b4-1e4a4d203de2"
            },
            "valueQuantity": {
              "code": "mmol/L",
              "system": "http://unitsofmeasure.org",
              "unit": "mmol/l",
              "value": 6.3
            }
          },
          "search": {
            "mode": "match"
          }
        },
        {
          "fullUrl": "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation/7473784b-46a8-470c-b9a6-fe38a01025aa",
          "resource": {
            "code": {
              "coding": [
                {
                  "code": "718-7",
                  "display": "Hemoglobin [Mass/volume] in Blood",
                  "system": "http://loinc.org"
                }
              ]
            },
            "effectivePeriod": {
              "start": "2021-12-10T05:30:10+01:00"
            },
            "id": "7473784b-46a8-470c-b9a6-fe38a01025aa",
            "issued": "2021-12-10T13:30:10+01:00",
            "meta": {
              "lastUpdated": "2022-09-01T17:31:40.423469+00:00",
              "source": "http://example.com/HappyHospital",
              "versionId": "VERSION_ID"
            },
            "resourceType": "Observation",
            "status": "final",
            "subject": {
              "reference": "Patient/3c6aa096-c054-4c22-b2b4-1e4a4d203de2"
            },
            "valueQuantity": {
              "code": "g/dL",
              "system": "http://unitsofmeasure.org",
              "unit": "g/dl",
              "value": 7.2
            }
          },
          "search": {
            "mode": "match"
          }
        }
      ],
      "link": [
        {
          "relation": "search",
          "url": "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation/?subject:Patient.name=Darcy"
        },
        {
          "relation": "first",
          "url": "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation/?subject:Patient.name=Darcy"
        },
        {
          "relation": "self",
          "url": "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation/?subject:Patient.name=Darcy"
        }
      ],
      "resourceType": "Bundle",
      "total": 2,
      "type": "searchset"
    }
    
  7. Le praticien Jeffrey Brown (identifié par Practitioner/12942879-f89f-41ae-aa80-0b911b649833) recherche les observations avec status=final à deux fins : le traitement et la recherche
  8. curl -X GET \
        -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
        -H "X-Consent-Scope: actor/Practitioner/12942879-f89f-41ae-aa80-0b911b649833 purp/v3/TREAT purp/v3/HRESCH" \
        "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation?status=final"
    

    Vous devriez recevoir une réponse JSON de ce type :

    {
      "issue": [
        {
          "code": "security",
          "details": {
            "text": "permission_denied"
          },
          "diagnostics": "the maximum number of allowed consent purpose scopes is 1, got 2",
          "severity": "error"
        }
      ],
      "resourceType": "OperationOutcome"
    }
    

    Dans ce cas, le professionnel Jeffrey Brown doit supprimer un objectif inutile de "X-Consent-Scope" dans la demande.

  9. Un administrateur informatique d'un hôpital utilise bypass pour rechercher tous les professionnels de l'hôpital.
  10. curl -X GET \
        -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
        -H "X-Consent-Scope: bypass actor/Admin/ef0592c9-6724-467e-878d-f879e537cd15 env/net/HappyNet" \
        "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Practitioner?"
    

    Comme bypass est fourni, les vérifications du consentement ont été ignorées. Vous devriez recevoir une réponse JSON semblable à celle-ci:

    {
      "entry": [
        {
          "fullUrl": "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Practitioner/12942879-f89f-41ae-aa80-0b911b649833",
          "resource": {
            "active": true,
            "birthDate": "1970-05-23",
            "gender": "male",
            "id": "12942879-f89f-41ae-aa80-0b911b649833",
            "meta": {
              "lastUpdated": "2022-09-01T17:31:40.423469+00:00",
              "versionId": "VERSION_ID"
            },
            "name": [
              {
                "family": "Brown",
                "given": [
                  "Jeffrey"
                ],
                "use": "official"
              }
            ],
            "resourceType": "Practitioner"
          },
          "search": {
            "mode": "match"
          }
        }
      ],
      "link": [
        {
          "relation": "search",
          "url": "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Practitioner/?"
        },
        {
          "relation": "first",
          "url": "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Practitioner/?"
        },
        {
          "relation": "self",
          "url": "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Practitioner/?"
        }
      ],
      "resourceType": "Bundle",
      "total": 1,
      "type": "searchset"
    }
    

L'API Cloud Healthcare permet d'obtenir une ressource FHIR dans un magasin FHIR donné avec actor, purpose et environment comme paramètres de requête. La réponse ne contient que les ressources autorisées.

  1. Le praticien Jeffrey Brown (identifié par Practitioner/12942879-f89f-41ae-aa80-0b911b649833) utilisant l'application App/123 lit la mesure d'hémoglobine du patient (dans cet exemple, Observation/7473784b-46a8-470c-b9a6-fe38a01025aa).
  2. curl -X GET \
        -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
        -H "X-Consent-Scope: actor/Practitioner/12942879-f89f-41ae-aa80-0b911b649833 env/App/123" \
        "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation/7473784b-46a8-470c-b9a6-fe38a01025aa"
    

    Comme le demandeur a obtenu son consentement, la réponse correspond au contenu de la ressource Observation.

    {
      "code": {
        "coding": [
          {
            "code": "718-7",
            "display": "Hemoglobin [Mass/volume] in Blood",
            "system": "http://loinc.org"
          }
        ]
      },
      "effectivePeriod": {
        "start": "2021-12-10T05:30:10+01:00"
      },
      "id": "7473784b-46a8-470c-b9a6-fe38a01025aa",
      "issued": "2021-12-10T13:30:10+01:00",
      "meta": {
        "lastUpdated": "2022-09-01T17:31:40.423469+00:00",
        "source": "http://example.com/HappyHospital",
        "versionId": "VERSION_ID"
      },
      "resourceType": "Observation",
      "status": "final",
      "subject": {
        "reference": "Patient/3c6aa096-c054-4c22-b2b4-1e4a4d203de2"
      },
      "valueQuantity": {
        "code": "g/dL",
        "system": "http://unitsofmeasure.org",
        "unit": "g/dl",
        "value": 7.2
      }
    }
    
  3. Le praticien Jeffrey Brown (identifié par Practitioner/12942879-f89f-41ae-aa80-0b911b649833) utilisant une application inconnue App/unknown lit la mesure d'hémoglobine du patient (dans cet exemple, Observation/7473784b-46a8-470c-b9a6-fe38a01025aa).
  4. curl -X GET \
      -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
      -H "X-Consent-Scope: actor/Practitioner/12942879-f89f-41ae-aa80-0b911b649833 env/App/unknown" \
      "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation/7473784b-46a8-470c-b9a6-fe38a01025aa"
    

    Étant donné que l'accès aux limites du demandeur ("App/unknown") n'est pas autorisé par le consentement du patient, la requête est refusée.

    {
      "issue": [
        {
          "code": "security",
          "details": {
            "text": "permission_denied"
          },
          "diagnostics": "Consent access denied or the resource being accessed does not exist",
          "severity": "error"
        }
      ],
      "resourceType": "OperationOutcome"
    }
    
  5. Le praticien Jeffrey Brown (identifié par Practitioner/12942879-f89f-41ae-aa80-0b911b649833) effectuant des recherches biomédicales à l'aide de l'application App/golden lit la date de naissance de Darcy (dans cet exemple, Patient/3c6aa096-c054-4c22-b2b4-1e4a4d203de2).
  6. curl -X GET \
      -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
      -H "X-Consent-Scope: actor/Practitioner/12942879-f89f-41ae-aa80-0b911b649833 purp/v3/BIORCH env/App/golden" \
      "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Patient/3c6aa096-c054-4c22-b2b4-1e4a4d203de2"
    

    Comme le demandeur a obtenu son consentement, la réponse correspond au contenu de la ressource Patient.

    {
      "active": true,
      "birthDate": "1990-01-01",
      "gender": "female",
      "id": "3c6aa096-c054-4c22-b2b4-1e4a4d203de2",
      "meta": {
        "lastUpdated": "2022-09-01T17:31:40.423469+00:00",
        "versionId": "VERSION_ID",
        "tag": [{
          "system": "http://terminology.hl7.org/CodeSystem/common-tags",
          "code": "employee"
        }]
      },
      "name": [
        {
          "family": "Smith",
          "given": [
            "Darcy"
          ],
          "use": "official"
        }
      ],
      "resourceType": "Patient"
    }
    
  7. Le praticien Jeffrey Brown (identifié par Practitioner/12942879-f89f-41ae-aa80-0b911b649833) demande un accès d'urgence non autorisé au dossier d'un patient à l'aide du protocole "bris de glace". (dans cet exemple, Observation/7473784b-46a8-470c-b9a6-fe38a01025aa).
  8. curl -X GET \
      -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
      -H "X-Consent-Scope: btg actor/Practitioner/12942879-f89f-41ae-aa80-0b911b649833" \
      "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation/7473784b-46a8-470c-b9a6-fe38a01025aa"
    

    Comme la méthode d'autorisation du consentement est btg, le serveur ignore les vérifications du consentement. La réponse correspond au contenu de la ressource Observation.

    {
      "code": {
        "coding": [
          {
            "code": "718-7",
            "display": "Hemoglobin [Mass/volume] in Blood",
            "system": "http://loinc.org"
          }
        ]
      },
      "effectivePeriod": {
        "start": "2021-12-10T05:30:10+01:00"
      },
      "id": "7473784b-46a8-470c-b9a6-fe38a01025aa",
      "issued": "2021-12-10T13:30:10+01:00",
      "meta": {
        "lastUpdated": "2022-09-01T17:31:40.423469+00:00",
        "source": "http://example.com/HappyHospital",
        "versionId": "VERSION_ID"
      },
      "resourceType": "Observation",
      "status": "final",
      "subject": {
        "reference": "Patient/3c6aa096-c054-4c22-b2b4-1e4a4d203de2"
      },
      "valueQuantity": {
        "code": "g/dL",
        "system": "http://unitsofmeasure.org",
        "unit": "g/dl",
        "value": 7.2
      }
    }
    

Les sections suivantes décrivent les méthodes d'application du consentement compatibles avec l'API Cloud Healthcare et comment l'accès aux ressources est appliqué lorsque vous effectuez une requête tenant compte du consentement.

Lorsque vous effectuez une requête, votre serveur d'autorisation est chargé de générer des jetons d'accès avec le champ d'application de consentement approprié.

Définir l'en-tête HTTP

Les champs d'application du consentement sont transmis à l'API Cloud Healthcare à l'aide de l'en-tête HTTP X-Consent-Scope. L'API Cloud Healthcare utilise cet en-tête pour appliquer un contrôle d'accès basé sur le consentement pour les données des magasins FHIR.

Une requête FHIR accepte un nombre limité de champs d'application d'entrée d'autorisations. Vous pouvez inclure jusqu'à trois entrées de actor, une de purp et une de env dans une requête FHIR donnée.

Pour les champs d'application spéciaux, une requête FHIR peut être compatible avec btg ou bypass.

Définir des en-têtes HTTP pour les applications de confiance

Cette section n'est requise que si vous utilisez un serveur d'autorisation contrôlé par le client. Dans ce cas, vous devez également utiliser un proxy SMART ou un proxy similaire.

Certaines applications de confiance peuvent appeler directement l'API Cloud Healthcare avec les champs d'application du consentement figurant dans l'en-tête HTTP spécifié. Cela permet l'application directe du consentement sans avoir besoin d'un proxy SMART ou d'un autre proxy pour effectuer la conversion entre les serveurs d'autorisation externes et Google Cloud.

Par exemple, votre application peut être enregistrée pour un sous-ensemble de champs d'application, tel que le champ d'application environment d'une application, ou l'application peut présenter un widget de sélection pour définir certaines entrées de champ d'application, telles que le purpose de l'accesseur.

Un utilisateur ou une application de confiance peuvent également utiliser les entrées de champ d'application btg ou bypass, qui font l'objet d'un examen post-audit.

L'API Cloud Healthcare est compatible avec l'application du consentement FHIR en fonction des champs d'application du consentement saisi. Les administrateurs de magasins FHIR sont chargés de créer et de configurer un serveur d'autorisation en dehors de l'API Cloud Healthcare qui accorde les champs d'application du consentement.

Exemple de jeton d'accès

L'exemple suivant montre un jeton d'accès encodé en base64 :

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzM4NCJ9.eyJpc3MiOiJjb25zZW50LnRva2VuLm9yZyIsImlhdCI6MTYxMjg4NDA4NSwiZXhwIjoxNjQ0NDIwMDg1LCJhdWQiOiJ3d3cuZXhhbXBsZS5jb20iLCJzdWIiOiJkb2N0b3IuZ2FicmllbGFAZXhhbXBsZS5jb20iLCJzY29wZSI6Im9pZGMgYWN0b3IvUHJhY3RpdGlvbmVyLzEyMyBhY3Rvci9Hcm91cC85OTkgcHVycC92My9UUkVBVCBlbnYvQXBwL2FiYyJ9.fC7ljkVUUx8fwUOrJuONcrqA-WKC-k_Bclzlgds0Cq6H_gEe3nUjPlSOCTQsIdYB

Après avoir décodé le jeton d'accès, vous pouvez voir qu'il contient la charge utile suivante :

{
  "iss": "consent.token.org",
  "iat": 1612884085,
  "exp": 1644420085,
  "aud": "www.example.com",
  "sub": "doctor.gabriela@example.com",
  "scope": "oidc actor/Practitioner/123 actor/Group/999 purp/v3/TREAT env/App/abc"
}

Configurer SMARTProxy

SMARTProxy est un proxy Open Source de Google qui fournit les fonctionnalités suivantes :

  • Permet au serveur FHIR de l'API Cloud Healthcare d'accepter et de valider les jetons d'accès basés sur le consentement.

  • Permet à l'implémentation FHIR dans l'API Cloud Healthcare d'inclure des jetons d'accès consentis dans le cadre du modèle d'autorisation et de gestion de l'API Cloud Healthcare.

  • Compatible également avec les fonctionnalités de jeton pour l'assistance SMART sur FHIR.

Lorsque vous effectuez une requête pour récupérer des données de l'API Cloud Healthcare via SMARTProxy, les événements suivants se produisent:

  1. SMARTProxy accepte une requête d'un client contenant un jeton compatible avec le consentement.

  2. SMARTProxy valide le jeton compatible avec le consentement via un serveur d'autorisation JWT que vous possédez.

  3. SMARTProxy lit les champs d'application à partir du jeton compatible avec le consentement et les transmet à l'API Cloud Healthcare via l'en-tête HTTP.

  4. L'API Cloud Healthcare reçoit les en-têtes et les valide pour appliquer les instructions d'autorisation sur la requête. L'API Cloud Healthcare renvoie ensuite une réponse via le SMARTProxy au client.

Configurer un compte de service Google Cloud

Un proxy ne peut posséder qu'un seul compte de service Google Cloud. Si plusieurs clients utilisent le même proxy, ils utilisent le même compte de service. Soyez prudent lorsque vous partagez un compte de service avec plusieurs clients pour les raisons suivantes :

Par exemple, si vous appelez l'API Cloud Healthcare directement à l'aide de votre compte Google pour l'authentification, Cloud Audit Logging enregistre votre adresse e-mail comme adresse e-mail principale. Lorsque vous utilisez un proxy pour appeler l'API Cloud Healthcare, le proxy utilise son propre compte de service, l'adresse e-mail principale est celle du compte de service et le compte d'origine n'est pas défini.

Journaux d'audit

Les journaux d'audit sont générés en cas de demande d'accès ou lorsque l'application de l'accès aux ressources est modifiée.

Accéder aux journaux d'audit

Si les journaux d'audit sont activés sur le store FHIR, un champ de métadonnées consentMode est inclus dans les journaux d'audit disponibles dans Cloud Logging. consentMode peut avoir l'une des valeurs suivantes:

  • off: consentConfig.accessEnforced est défini sur false dans la configuration du store FHIR et n'autorise pas les requêtes basées sur le consentement.

  • emptyScope: consentConfig.accessEnforced est défini sur true pour le store FHIR, mais aucun en-tête de champ d'application du consentement n'a été inclus. Par conséquent, les consentements n’ont pas été appliqués.

  • enforced: consentConfig.accessEnforced est défini sur true pour le magasin FHIR et l'en-tête du champ d'application d'autorisation est présent. Par conséquent, les autorisations ont été évaluées et appliquées à la requête.

  • btg: btg a été fourni dans l'en-tête du champ d'application du consentement pour la requête FHIR. Par conséquent, les vérifications du consentement ont été ignorées. Cette demande est destinée à être utilisée en cas d'urgence et n'est sujette qu'à un examen post-audit.

  • bypass: seul bypass a été fourni dans l'en-tête du champ d'application du consentement pour la requête FHIR. Par conséquent, les vérifications du consentement ont été ignorées. Cette requête est destinée à être utilisée par un workflow approuvé (par exemple, un administrateur ou une application de confiance plutôt que des utilisateurs finaux), de sorte que ce journal d'audit est différent du btg, qui est utilisé pour les vérifications de gouvernance des données.

Vous pouvez éventuellement définir access_determination_log_config sur VERBOSE pour enregistrer plus d'informations sur les motifs d'acceptation ou de refus d'une requête.

Journaux d'audit des modifications liées à l'application des règles d'accès

Lorsque la ressource de base d'un compartiment change (par exemple, en cas de suppression de la balise employee d'un patient): le contrôle des accès à la ressource modifiée et à son compartiment peut changer en raison de la règle en cascade définie par l'administrateur. Il déclenche la réindexation sur toutes les ressources de son compartiment. La progression du réindexation pour chaque mise à jour des ressources de base du compartiment peut être suivie dans Cloud Logging avec le filtre jsonPayload.@type="type.googleapis.com/google.cloud.healthcare.logging.FhirConsentCascadeLogEntry".

Exemple de journal de progression de la réindexation en cascade

{
  "insertId": "tz2gtza8",
  "jsonPayload": {
    "@type": "type.googleapis.com/google.cloud.healthcare.logging.FhirConsentCascadeLogEntry",
    "state": "STATE_FINISHED",
    "affectedResources": "2",
    "lastUpdated": "YYYY-MM-DDTHH:MM:SS+ZZ:ZZ",
    "compartmentBaseResourceName": "projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Patient/PATIENT_RESOURCE_ID/_history/PATIENT_RESOURCE_VERSION"
  },
  "resource": {
    "type": "healthcare_fhir_store",
    "labels": {
      "location": "LOCATION",
      "dataset_id": "DATASET_ID",
      "fhir_store_id": "FHIR_STORE_ID",
      "project_id": "PROJECT_ID"
    }
  },
  "timestamp": "YYYY-MM-DDTHH:MM:SS+ZZ:ZZ",
  "severity": "INFO",
  "logName": "projects/PROJECT_ID/logs/healthcare.googleapis.com%2Fconsent_cascading_fhir",
  "receiveTimestamp": "YYYY-MM-DDTHH:MM:SS+ZZ:ZZ"
}

jsonPayload.state est l'état de l'opération de réindexation, jsonPayload.affectedResources est le nombre de ressources du compartiment réindexées et jsonPayload.lastUpdated est l'horodatage de la mise à jour des ressources du patient. Si l'opération vient de commencer, jsonPayload.state="STATE_STARTED" et jsonPayload.affectedResources ne sont pas présents.

Contraintes et limites

Cette section présente les contraintes et les limites de FHIR R4, mais les mêmes contraintes et limites s'appliquent à FHIR STU3.

Type Contraintes et limites
Ressource de consentement unique
  • Un seul élément Consent.provision est accepté. Les provisionnements multiples ou imbriqués ne le sont pas.
  • Au moins 1 Consent.provision.actor, au maximum 25:
    • Consent.provision.actor.role doit être http://terminology.hl7.org/CodeSystem/v3-RoleCode.
    • La valeur de Consent.provision.actor.code doit être GRANTEE ou HPOWATT.
  • Maximum Consent.provision.purpose:
    • Consent.provision.purpose.system doit être http://terminology.hl7.org/CodeSystem/v3-ActReason.
    • Consent.provision.purpose.code n'est pas vide et ne doit pas comporter plus de 13 caractères.
  • 1 environment maximum:
    • Consent.provision.extension.url doit être https://g.co/fhir/medicalrecords/Environment.
    • La longueur combinée du système et du code ne doit pas dépasser 15 caractères.
  • Si vous filtrez par type de ressource, Consent.provision.class.system doit être http://hl7.org/fhir/resource-types.
  • Si vous effectuez un filtrage par source de données, la valeur de Consent.provision.extension.url doit être https://g.co/fhir/medicalrecords/DataSource.
  • Si vous filtrez par tag de données, la valeur de Consent.provision.extension.url doit être https://g.co/fhir/medicalrecords/DataTag.
    • Un tag de données peut être une extension complexe, imbriquée au niveau d'un niveau supérieur, qui permet de décrire une règle qui fait correspondre des ressources à toutes les balises spécifiées (interprétées de manière conjonctive).
    • Cinq tags imbriqués au maximum sont acceptés.
  • 100 valeurs maximum pour tous les attributs répétés, sauf indication contraire sur cette ligne.
Modèle d'application
  • Chaque patient peut disposer d'un maximum de 200 ressources de consentement active appliquées à la fois.
  • Chaque magasin peut avoir jusqu'à 200 règles d'administration active appliquées à la fois.
  • Un format compact spécial pour l'ensemble des Instructions d'autorisation sur toutes les autorisations actives pour un patient donné ne doit pas dépasser un seuil défini de taille. En général, la capacité est suffisante pour encoder des milliers d'instructions d'autorisation, sauf si les chaînes de ressources très longues sont particulièrement abondantes. Exemple :
    • Des centaines d'autorisations sur la source de données unique et les balises de données, chacune très longue consomme beaucoup d'espace.
    • Un seul patient avec 3 000 entrées d'identifiant de ressource Consent.provision.data.reference unique dans plusieurs consentements actifs spécifiant chacun un Consent.provision.actor unique utilise l'espace de manière plus agressive que les dispositions qui ne spécifient pas de contrainte de référence de données ou qui contiennent un grand nombre de chaînes de référence d'acteur identiques.
  • Chaque ressource peut comporter jusqu'à 1 000 instructions de consentement provenant de toutes les autorisations qui s'appliquent à elle.
X-Consent-Scope
  • Entre une et trois entrées actor.
  • Maximum une entrée purp:
    • Chaque entrée purp doit être au format system/code (v3 est le système enregistré pour http://terminology.hl7.org/CodeSystem/v3-ActReason).
    • La longueur du code doit être inférieure à 13.
  • Maximum une entrée env:
    • Chaque entrée env doit être au format system/code.
    • La longueur du système et du code combinés doit être inférieure à 15.
  • btg nécessite au moins une entrée actor.
  • bypass nécessite au moins une entrée actor et une entrée env.
Méthodes acceptées
Performances
  • ApplyConsents et ApplyAdminConsents évoluent de façon similaire ou supérieure à ImportResources.
  • Concernant les demandes tenant compte du consentement:
    • Notre modèle de consentement a été optimisé pour améliorer les performances des opérations CRUD, y compris la recherche à grande échelle pour de nombreuses ressources et pour de nombreux patients.
    • La lecture de ressources individuelles peut avoir un impact marginal sur la latence des requêtes, mais les performances de recherche varient en fonction de la requête de base et du nombre de niveaux d'autorisation, ce qui entraîne une augmentation des critères d'accès actifs lors d'une recherche.
    • Nous vous recommandons d'exécuter vos propres tests de performances sur différents paramètres de requête FHIR représentatifs afin de déterminer les caractéristiques de performance de vos cas d'utilisation en fonction des caractéristiques de vos données, telles que le nombre de ressources de recherche d'un type donné dans le magasin FHIR.
    • Notre solution allège l'ingestion et la mise à jour de toutes les ressources, y compris les ressources de consentement, de sorte que le débit lors de l'ingestion et d'autres formes de trafic en écriture puisse s'effectuer avec un impact minimal.

Bonnes pratiques

Les sections suivantes décrivent les bonnes pratiques liées au contrôle des accès FHIR.

Bonnes pratiques générales

  • N'import pas de ressources FHIR et appelez ApplyConsents ou ApplyAdminConsents en parallèle. Nous vous recommandons d'importer d'abord les ressources FHIR, puis d'appeler ApplyConsents ou ApplyAdminConsents. Toutefois, si les ressources à importer n'incluent aucune ressource Patient ou Consentement, le modèle d'application ne sera pas affecté et le traitement des autorisations ou des règles d'administration n'est pas nécessaire.

  • Ne créez pas de recherches personnalisées et appelez ApplyConsents en parallèle. Nous vous recommandons de le faire l'un après l'autre.

  • Si vos workflows nécessitent d'appeler plusieurs ApplyConsents sur des PatientScope disjoints, ils peuvent être appelés en parallèle.

  • ApplyAdminConsents peut s'exécuter en parallèle avec un nombre illimité de ApplyConsents, mais pas avec une autre ApplyAdminConsents.

  • Lors de la configuration du proxy, limitez le compte de service IAM avec des autorisations en lecture seule pour éviter d'écrire les données d'un patient dans les dossiers d'un autre.

  • N'utilisez pas le proxy de consentement lorsque vous créez ou mettez à jour des enregistrements.

  • Validez toutes les requêtes d'écriture pour éviter toute modification croisée de données patient.

  • Lorsque des autorisations en cascade sont appliquées, les ressources de base d'un compartiment doivent être importées en premier, suivies des ressources de compartiment restantes. Toutes les ressources de compartiment peuvent également être encapsulées dans un seul bundle et ingérées à l'aide de fhir.executeBundle.

Supprimer la ressource Patient

Lorsque vous supprimez une ressource Patient, si vous souhaitez également supprimer l'application des autorisations pour ce patient (en particulier lorsque FhirStore.disableReferentialIntegrity est défini sur "true"), nous vous recommandons de suivre l'ordre des étapes suivantes :

  1. Supprimez toutes les ressources d'autorisation appartenant à la ressource Patient.

  2. Appelez ApplyConsents avec le filtre PatientScope.

Pour configurer un magasin existant pour l'accès au consentement, procédez comme suit:

  1. Utiliser UpdateFhirStore pour définir le ConsentConfig avec l'application des autorisations version en tant queV1 et définir accessEnforced sur true.

    curl -X PATCH \
        -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
        -H "Content-Type: application/json" \
        --data "{
          'consentConfig': {
            'version': 'V1',
            'accessEnforced': true
          }
        }" "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID?update_mask=consentConfig"
    
  2. Traiter les autorisations des patients ou les règles d'administration

    1. ApplyConsents pour les autorisations des patients
    curl -X POST \
        -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
        -H "Content-Type: application/json" \
        --data "{'validateOnly': false}" \
        "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID:applyConsents"
    
    1. ApplyAdminConsents pour les règles d'administration et les règles en cascade pour les administrateurs.
    curl -X POST \
        -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
        -H "Content-Type: application/json" \
        --data "{
          'newConsentsList': {
              'names': [
              'projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Consent/RESOURCE_ID_1/_history/VERSION_ID_1',
              ...
              'projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Consent/RESOURCE_ID_N/_history/VERSION_ID_N'
              ]
          },
          'validateOnly': false
        }" \
        "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID:applyAdminConsents"
    

Fréquence d'exécution de ApplyConsents ou ApplyAdminConsents

  • Lorsque le champ ConsentConfig n'est plus défini, le champ ConsentConfig n'est pas défini lors de la création d'un magasin FHIR ni lors de l'effacement du champ ConsentConfig. Une fois que le champ ConsentConfig n'est plus défini, vous devez répéter la configuration du magasin pour l'accès aux autorisations avant d'effectuer des requêtes compatibles avec les autorisations pour éviter d'évaluer des règles d'application des autorisations obsolètes.

  • Le modèle d'application change: lorsqu'une ressource d'autorisation est créée, mise à jour ou supprimée, le modèle d'application change. Dans ce cas, vous devez appeler ApplyConsents ou ApplyAdminConsents pour que ces modifications soient prises en compte.

    • Si vous souhaitez effectuer un suivi des patients dont les autorisations ont été modifiées, nous vous recommandons d'utiliser le filtre PatientScope pour éviter de relancer le traitement sur l'ensemble du magasin. Ce filtre est utile pour actualiser immédiatement l'application d'un petit ensemble de patients.

    • Vous pouvez également exécuter ApplyConsents régulièrement à l'aide du filtre TimeRange. Ce filtre est utile lorsqu'il n'est pas nécessaire d'effectuer une actualisation immédiate. Par exemple, la requête suivante actualise l'application pour les changements de consentement entre UTC 0AM 2022-09-20 et UTC 0AM 2022-09-21.

      curl -X POST \
        -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
        -H "Content-Type: application/json" \
        --data "{
           'validateOnly': false,
           'timeRange': {
             'start': '2022-09-20T00:00:00Z',
             'end': '2022-09-21T00:00:00Z',
           }
          }" \
        "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID:applyConsents"
      

Étapes suivantes