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

Cette page explique comment utiliser Ressources sur le 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 l'application du consentement, procédez comme suit:

  1. Créez un store FHIR si vous n'en avez pas déjà un.

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

    • version: indique pour quelle version d'application du consentement est utilisée le store FHIR. Cette valeur ne peut être définie qu'une seule fois CreateFhirStore ou UpdateFhirStore. Vous devez ensuite appeler ApplyConsents ou ApplyAdminConsents pour changer de version.

    • access_enforced: si ce champ est défini sur true, lors de l'accès aux ressources FHIR, Les en-têtes de consentement fournis seront vérifiés par rapport aux directives de consentement données par les consommateurs.

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

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 avez déjà un magasin, utilisez UpdateFhirStore pour définir le ConsentConfig avec la mesure d'application du consentement version en tant que V1 et définissez 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 par la ressource Consent. Les champs "resource" leurs objectifs et leur utilisation sont décrits dans la documentation sur le modèle de données.

Voici un exemple de toutes les ressources pouvant être créées pour cet exemple spécifique.

Créer des ressources FHIR

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

  • Une ressource de type Professionnel portant le nom Jeffrey Brown
  • Une ressource de type Patient portant le nom Darcy Smith
  • Une ressource d'observation montrant la mesure de l'hémoglobine de Darcy (LOINC718-7) collectée par le Happy Hospital
  • Ressource d'observation montrant la mesure du glucose pour Darcy (LOINC15074-8).
  • Autorisation de Darcy pour permettre à Jeffrey Brown d'utiliser sa demande App/123 pour accéder à ses données collectées par Happy Hospital
  • Une autorisation de Darcy autorisant Jeffrey Brown à accéder à l'une de ses données pour traitement d'urgence (ETREAT)
  • Autorisation de Happy Hospital permettant à Jeffrey Brown d'accéder à toutes les données lorsqu'ils effectuent des 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"
}

