Controla el acceso a los recursos de FHIR en la API de Cloud Healthcare

En esta página, se describe cómo usar los recursos de consentimiento de FHIR para determinar el acceso a los datos de los almacenes de FHIR en la API de Cloud Healthcare.

Para configurar un almacén de FHIR con aplicación de consentimiento, completa los siguientes pasos:

  1. Crea un almacén de FHIR si aún no tienes uno.

  2. Establece los siguientes parámetros ConsentConfig del almacén de FHIR para habilitar la aplicación de consentimientos:

    • version: Especifica qué versión de la aplicación de consentimiento se usa para el almacén de FHIR. Este valor solo se puede establecer una vez mediante CreateFhirStore o UpdateFhirStore. Una vez configurada, debes llamar a ApplyConsents o a ApplyAdminConsents para cambiar la versión.

    • access_enforced: Si se establece como true, cuando se accede a los recursos de FHIR, los encabezados de consentimiento proporcionados se verificarán con las directivas de consentimiento que proporcionan los consumidores.

    • consent_header_handling: Si se establece en PERMIT_EMPTY_SCOPE (predeterminado), el servidor permite solicitudes sin encabezado X-Consent-Scope (o vacío). Si se establece en REQUIRED_ON_READ y access_enforced = true, el servidor rechaza todas las solicitudes sin encabezado X-Consent-Scope (o vacío).

Configura un nuevo almacén de FHIR con 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"

Deberías recibir una respuesta JSON similar a la que se muestra a continuación:

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

Si ya tienes una tienda existente, usa UpdateFhirStore para configurar lo siguiente:ConsentConfig con la aplicación de consentimientoversion como V1 y establece accessEnforced a 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"

Las políticas se representan a través del recurso de consentimiento. El propósito y el uso de los campos de recursos se describen en la documentación del modelo de datos.

Este es un ejemplo de todos los recursos que se pueden crear para este ejemplo en particular.

Crea recursos de FHIR

En el siguiente ejemplo, se muestra cómo ejecutar un [paquete de FHIR](/healthcare-api/docs/how-tos/fhir-bundles) para propagar los siguientes recursos:

  • Un recurso de un profesional con el nombre José Borrero
  • Un recurso de un paciente con el nombre Diana Sánchez
  • Un recurso de observación que muestra la medición de hemoglobina de Diana (LOINC718-7) que recopiló el Hospital Happy
  • Un recurso de observación que muestra la medición de glucosa de Darcy (LOINC15074-8).
  • Un consentimiento de Darcy para permitir que Jeffrey Brown use la aplicación App/123 a fin de acceder a los datos recopilados por el hospital Happy
  • Un consentimiento de Diana para permitir que José Borrero acceda a cualquiera de sus datos para un tratamiento de emergencia (ETREAT)
  • Un consentimiento del Hospital Feliz para permitir que José Borrero acceda a todos los datos cuando realice investigaciones biomédicas (BIORCH) con la aplicación 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"

Deberías recibir una respuesta JSON similar a la que se muestra a continuación:

{
  "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"
}

A continuación, se muestran más ejemplos de recurso de consentimiento de R4 que demuestran cómo se pueden representar las políticas complejas.

{
  "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"
      }
    ]
  }
}

En el ejemplo anterior, se representa un recurso de consentimiento del paciente en el que un f001 de paciente otorga permiso a un profesional f002 con el fin de proporcionar un tratamiento regular representado por TREAT. El profesional proviene de la ubicación geográfica iso3166-1/CA. Este recurso de consentimiento permite que el profesional acceda a los datos del paciente si cumplen con todas las condiciones siguientes.

  • Es un tipo Encounter con el ID Encounter/e001.
  • Proviene de la fuente http://somesystem.example.org/foo.
  • Satisface al menos una de las siguientes condiciones en la etiqueta (se pueden etiquetar recursos configurando los campos system y code de Meta.tag):
    • Tiene la etiqueta (system = http://terminology.hl7.org/CodeSystem/common-tags y code = actionable).
    • Tiene etiquetas (system = http://example.com/custom-tags y code = archived) y (system = http://example.com/custom-tags y code = insensitive).
  • Tiene al menos una de las siguientes etiquetas de seguridad
    • system = http://terminology.hl7.org/CodeSystem/v3-Confidentiality y code es uno de R, N, M, L o U.
    • system = http://terminology.hl7.org/CodeSystem/v3-ActCode y code = PSY.

Ejemplo de directiva de política de administrador

{
  "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"
      }
    ]
  }
}