Voici d'autres exemples de R4 Ressource de consentement qui montre comment les stratégies 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 de patient dans laquelle un patient f001 accorde l'autorisation à un professionnel f002 avec dans le but d'assurer un traitement régulier représenté par TREAT. Le professionnel provient du iso3166-1/CA de géolocalisation. Ce La ressource de consentement permet au praticien d'accéder aux données du patient si la Les données répondent à 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.
  • Elle remplit au moins l'une des conditions suivantes sur la balise (vous pouvez ajouter des tags aux ressources en définissant les champs system et code de Meta.tag):
    • Contient la balise (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 comporte au moins l'un des libellés de sécurité suivants
    • system = http://terminology.hl7.org/CodeSystem/v3-Confidentiality et code est l'une des valeurs suivantes : R, N, M, L, U.
    • system = http://terminology.hl7.org/CodeSystem/v3-ActCode et code = PSY.

Exemple de directive pour les règles 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 montre qu'une ressource de consentement d'une règle d'administration accorde une autorisation à un professionnel f002 afin de lui proposer traitement représenté par TREAT. Le professionnel provient du iso3166-1/CA de géolocalisation. Cette ressource Consent permet au d'un professionnel de santé à accéder aux données du patient si celles-ci répondent à toutes les 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.
  • Elle remplit au moins l'une des conditions suivantes sur la balise:
    • Contient la balise (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 comporte au moins l'un des libellés de sécurité suivants
    • system = http://terminology.hl7.org/CodeSystem/v3-Confidentiality et code est l'une des valeurs suivantes : R, N, M, L, U.
    • system = http://terminology.hl7.org/CodeSystem/v3-ActCode et code = PSY.

Exemple de règle d'administration 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 d'une règle d'administration en cascade autorisation à un professionnel f002 dans le but de fournir traitement standard représenté par TREAT. Le professionnel vient de iso3166-1/CA de géolocalisation. Cette ressource Consent permet au pour accéder aux données du compartiment des patients employee Tous les critères applicables aux ressources ne s'applique qu'aux ressources de base du compartiment, c'est-à-dire à la ressource Patient, car elle contrôle les ressources à partir desquelles effectuer la cascade.

Appliquez les autorisations des patients ou les règles d'administration

Appliquez l'autorisation 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 [Méthode de l'opération "get"](/healthcare-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 avec l'état 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 bien traité deux autorisations et mis à jour l’accès consensuel à 5 ressources (1 patient, 2 consentements, 2 Observations).

Appliquer 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 [Méthode de l'opération "get"](/healthcare-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 avec l'état 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 bien traité 1 règle d'administration et mis à jour l'accès consensuel à 7 ressources (1 praticien, 1 patient, 2 observations, 2 autorisations des patients et 1 règle d'administration).

L'application des autorisations stockées dans un store FHIR n'entrera pas en vigueur jusqu'au ApplyConsents (pour l'autorisation du patient) ou au ApplyAdminConsents (pour l'administrateur) et stratégies d'administration en cascade) est appelée et s'exécute correctement. Si vous ajoutez, modifiez ou supprimez des autorisations après avoir exécuté ApplyConsents ou ApplyAdminConsents, vous devez l'exécuter à nouveau pour que ces autorisations soient incluses dans le modèle d'application.

Les ressources FHIR sont indexées de manière asynchrone, ce qui peut prendre un peu de temps entre le moment où ApplyConsents ou ApplyAdminConsents se termine et le moment où le modèle d'application des règles se reflète dans les résultats de recherche. Ce délai n'est pour les requêtes de recherche.

Si vous configurez l'application du consentement pour la première fois sur FHIR de stockage, attendez que l'erreur ApplyConsents ou ApplyAdminConsents de longue durée avant d'effectuer des requêtes basées sur le consentement.

Pour appeler ApplyConsents sur un sous-ensemble de patients, vous pouvez utiliser le code suivant : filtres:

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

  • TimeRange: d'exécuter ApplyConsent sur une liste d'ID de ressources de patients dont le consentement les ressources sont mises à jour au cours d'une certaine période

Pour appeler ApplyAdminConsents, vous devez fournir la liste complète de tous. à appliquer (et non sous forme de liste incrémentielle). Par conséquent, un champ vide annule l'application forcée de toutes les règles d'administration du magasin. Chaque stratégie doit être un nom de version de ressource si le Magasin FHIR est la gestion des versions, et un nom de ressource dans le cas contraire.

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

ProgressCounter ApplyConsentsResponse ou ApplyAdminConsentsResponse Description
success consentApplySuccess Nombre de ressources de consentement que l'opération a bien traitées.
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 de l'erreur.
secondarySuccess affectedResources Lorsque validateOnly est défini sur false, cela représente le nombre de ressources FHIR qui ont été réindexées avec succès en raison de l'effet de la modification du consentement.
secondaryFailure failedResources Lorsque validateOnly est défini sur false, cela représente le nombre de ressources FHIR susceptibles d'avoir une modification du consentement, mais dont la réindexation a échoué. Cela peut affecter la recherche avec contexte de consentement, mais pas d'autres méthodes. Pour afficher les détails de l'erreur, vous pouvez afficher les journaux d'erreurs dans Cloud Logging.

Lorsque les ressources de consentement FHIR sont traitées, vous pouvez utiliser les API suivantes pour : vérifier l'état d'application d'un consentement unique ou de tous les consentements d'une patient:

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

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

  • OFF: représente l'état d'application par défaut d'une nouvelle ressource Consent. pour 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 Consent pouvant être conforme à FHIR mais n'est pas applicable. Cela est dû à une implémentation limitée de l'application du consentement FHIR avec le niveau actuel de compatibilité des fonctionnalités.

  • ENFORCEMENT_LIMIT_EXCEEDED: l'état lorsque la ressource de consentement FHIR et le niveau de compatibilité de la ressource sont dépourvus d'erreurs. Toutefois, une seule 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 prend en charge les recherches de ressources FHIR dans un Store FHIR avec actor, purpose et environment comme paramètres de requête. La ne contient que les ressources autorisées.

  1. Jeffrey Brown, praticien (identifié par Practitioner/12942879-f89f-41ae-aa80-0b911b649833) à l'aide d'une application de confiance 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. Jeffrey Brown, praticien (identifié par Practitioner/12942879-f89f-41ae-aa80-0b911b649833) à l'aide de 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 enchaînée. Comme 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. Jeffrey Brown, praticien (identifié par Practitioner/12942879-f89f-41ae-aa80-0b911b649833) l'application App/123 recherche toutes les observations depuis 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. Jeffrey Brown, praticien (identifié par Practitioner/12942879-f89f-41ae-aa80-0b911b649833) recherche Observations avec status=final pour deux finalités : 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 praticien Jeffrey Brown doit supprimer un à partir de "X-Consent-Scope" dans la requête.

  9. Un administrateur informatique d'un hôpital utilise bypass pour rechercher Des praticiens à 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. Toi doit 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 une Store FHIR avec actor, purpose et environment comme paramètres de requête. La ne contient que les ressources autorisées.

  1. Jeffrey Brown, praticien (identifié par Practitioner/12942879-f89f-41ae-aa80-0b911b649833) L'utilisation de l'application App/123 lit la mesure de l'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 reçu son consentement, la réponse correspond au contenu de l'e-mail Ressource d'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. Jeffrey Brown, praticien (identifié par Practitioner/12942879-f89f-41ae-aa80-0b911b649833) à l'aide de l'application inconnue App/unknown lit la mesure de l'hémoglobine du patient (dans ce (par 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"
    

    Parce que l'accès aux limites du demandeur ("Application/inconnu") n'est pas autorisée par le consentement du patient, la demande 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. Jeffrey Brown, praticien (identifié par Practitioner/12942879-f89f-41ae-aa80-0b911b649833) des recherches biomédicales à l'aide de l'application App/golden lit la date de naissance de Darcy (dans ce (par 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 reçu son consentement, la réponse correspond au contenu de l'e-mail 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. Jeffrey Brown, praticien (identifié par Practitioner/12942879-f89f-41ae-aa80-0b911b649833) demande un accès d'urgence non autorisé au dossier d'un patient à l'aide de la méthode "bris de glace" standard. (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 le consentement vérifications. La réponse est le 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 acceptées dans les l'API Cloud Healthcare et la manière dont l'accès aux ressources est appliqué lorsque vous effectuez une demande d'autorisation préalable.

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

Définir l'en-tête HTTP

Les champs d'application de consentement sont transmis à l'API Cloud Healthcare à l'aide du 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 prendre en charge l'un des champs btg, ou bypass

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

Cette section n'est obligatoire que si vous utilisez un système serveur d'autorisation. Dans ce cas, vous devez également utiliser un SMARTproxy ou un proxy similaire.

Certaines applications approuvées peuvent appeler directement l'API Cloud Healthcare avec les champs d'application du consentement dans l'en-tête HTTP spécifié. Ce permet d’appliquer directement le consentement sans avoir besoin d’un SMARTproxy ni d’un autre pour convertir des serveurs d'autorisation externes vers 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 de confiance ou une application de confiance peut également utiliser les entrées de champ d'application btg ou bypass, qui sont soumises aux d'examens post-audit.

L'API Cloud Healthcare offre une prise en charge intégrée du consentement FHIR. en fonction des champs d'application du consentement d'entrée. Les administrateurs de store FHIR sont responsable de la création et de la configuration d'un serveur d'autorisation en dehors API Cloud Healthcare qui accorde des 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 des jetons d'accès avec consentement.

  • Permet à l'implémentation FHIR dans l'API Cloud Healthcare d'inclure les éléments suivants : des jetons d'accès avec consentement dans le cadre de la gestion de l'API Cloud Healthcare et modèle d'autorisation.

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

Lorsque vous envoyez une requête pour récupérer des données de l'API Cloud Healthcare avec SMARTProxy, voici ce qui se produit:

  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'accès des ressources les modifications de l'application des accès.

Accéder aux journaux d'audit

Si les journaux d'audit sont activé sur le store FHIR, un champ de métadonnées consentMode est inclus dans l'audit de journaux disponibles dans Cloud Logging. L'élément consentMode peut être associé à l'un des éléments suivants : :

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

  • emptyScope: consentConfig.accessEnforced est défini sur le store FHIR. true, 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ées.

  • 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 consentements étaient évaluée et appliquée à la demande.

  • btg: btg est indiqué dans l'en-tête du champ d'application du consentement pour la requête FHIR. En tant que résultat, la vérification du consentement a été ignorée. Cette requête est destinée en cas d'urgence et ne sont soumises qu'à un examen post-audit.

  • bypass: seul bypass est indiqué dans le champ d'application du consentement pour la requête FHIR. en-tête. Par conséquent, les vérifications du consentement ont été ignorées. Cette demande est destinée à être utilisée par un flux de travail de confiance (tel qu'un administrateur ou application au lieu des utilisateurs finaux), ce qui différencie ce journal d'audit btg, qui est utilisé pour les contrôles de gouvernance des données.

Vous pouvez éventuellement définir access_determination_log_config sur VERBOSE pour enregistrer plus d'informations sur les raisons pour lesquelles une demande est acceptée ou refusée.

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

Lorsque la ressource de la base du compartiment change (par exemple, en supprimant la mémoire d'un patient Tag employee): contrôle des accès sur la ressource modifiée et son compartiment. peut changer en raison des règles d'administration en cascade. Cela déclenchera la réindexation ses ressources compartimentées. Progression de la réindexation pour chaque base de compartiment la mise à jour des ressources 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 correspond à l'état de l'opération de réindexation, jsonPayload.affectedResources au nombre de ressources de compartiment réindexées et jsonPayload.lastUpdated correspond au code temporel de la mise à jour des ressources du patient. Si l'opération vient de commencer, jsonPayload.state="STATE_STARTED" et jsonPayload.affectedResources ne seront pas présents.

Contraintes et limites

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

Type Contraintes et limites
Ressource de consentement unique
  • Un seul Consent.provision est accepté. Les dispositions multiples ou imbriquées ne sont pas acceptées.
  • 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 dépasser 13 caractères.
  • 1 environment au maximum:
    • Consent.provision.extension.url doit être https://g.co/fhir/medicalrecords/Environment.
    • La longueur du système et du code combinés doit être inférieure à 15 caractères.
  • Si vous filtrez par type de ressource, Consent.provision.class.system doit être http://hl7.org/fhir/resource-types.
  • Si vous filtrez par source de données, Consent.provision.extension.url doit être https://g.co/fhir/medicalrecords/DataSource.
  • Si vous filtrez par tag de données, Consent.provision.extension.url doit être https://g.co/fhir/medicalrecords/DataTag.
    • Un tag de données peut être une extension complexe, imbriquée jusqu'à un niveau, permettant de décrire une règle qui associe des ressources à toutes les balises spécifiées (interprétées de manière conjointe).
    • Vous ne pouvez pas utiliser plus de cinq balises imbriquées.
  • 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 en même temps.
  • Chaque magasin peut appliquer jusqu'à 200 règles d'administration active à 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 de consentements sur une source de données et des balises de données uniques, chacun d'entre eux très longtemps occupe beaucoup d'espace.
    • Un patient unique avec 3 000 entrées d'identifiant de ressource Consent.provision.data.reference uniques sur plusieurs autorisations actives spécifiant chacune un Consent.provision.actor unique utilise l'espace de manière plus agressive que les dispositions qui ne spécifient aucune contrainte de référence des données ou qui contiennent de nombreuses chaînes de référence d'acteur identiques.
  • Chaque ressource peut comporter jusqu'à 1 000 instructions de consentement pour l'ensemble des autorisations applicables.
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
Performance
  • Le scaling de ApplyConsents et ApplyAdminConsents est semblable ou supérieur à celui de ImportResources.
  • Concernant les demandes basées sur le consentement:
    • Notre modèle de consentement a été optimisé pour l'application des performances des opérations CRUD, y compris la recherche à grande échelle dans de nombreuses ressources et auprès 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 permet de continuer à ingérer et à mettre à jour toutes les ressources, y compris les ressources de consentement. Elle reste légère afin que le débit lors de l'ingestion et des autres formes de trafic en écriture puisse avoir un impact minimal.

Bonnes pratiques

Les sections suivantes décrivent les meilleures pratiques lors de l'utilisation du contrôle des accès FHIR.

Bonnes pratiques générales

  • À ne pas faire import FHIR et appeler 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 n'incluent aucune ressource Patient ou Consentement, le fichier modèle d'application ne sera pas affecté et Traitement des autorisations ou règles d'administration n'est pas nécessaire.

  • À ne pas faire créer des 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 instances disjointes PatientScope, elles peuvent être appelées en parallèle.

  • ApplyAdminConsents peut s'exécuter en parallèle avec n'importe quel nombre d'ApplyConsents, mais pas avec un autre ApplyAdminConsents.

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

  • 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 les consentements en cascade sont appliqués, les ressources de base par compartiment doivent être importé suivie des autres ressources du compartiment. Vous pouvez également peuvent être encapsulées dans un seul bundle et ingérées avec 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 l'autorisation 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 d'administration en cascade.
    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'une petite ensemble de patients.

    • Vous pouvez également exécuter ApplyConsents régulièrement à l'aide de TimeRange. filtre. Ce filtre est utile lorsqu'il n'est pas nécessaire d'actualiser immédiatement la page. Par exemple, la requête suivante actualise l'application des modifications du 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"
      

Étape suivante