En el ejemplo anterior, se representa un recurso de consentimiento de política de administrador que otorga permiso a un profesional f002 con el fin de proporcionar un tratamiento regular representado por TREAT. El profesional proviene de la ubicación geográfica iso3166-1/CA. Este recurso de consentimiento permite que el profesional acceda a los datos del paciente si cumplen con todas las condiciones siguientes:

  • Es un tipo Encounter con el ID Encounter/e001.
  • Proviene de la fuente http://somesystem.example.org/foo.
  • Satisface al menos una de las siguientes condiciones en la etiqueta:
    • Tiene la etiqueta (system = http://terminology.hl7.org/CodeSystem/common-tags y code = actionable).
    • Tiene etiquetas (system = http://example.com/custom-tags y code = archived) y (system = http://example.com/custom-tags y code = insensitive).
  • Tiene al menos una de las siguientes etiquetas de seguridad
    • system = http://terminology.hl7.org/CodeSystem/v3-Confidentiality y code es uno de R, N, M, L o U.
    • system = http://terminology.hl7.org/CodeSystem/v3-ActCode y code = PSY.

Ejemplo de directiva de política de encadenamiento del administrador

{
  "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"
        }
      }
    ]
  }
}

En el ejemplo anterior, se representa un recurso de consentimiento de política de cascada de administrador que otorga permiso a un profesional f002 con el fin de proporcionar un tratamiento regular representado por TREAT. El profesional proviene de la ubicación geográfica iso3166-1/CA. Este recurso de consentimiento permite que el profesional acceda a los datos del compartimento de los pacientes con la etiqueta employee. Todos los criterios de recursos solo se aplican a los recursos base del compartimiento, es decir, al recurso Patient, ya que controla de qué recursos se debe aplicar la habilitación en cascada.

Aplicar los consentimientos de los pacientes o las políticas del administrador

Aplica los consentimientos del paciente con 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"

Deberías recibir una respuesta JSON similar a la que se muestra a continuación:

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

La respuesta contiene un nombre de operación. Para realizar un seguimiento del estado de la operación, puedes usar el [método "get" de la operación](/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"

Cuando la operación finaliza, el servidor muestra una respuesta con el estado de la operación en formato 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"
  }
}

Esta respuesta indicó que el servidor procesó con éxito 2 consentimientos y actualizó el acceso consensual de 5 recursos (1 del paciente, 2 Consentimientos, 2 Observaciones).

Aplica la política de administrador con 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"

Deberías recibir una respuesta JSON similar a la que se muestra a continuación:

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

La respuesta contiene un nombre de operación. Para realizar un seguimiento del estado de la operación, puedes usar el [método "get" de la operación](/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"

Cuando la operación finaliza, el servidor muestra una respuesta con el estado de la operación en formato 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"
  }
}

Esta respuesta indicó que el servidor procesó con éxito 1 política de administrador y actualizó el acceso con consentimiento de 7 recursos (1 profesional, 1 paciente, 2 observaciones, 2 consentimientos del paciente y 1 política de administrador).

La aplicación forzosa de los consentimientos almacenados dentro de un almacén de FHIR no entrará en vigor hasta que se llame a ApplyConsents (para los consentimientos de los pacientes) o ApplyAdminConsents (para las políticas de administrador y las políticas de encadenamiento de administrador) y se complete de forma correcta. Si agregas, modificas o quitas consentimientos después de ejecutar ApplyConsents o ApplyAdminConsents, debes volver a ejecutarlo para que esos consentimientos se incluyan en el modelo de aplicación.

Los recursos de FHIR se indexan de forma asíncrona, por lo que puede haber una pequeña demora entre el momento en el que se completa ApplyConsents o ApplyAdminConsents y el momento en que el modelo de aplicación se refleja en los resultados de la búsqueda. Esta demora solo se espera para las solicitudes de búsqueda.

Si es la primera vez que configuras la aplicación de consentimiento en el almacén de FHIR, espera a que se complete la operación de larga duración de ApplyConsents o ApplyAdminConsents antes de realizar solicitudes de consentimiento.

Para llamar a ApplyConsents en un subconjunto de pacientes, puedes usar los siguientes filtros:

  • PatientScope: para ejecutar ApplyConsents en una lista de ID de pacientes con hasta 10,000 pacientes

  • TimeRange: para ejecutar ApplyConsent en una lista de ID de recursos de pacientes cuyos recursos de consentimiento se actualizan durante un período determinado

Para llamar a ApplyAdminConsents, debes proporcionar la lista completa de todas las políticas que deseas aplicar (no una lista incremental). Como resultado, una lista vacía anulará la aplicación forzosa de todas las políticas de administrador de la tienda. Cada política debe ser un nombre de versión de recurso si el almacén de FHIR controla las versiones, y un nombre de recurso en caso contrario.

Puedes usar operations.get para recuperar el ProgressCounter de la operación. Una vez completado, hay un ApplyConsentsResponse que se incluye en Operation.response. Los contadores de ProgressCounter y ApplyConsentsResponse o ApplyAdminConsentsResponse se describen en la siguiente tabla.

ProgressCounter ApplyConsentsResponse o ApplyAdminConsentsResponse Descripción
success consentApplySuccess Es la cantidad de recursos de consentimiento que la operación procesó correctamente.
failure consentApplyFailure Es la cantidad de recursos de consentimiento que no son compatibles o no son válidos. Para ello, puedes ver los registros de errores en Cloud Logging o, cuando validateOnly sea false, verificar el estado de aplicación del consentimiento con CheckConsentEnforcementStatus o CheckPatientConsentEnforcementStatus para recuperar los detalles del error.
secondarySuccess affectedResources Cuando validateOnly es false, representa la cantidad de recursos FHIR que se volvieron a indexar correctamente debido al efecto del cambio de consentimiento.
secondaryFailure failedResources Cuando validateOnly es false, representa la cantidad de recursos de FHIR que pueden tener un cambio de consentimiento, pero no pudieron reindexarse. Esto puede afectar la búsqueda con contexto de consentimiento, pero no de otros métodos. Para ver los detalles del error, puedes ver los registros de errores en Cloud Logging.

Cuando se procesan los recursos de consentimiento de FHIR, puedes usar las siguientes API para verificar el estado de la aplicación de un solo consentimiento o de todos los consentimientos de un paciente:

En el caso de la política de administrador, CheckConsentEnforcementStatus solo se puede usar para verificar el estado de aplicación de una sola política de administrador de consentimiento. Como alternativa, puedes usar fhirStores.get para ver todas las políticas de administrador activas aplicadas a la tienda.

La consent-enforcement-status puede tener cualquiera de los siguientes valores:

La API de Cloud Healthcare admite búsquedas de recursos de FHIR en un almacén de FHIR determinado con actor, purpose y environment como parámetros de consulta. La respuesta contiene solo los recursos que están en consentimiento.

  1. El profesional José Borrero (identificado con Practitioner/12942879-f89f-41ae-aa80-0b911b649833) mediante una aplicación de confianza App/123 busca todas las observaciones con 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"

    Deberías recibir una respuesta JSON similar a la que se muestra a continuación:

    {
      "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. El profesional José Borrero (identificado con Practitioner/12942879-f89f-41ae-aa80-0b911b649833) mediante la aplicación App/123 busca todas las observaciones de la paciente Diana.
  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"

    Deberías recibir una respuesta JSON similar a la que se muestra a continuación:

    {
      "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 consulta anterior es una búsqueda en cadena. Debido a que en la situación del consentimiento a actor/Practitioner/12942879-f89f-41ae-aa80-0b911b649833 env/App/123 se le niega el acceso al recurso de la paciente Diana (identificada con Patient/3c6aa096-c054-4c22-b2b4-1e4a4d203de2), el servidor de FHIR no muestra ninguna observación del paciente, es como si no existiera.

  5. El profesional José Borrero (identificado con Practitioner/12942879-f89f-41ae-aa80-0b911b649833) mediante la aplicación App/123 busca en todas las observaciones de la paciente Diana con fines de tratamiento de emergencia.
  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"

    Deberías recibir una respuesta JSON similar a la que se muestra a continuación:

    {
      "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. El profesional José Borrero (identificado con Practitioner/12942879-f89f-41ae-aa80-0b911b649833) busca observaciones con status=final para dos propósitos, investigaciones de tratamientos y
  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"

    Deberías recibir una respuesta JSON similar a la que se muestra a continuación:

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

    En este caso, el profesional José Borrero debe quitar un propósito innecesario de "X-Consent-Scope" en la solicitud.

  9. Un administrador de TI de un hospital usa bypass para buscar a todos los profesionales del hospital.
  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?"

    Como se proporciona bypass, se omitieron las verificaciones de consentimiento. Deberías recibir una respuesta JSON similar a la que se muestra a continuación:

    {
      "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"
    }
    

La API de Cloud Healthcare admite la obtención de recursos de FHIR en un almacén de FHIR determinado con actor, purpose y environment como parámetros de consulta. La respuesta contiene solo los recursos que están en consentimiento.

  1. El profesional José Borrero (identificado con Practitioner/12942879-f89f-41ae-aa80-0b911b649833) que usa la aplicación App/123 lee la medición de hemoglobina del paciente (en este ejemplo, 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"

    Debido a que se le otorgó el consentimiento al solicitante, la respuesta es el contenido del recurso de observación.

    {
      "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. El profesional José Borrero (identificado con Practitioner/12942879-f89f-41ae-aa80-0b911b649833) que usa la aplicación desconocida App/unknown lee la medición de hemoglobina del paciente (en este ejemplo, 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"

    Debido a que el consentimiento del paciente no permite el acceso al límite del solicitante ("App/unknown"), se rechaza la solicitud.

    {
      "issue": [
        {
          "code": "security",
          "details": {
            "text": "permission_denied"
          },
          "diagnostics": "Consent access denied or the resource being accessed does not exist",
          "severity": "error"
        }
      ],
      "resourceType": "OperationOutcome"
    }
    
  5. El profesional José Borrero (identificado con Practitioner/12942879-f89f-41ae-aa80-0b911b649833) que realiza una investigación biomédica con la aplicación App/golden lee el atributo birthDate de Darcy (en este ejemplo, 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"

    Debido a que se le otorgó el consentimiento al solicitante, la respuesta es el contenido del recurso de paciente.

    {
      "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. El profesional José Borrero (identificado con Practitioner/12942879-f89f-41ae-aa80-0b911b649833) solicita acceso de emergencia no autorizado al registro de un paciente con el protocolo "rompe el vidrio". (en este ejemplo, 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"

    Debido a que el método de autorización del consentimiento es btg, el servidor omite las verificaciones de consentimiento. La respuesta es el contenido del recurso 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
      }
    }
    

En las siguientes secciones, se describen los métodos de aplicación de consentimiento compatibles en la API de Cloud Healthcare y cómo se aplica el acceso a los recursos cuando se realiza una solicitud de consentimiento adaptada.

Cuando se realiza una solicitud, tu servidor de autorización es responsable de generar tokens de acceso con el permiso de consentimiento relevante.

Configura el encabezado HTTP

Los permisos de consentimiento se pasan a la API de Cloud Healthcare mediante el encabezado HTTP X-Consent-Scope. La API de Cloud Healthcare usa este encabezado para aplicar el control de acceso basado en el consentimiento de los datos en almacenes de FHIR.

Una solicitud de FHIR puede admitir una cantidad limitada de permisos de entrada de consentimiento. Se pueden incluir hasta tres entradas de actor, una de purp y una de env en una solicitud de FHIR determinada.

Para los permisos especiales, una solicitud de FHIR puede admitir uno de btg o bypass.

Establece encabezados HTTP para aplicaciones de confianza

Esta sección solo es necesaria si utilizas un servidor de autorización controlado por el cliente. En esta instancia, también debes usar un proxy SMARTproxy o una opción similar.

Algunas aplicaciones de confianza pueden realizar llamadas directamente a la API de Cloud Healthcare con los permisos de consentimiento en el encabezado HTTP especificado. Esto permite la aplicación directa del consentimiento sin la necesidad de que SMARTproxy o algún otro proxy realicen conversiones entre los servidores de autorización externos y Google Cloud.

Por ejemplo, la aplicación se puede registrar para un subconjunto de permisos, como un permiso de aplicación environment, o la aplicación podría presentar un widget de selección para establecer algunas entradas del permiso, como el purpose de la persona que accede.

Un usuario de confianza o una aplicación de confianza también pueden usar las entradas de alcance btg o bypass, que están sujetas a revisiones posteriores a la auditoría.

La API de Cloud Healthcare proporciona una compatibilidad integrada para la aplicación del consentimiento de FHIR según los permisos de consentimiento de entrada. Los administradores de los almacenes de FHIR son responsables de crear y configurar un servidor de autorización fuera de la API de Cloud Healthcare que otorga permisos de consentimiento.

Token de acceso de muestra

En el siguiente ejemplo, se muestra un token de acceso codificado en Base64:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzM4NCJ9.eyJpc3MiOiJjb25zZW50LnRva2VuLm9yZyIsImlhdCI6MTYxMjg4NDA4NSwiZXhwIjoxNjQ0NDIwMDg1LCJhdWQiOiJ3d3cuZXhhbXBsZS5jb20iLCJzdWIiOiJkb2N0b3IuZ2FicmllbGFAZXhhbXBsZS5jb20iLCJzY29wZSI6Im9pZGMgYWN0b3IvUHJhY3RpdGlvbmVyLzEyMyBhY3Rvci9Hcm91cC85OTkgcHVycC92My9UUkVBVCBlbnYvQXBwL2FiYyJ9.fC7ljkVUUx8fwUOrJuONcrqA-WKC-k_Bclzlgds0Cq6H_gEe3nUjPlSOCTQsIdYB

Después de decodificar el token de acceso, puedes ver que contiene la siguiente carga útil:

{
  "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"
}

Configura SMARTProxy

SMARTProxy es un proxy de código abierto de Google que tiene las siguientes características:

  • Permite que el servidor FHIR de la API de Cloud Healthcare acepte y valide los tokens de acceso adaptados al consentimiento.

  • Permite que la implementación de FHIR en la API de Cloud Healthcare incluya tokens de acceso adaptados al consentimiento como parte del modelo de permisos y la administración de la API de Cloud Healthcare.

  • También admite características de token para la compatibilidad de SMART en FHIR.

Cuando realizas una solicitud para recuperar datos de la API de Cloud Healthcare a través de SMARTProxy, ocurre lo siguiente:

  1. SMARTProxy acepta una solicitud de un cliente que contiene un token adaptado al consentimiento.

  2. SMARTProxy valida el token adaptado al consentimiento mediante un servidor de autorización JWT que te pertenece.

  3. SMARTProxy lee los permisos del token adaptado al consentimiento y los pasa a la API de Cloud Healthcare a través del encabezado HTTP.

  4. La API de Cloud Healthcare recibe los encabezados y los valida para aplicar las directivas de consentimiento en la solicitud. Luego, la API de Cloud Healthcare le muestra al cliente una respuesta a través del SMARTProxy del cliente.

Configura una cuenta de servicio de Google Cloud

Un proxy solo puede tener una sola cuenta de servicio de Google Cloud. Si varios clientes usan el mismo proxy, los clientes usarán la misma cuenta de servicio. Ten cuidado cuando compartas una cuenta de servicio con varios clientes por los siguientes motivos:

Por ejemplo, si llamas a la API de Cloud Healthcare directamente con tu Cuenta de Google para la autenticación, entonces, los Registros de auditoría de Cloud registran tu dirección de correo electrónico como la principal. Cuando usas un proxy para llamar a la API de Cloud Healthcare, el proxy usa su propia cuenta de servicio, y la dirección de correo electrónico principal es la de la cuenta de servicio y la cuenta original no está definida.

Registros de auditoría

Los registros de auditoría se generan cuando hay una solicitud de acceso o cuando cambia la aplicación forzosa de acceso de los recursos.

Accede a los registros de auditoría

Si los registros de auditoría están habilitados en el almacén de FHIR, se incluye un campo de metadatos consentMode en los registros de auditoría disponibles en Cloud Logging. consentMode puede tener uno de los siguientes valores:

  • off: La configuración del almacén de FHIR tiene consentConfig.accessEnforced configurado como false y no permite solicitudes de consentimiento.

  • emptyScope: El almacén de FHIR tiene consentConfig.accessEnforced configurado como true, pero no se incluyó un encabezado de alcance de consentimiento. Como resultado, no se aplicaron los consentimientos.

  • enforced: El almacén de FHIR tiene consentConfig.accessEnforced configurado como true y el encabezado del permiso de consentimiento estaba presente. Como resultado, se evaluaron los consentimientos y se aplicaron en la solicitud.

  • btg: La solicitud de FHIR tenía btg proporcionado en el encabezado de alcance de consentimiento. Como resultado, se omitieron las verificaciones de consentimiento. Esta solicitud está destinada a usarse en emergencias y está sujeta solo a la revisión posterior a la auditoría.

  • bypass: La solicitud de FHIR solo tenía bypass proporcionado en el encabezado de permiso de consentimiento. Como resultado, se omitieron las verificaciones de consentimiento. Esta solicitud está diseñada para que la use un flujo de trabajo de confianza (como un administrador o una aplicación de confianza en lugar de los usuarios finales) de modo que este registro de auditoría sea diferente de btg, que se usa para las verificaciones de gobernanza de datos.

De manera opcional, puedes establecer access_determination_log_config en VERBOSE para registrar más información sobre por qué se otorga o se rechaza una solicitud.

Accede a los registros de auditoría de cambios de aplicación forzosa

Cuando cambia el recurso base del compartimento (por ejemplo, se quita la etiqueta employee de un paciente), el control de acceso en el recurso modificado y su compartimento puede cambiar debido a la política de anidación de administradores. Se activará el reindexado en todos los recursos del compartimento. Se puede hacer un seguimiento del progreso de la reinstalación de índices de cada actualización de recursos básicos del compartimento en Cloud Logging con el filtro jsonPayload.@type="type.googleapis.com/google.cloud.healthcare.logging.FhirConsentCascadeLogEntry".

Ejemplo de registro de progreso del reindexación en cascada

{
  "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 es el estado de la operación de reindexación, jsonPayload.affectedResources es la cantidad de recursos de compartimento reindexados y jsonPayload.lastUpdated es la marca de tiempo de la actualización del recurso del paciente. Si la operación acaba de comenzar, jsonPayload.state="STATE_STARTED" y jsonPayload.affectedResources no estarán presentes.

Restricciones y limitaciones

En esta sección, se muestran las restricciones y los límites de FHIR R4, pero se aplican a la FTU3 de FHIR.

Tipo Restricciones y límites
Recurso de consentimiento único
  • Solo se admite un único Consent.provision; no se admiten varios aprovisionamientos o aprovisionamientos anidados.
  • Al menos 1 Consent.provision.actor, como máximo 25:
    • Consent.provision.actor.role debe ser http://terminology.hl7.org/CodeSystem/v3-RoleCode
    • Consent.provision.actor.code debe ser GRANTEE o HPOWATT.
  • Como máximo 1 Consent.provision.purpose:
    • Consent.provision.purpose.system debe ser http://terminology.hl7.org/CodeSystem/v3-ActReason
    • Consent.provision.purpose.code no está vacío y tiene un máximo de 13 caracteres.
  • Como máximo 1 environment:
    • Consent.provision.extension.url debe ser https://g.co/fhir/medicalrecords/Environment
    • La longitud combinada entre el sistema y el código debe ser inferior a 15 caracteres.
  • Si filtras por tipo de recurso, Consent.provision.class.system debe ser http://hl7.org/fhir/resource-types.
  • Si filtras por fuente de datos, Consent.provision.extension.url debe ser https://g.co/fhir/medicalrecords/DataSource.
  • Si filtras por etiqueta de datos, Consent.provision.extension.url debe ser https://g.co/fhir/medicalrecords/DataTag.
    • La etiqueta de datos puede ser una extensión compleja, anidada hasta un nivel, para describir una política que coincida con los recursos con todas las etiquetas especificadas (interpretada de forma conjunta).
    • Se admiten como máximo 5 etiquetas anidadas.
  • Máximo 100 valores para todos los atributos repetidos, a menos que se describan de manera diferente en esta fila.
Modelo de aplicación
  • Cada paciente puede tener hasta 200 recursos de consentimiento active aplicados a la vez.
  • Cada tienda puede tener hasta 200 políticas de administrador active aplicadas a la vez.
  • Un formato compacto especial para el conjunto de todas las Directivas de consentimiento en todos los consentimientos activos de un paciente determinado no debe exceder un umbral de tamaño establecido. Por lo general, hay capacidad suficiente para codificar miles de directivas de consentimiento, a menos que las strings de recursos muy largas estén sobrecargadas. Por ejemplo:
    • Cientos de consentimientos en fuentes de datos y etiquetas de datos únicas, cada una de las cuales consume mucho espacio.
    • Un solo paciente con 3,000 entradas de identificador de recurso Consent.provision.data.reference únicas en varios consentimientos activos, cada una con una Consent.provision.actor única, usa un espacio de forma más impositiva que las provisiones que no especifican ninguna restricción de referencia de datos ni contienen muchas de las mismas cadenas de referencia de actor.
  • Cada recurso puede tener hasta 1,000 directivas de consentimiento de todos los Consentimientos que se apliquen a él.
X-Consent-Scope
  • Mínimo una y máximo tres entradas actor.
  • Máximo una entrada purp:
    • Cada entrada purp debe tener el formato system/code (v3 es el sistema registrado para http://terminology.hl7.org/CodeSystem/v3-ActReason).
    • La longitud del código debe ser menor que 13.
  • Máximo una entrada env:
    • Cada entrada env debe tener el formato system/code.
    • La longitud combinada del sistema y el código debe ser inferior a 15.
  • btg requiere al menos una entrada actor.
  • bypass requiere, como mínimo, una entrada actor y una entrada env.
Métodos admitidos
Rendimiento
  • ApplyConsents y ApplyAdminConsents escalan de manera similar o mejor que ImportResources.
  • Información sobre las solicitudes que tienen en cuenta el consentimiento:
    • Nuestro modelo de consentimiento se optimizó para la aplicación del rendimiento de las operaciones CRUD, incluida la búsqueda a gran escala en muchos recursos y muchos pacientes.
    • Una lectura de recursos individuales puede tener un impacto marginal en la latencia de la solicitud. Sin embargo, el rendimiento de la búsqueda varía según la consulta base y la cantidad de permisos de consentimiento que generan más criterios de acceso activos durante una búsqueda.
    • Recomendamos ejecutar tus propias pruebas de rendimiento en una variedad de parámetros de solicitud de FHIR representativos a fin de determinar las características de rendimiento para tus casos prácticos en función de las características de tus datos, como la cantidad de recursos de un tipo de recurso de búsqueda determinado en el almacén de FHIR.
    • Nuestra solución mantiene la transferencia y las actualizaciones de todos los recursos, incluidos los de consentimiento y básicos que permite que la capacidad de procesamiento durante la transferencia y otras formas de tráfico de escritura continúe con un impacto mínimo.

Prácticas recomendadas

En las siguientes secciones, se describen las prácticas recomendadas para usar el control de acceso de FHIR.

Prácticas recomendadas generales

  • No import recursos de FHIR ni llames a ApplyConsents o ApplyAdminConsents en paralelo. Te recomendamos que primero importes recursos de FHIR y, luego, llames a ApplyConsents o ApplyAdminConsents. Sin embargo, si los recursos que se importarán no incluyen ningún recurso de paciente o consentimiento, el modelo de aplicación no se verá afectado y no será necesario procesar consentimientos o políticas de administración.

  • No crees búsquedas personalizadas ni llames a ApplyConsents en paralelo. Te recomendamos realizarlos una tras otra.

  • Si tus flujos de trabajo requieren llamar a varios ApplyConsents en PatientScope disyuntos, se pueden llamar en paralelo.

  • ApplyAdminConsents puede ejecutarse en paralelo con cualquier cantidad de ApplyConsents, pero no con otra ApplyAdminConsents.

  • Cuando configures el proxy, restringe la cuenta de servicio de IAM con permisos de solo lectura para evitar escribir los datos de un paciente en los registros de otro.

  • No uses el proxy de consentimiento cuando crees o actualices registros.

  • Valida todas las solicitudes de escritura para evitar modificaciones inesperadas de los datos de los pacientes.

  • Cuando se aplican los consentimientos en cascada, primero se deben importar los recursos básicos del compartimento, seguidos de los recursos restantes del compartimento. Como alternativa, todos los recursos del compartimento se pueden unir en un solo paquete y transferir con fhir.executeBundle.

Borra recursos Patient

Cuando borras un recurso Patient, si también deseas quitar la aplicación del consentimiento para ese paciente (en especial cuando FhirStore.disableReferentialIntegrity es verdadero), te recomendamos que sigas este orden de las operaciones:

  1. Borra todos los recursos de consentimiento que pertenecen al recurso Patient.

  2. Llama a ApplyConsents con el filtro PatientScope.

A fin de configurar un almacén existente para el acceso de consentimiento, sigue estos pasos:

  1. Usa UpdateFhirStore para configurar lo siguiente:ConsentConfig con la aplicación de consentimientoversion como V1 y establece accessEnforced a 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. Procesar los consentimientos de los pacientes o las políticas de administración

    1. ApplyConsents para los consentimientos de los pacientes
    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 para las políticas del administrador y las políticas en cascada del administrador.
    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"

Con qué frecuencia se debe ejecutar ApplyConsents o ApplyAdminConsents

  • Cuando el campo ConsentConfig no está configurado: el campo ConsentConfig no se configura cuando se crea por primera vez un almacén de FHIR y cuando el campo ConsentConfig se borra. Una vez que el campo ConsentConfig no esté configurado, debes repetir la configuración del almacén para el acceso de consentimiento antes de realizar solicitudes adaptadas al consentimiento a fin de para evitar la evaluación de políticas de aplicación de consentimiento desactualizadas.

  • Cuando el modelo de aplicación cambia: cuando se crea, actualiza o borra un recurso de consentimiento, el modelo de aplicación cambia. En esos casos, debes llamar a ApplyConsents o a ApplyAdminConsents para que se apliquen estos cambios.

    • Si puedes realizar un seguimiento de Patients con cambios de consentimiento, te recomendamos que uses el filtro PatientScope para evitar volver a procesar todo el almacén. Este filtro es útil para actualizar de inmediato la aplicación de un conjunto pequeño de pacientes.

    • También puedes ejecutar ApplyConsents de forma periódica mediante el filtro TimeRange. Este filtro es útil cuando la actualización inmediata no es crítica. Por ejemplo, la siguiente solicitud actualiza la aplicación de los cambios de consentimiento entre el 20 de enero de 2022 y las 0 a.m. de UTC 2022.

      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"

El visor de consentimiento de FHIR muestra las políticas de control de acceso. Proporciona una tabla que contiene permisos de consentimiento para representar las reglas de control de acceso de FHIR.

Antes de usar el visor de consentimiento de FHIR, asegúrate de lo siguiente:

Para ver el Visor de consentimiento de FHIR, completa los siguientes pasos:

¿Qué sigue?