En esta página se describe cómo usar los recursos Consent de FHIR para determinar el acceso a los datos de los almacenes FHIR en la API Cloud Healthcare.
Configurar un almacén con control de acceso FHIR habilitado
Para configurar un almacén FHIR con la opción de aplicar el consentimiento, sigue estos pasos:
Crea un almacén FHIR si aún no tienes uno.
Defina los siguientes parámetros
ConsentConfig
del almacén FHIR para habilitar la aplicación del consentimiento:version
: especifica qué versión de la aplicación del consentimiento se está usando en el almacén FHIR. Este valor solo se puede definir una vez medianteCreateFhirStore
oUpdateFhirStore
. Una vez que lo hayas configurado, debes llamar alApplyConsents
o alApplyAdminConsents
para cambiar la versión.access_enforced
: si se le asigna el valortrue
, al acceder a los recursos FHIR, los encabezados de consentimiento proporcionados se verificarán con las directivas de consentimiento dadas por los consumidores.consent_header_handling
: Si se define comoPERMIT_EMPTY_SCOPE
(valor predeterminado), el servidor permite solicitudes sin encabezadoX-Consent-Scope
(o con un encabezado vacío). Si se define comoREQUIRED_ON_READ
yaccess_enforced
=true
, el servidor rechaza todas las solicitudes sin el encabezadoX-Consent-Scope
(o con él vacío).
Configurar un almacén 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/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores?fhirStoreId=FHIR_STORE_ID"
Deberías recibir una respuesta JSON similar a la siguiente:
{ "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, usa UpdateFhirStore
para definir el
ConsentConfig
con la opción de cumplimiento del consentimiento version
como
V1
y define accessEnforced
como 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/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID?update_mask=consentConfig"
Definir políticas mediante el recurso Consent
Las políticas se representan mediante el recurso Consent. El propósito y el uso de los campos de recursos se describen en la documentación del modelo de datos.
A continuación se muestra un ejemplo de todos los recursos que se pueden crear en este caso concreto.
Crear recursos FHIR
En el siguiente ejemplo se muestra cómo ejecutar un [paquete FHIR](/healthcare-api/docs/how-tos/fhir-bundles) para rellenar los siguientes recursos:
- Un recurso Practitioner con el nombre Jeffrey Brown
- Un recurso Patient con el nombre Darcy Smith
- Recurso Observation que muestra la medición de hemoglobina de Darcy
(LOINC
718-7
) recogida por el Happy Hospital - Recurso Observation que muestra la medición de glucosa de Darcy
(LOINC
15074-8
). - Consentimiento de Darcy para permitir que Jeffrey Brown use la aplicación
App/123
para acceder a sus datos recogidos por Happy Hospital - Consentimiento de Darcy para permitir que Jeffrey Brown acceda a cualquiera de sus datos para
tratamiento de emergencia
(
ETREAT
) - Un consentimiento del Happy Hospital para permitir que Jeffrey Brown acceda a todos los datos
cuando realice investigaciones biomédicas (
BIORCH
) con la aplicaciónApp/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/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir"
Deberías recibir una respuesta JSON similar a la siguiente:
{ "entry": [ { "response": { "etag": "W/\"VERSION_ID\"", "lastModified": "2022-09-01T17:31:40.423469+00:00", "location": "https://healthcare.googleapis.com/v1/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/v1/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/v1/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/v1/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/v1/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/v1/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/v1/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 incluyen más ejemplos de recursos Consent de R4 que muestran cómo se pueden representar políticas complejas.
Directiva de consentimiento de un paciente de ejemplo
{ "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" } ] } }
El ejemplo anterior representa un recurso Consent de un paciente en el que un paciente f001
da permiso a un profesional sanitario f002
con el fin de recibir un tratamiento periódico representado por TREAT
.
El profesional procede de la geolocalización iso3166-1/CA
. Este recurso Consent permite al profesional acceder a los datos del paciente si los datos cumplen todas las condiciones siguientes.
- Es de tipo
Encounter
y tiene el IDEncounter/e001
. - Procede de la fuente
http://somesystem.example.org/foo
. - Cumple al menos una de las siguientes condiciones en la etiqueta (los recursos se pueden etiquetar configurando los campos
system
ycode
de Meta.tags): - Tiene la etiqueta (
system
=http://terminology.hl7.org/CodeSystem/common-tags
ycode
=actionable
) - Tiene ambas etiquetas (
system
=http://example.com/custom-tags
ycode
=archived
) and (system
=http://example.com/custom-tags
ycode
=insensitive
) - Tiene al menos una de las siguientes etiquetas de seguridad
system
=http://terminology.hl7.org/CodeSystem/v3-Confidentiality
ycode
es uno de los siguientes valores:R
,N
,M
,L
oU
.system
=http://terminology.hl7.org/CodeSystem/v3-ActCode
ycode
=PSY
.
Directiva de política de administrador de ejemplo
{ "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, el recurso Consent de la política de administrador otorga permiso a un profesional sanitario f002
con el fin de proporcionar un tratamiento periódico representado por TREAT
. El profesional es de la
geolocalización iso3166-1/CA
. Este recurso Consent permite al profesional acceder a los datos del paciente si estos cumplen todas las condiciones siguientes:
- Es de tipo
Encounter
y tiene el IDEncounter/e001
. - Procede de la fuente
http://somesystem.example.org/foo
. - Cumple al menos una de las siguientes condiciones en la etiqueta:
- Tiene la etiqueta (
system
=http://terminology.hl7.org/CodeSystem/common-tags
ycode
=actionable
) - Tiene ambas etiquetas (
system
=http://example.com/custom-tags
ycode
=archived
) and (system
=http://example.com/custom-tags
ycode
=insensitive
) - Tiene al menos una de las siguientes etiquetas de seguridad
system
=http://terminology.hl7.org/CodeSystem/v3-Confidentiality
ycode
es uno de los siguientes valores:R
,N
,M
,L
oU
.system
=http://terminology.hl7.org/CodeSystem/v3-ActCode
ycode
=PSY
.
Directiva de política en cascada de administrador de ejemplo
{ "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 Consent de una política en cascada de administrador que otorga permiso a un profesional sanitario f002
con el fin de proporcionar un tratamiento habitual representado por TREAT
. El profesional procede de la geolocalización iso3166-1/CA
. Este recurso Consent permite al profesional acceder 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 compartimento, es decir, al recurso Paciente, ya que controla los recursos de los que se va a hacer una cascada.
Aplicar los consentimientos de los pacientes o las políticas de administrador
Cumplir los consentimientos de los pacientes mediante 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/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID:applyConsents"
Deberías recibir una respuesta JSON similar a la siguiente:
{ "name": "projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID" }
La respuesta contiene un nombre de operación. Para hacer un seguimiento del estado de la operación, puedes usar el [método `get` de Operation](/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/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID"
Cuando finaliza la operación, el servidor devuelve 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.v1.OperationMetadata", "apiMethodName": "google.cloud.healthcare.v1.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.v1.fhir.ApplyConsentsResponse", "consentApplySuccess": "2", "affectedResources": "5" } }
Esta respuesta indica que el servidor ha procesado correctamente 2 consentimientos y ha actualizado el acceso consensual de 5 recursos (1 Patient, 2 Consents y 2 Observations).
Aplica la política de administrador 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/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID:applyAdminConsents"
Deberías recibir una respuesta JSON similar a la siguiente:
{ "name": "projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID" }
La respuesta contiene un nombre de operación. Para hacer un seguimiento del estado de la operación, puedes usar el [método `get` de Operation](/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/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID"
Cuando finaliza la operación, el servidor devuelve 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.v1.OperationMetadata", "apiMethodName": "google.cloud.healthcare.v1.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.v1.fhir.ApplyAdminConsentsResponse", "consentApplySuccess": "1", "affectedResources": "7" } }
Esta respuesta indica que el servidor ha procesado correctamente una política de administrador y ha actualizado el acceso consensual de siete recursos (un profesional sanitario, un paciente, dos observaciones, dos consentimientos de pacientes y una política de administrador).
La aplicación de los consentimientos almacenados en un almacén FHIR no entrará en vigor hasta que se llame a ApplyConsents
(para los consentimientos de los pacientes) o a ApplyAdminConsents
(para las políticas de administrador y las políticas de administrador en cascada) y se complete correctamente. Si añades, modificas o quitas consentimientos después de haber ejecutado ApplyConsents
o ApplyAdminConsents
, debes volver a ejecutarlo para que esos consentimientos se incluyan en el modelo de cumplimiento.
Los recursos FHIR se indexan de forma asíncrona, por lo que puede haber un ligero retraso entre el momento en que se completan las solicitudes ApplyConsents
o ApplyAdminConsents
y el momento en que el modelo de aplicación se refleja en los resultados de búsqueda. Este retraso solo se espera en las solicitudes de búsqueda.
Si es la primera vez que configuras la aplicación del consentimiento en el almacén FHIR, espera a que se complete la operación de larga duración ApplyConsents
o ApplyAdminConsents
antes de hacer solicitudes que tengan en cuenta el consentimiento.
Para llamar a ApplyConsents
en un subconjunto de pacientes, puedes usar los siguientes filtros:
PatientScope
: para ejecutarApplyConsents
en una lista de IDs de pacientes con hasta 10.000 pacientesTimeRange
: para ejecutarApplyConsent
en una lista de IDs de recursos de Patient cuyos recursos de Consent se actualizan durante un periodo determinado.
Para llamar a ApplyAdminConsents
, debe proporcionar la lista completa de todas las políticas que quiera aplicar (no una lista incremental). Por lo tanto, si se incluye una lista vacía, no se aplicarán las políticas de administrador de la tienda. Cada política debe ser un nombre de versión de recurso si el almacén FHIR usa versiones y un nombre de recurso en caso contrario.
Puedes usar operations.get
para obtener el ProgressCounter
de la operación. Una vez completado, se incluye un ApplyConsentsResponse en el Operation.response
.
Los contadores de ProgressCounter
y ApplyConsentsResponse
o ApplyAdminConsentsResponse
se describen en la siguiente tabla.
ProgressCounter |
ApplyConsentsResponse o ApplyAdminConsentsResponse |
Descripción |
---|---|---|
success |
consentApplySuccess |
Número de recursos Consent que la operación ha procesado correctamente. |
failure |
consentApplyFailure |
Número de recursos Consent no admitidos o no válidos. Puedes consultar los registros de errores en Cloud Logging o, si validateOnly está false , comprobar el estado de la aplicación del consentimiento con CheckConsentEnforcementStatus o CheckPatientConsentEnforcementStatus para obtener información detallada sobre los errores. |
secondarySuccess |
affectedResources |
Cuando validateOnly es false , representa el número de recursos FHIR que se han reindexado correctamente debido al efecto del cambio de consentimiento. |
secondaryFailure |
failedResources |
Cuando validateOnly es false , representa el número de recursos FHIR cuyo consentimiento puede haber cambiado, pero no se han podido reindexar. Esto puede afectar a la búsqueda con contexto de consentimiento, pero no a otros métodos. Para ver los detalles del error, puedes consultar los registros de errores en Cloud Logging. |
Cuando se procesan los recursos de consentimiento de FHIR, puede usar las siguientes APIs para comprobar el estado de la aplicación de un consentimiento o de todos los consentimientos de un paciente:
CheckConsentEnforcementStatus
: devuelve un recursoParameters
(STU3, R4) que incluye los siguientes parámetros:id
: representa el ID de recurso del recurso ConsentlastUpdated
: representa la hora en la que se aplicó el consentimiento por última vez.versionId
: representa el ID de versión usado para aplicar el consentimiento.consent-enforcement-status
: representa el estado de la aplicación del consentimiento
CheckPatientConsentEnforcementStatus
: devuelve unBundle
(STU3, R4) del recursoParameters
(STU3, R4) que consta del estado de cumplimiento de todos los consentimientos de un solo paciente.
En el caso de las políticas de administrador, CheckConsentEnforcementStatus
solo se puede usar para comprobar el estado de implementación de una única política de administrador de consentimiento. También puede usar fhirStores.get
para ver todas las políticas de administrador activas aplicadas a la tienda.
Estado de la aplicación del consentimiento
El consent-enforcement-status
puede tener cualquiera de los siguientes valores:
OFF
: representa el estado de cumplimiento predeterminado de un nuevo recurso Consent en el que nunca se ha procesado el recurso Consent.ENFORCEABLE
: el estado en el que se ha procesado correctamente el recurso Consent.INACTIVE
: estado inactivo en el que se ignora el recurso Consent.UNSUPPORTED
: el estado de un recurso Consent que puede ajustarse a las especificaciones de FHIR, pero no se puede aplicar. Esto se debe a la implementación limitada de la aplicación del consentimiento de FHIR con el nivel actual de compatibilidad de funciones.ENFORCEMENT_LIMIT_EXCEEDED
: el estado en el que el formato del recurso de consentimiento de FHIR y el nivel de asistencia del recurso no tienen errores, pero se cumple una o varias de las siguientes condiciones:El paciente tiene un gran conjunto de recursos Consent.
El tamaño de las directivas de consentimiento de todos los consentimientos activos es mayor que el tamaño máximo permitido de las directivas de consentimiento para que un servidor FHIR las aplique.
Buscar con contexto de consentimiento
La API Cloud Healthcare admite búsquedas de recursos FHIR en un almacén FHIR determinado con actor
, purpose
y environment
como parámetros de consulta. La respuesta solo contiene los recursos para los que se ha obtenido el consentimiento.
Buscar recursos FHIR con ámbito de consentimiento
- El profesional sanitario Jeffrey Brown (identificado con
Practitioner/12942879-f89f-41ae-aa80-0b911b649833
) usa una aplicación de confianzaApp/123
y busca todas las Observations constatus=final
. - El profesional sanitario Jeffrey Brown (identificado por
Practitioner/12942879-f89f-41ae-aa80-0b911b649833
) usa la aplicaciónApp/123
para buscar todas las Observations del paciente Darcy. - El profesional sanitario Jeffrey Brown (identificado con
Practitioner/12942879-f89f-41ae-aa80-0b911b649833
) usa la aplicaciónApp/123
para buscar todas las observaciones de la paciente Darcy con fines de tratamiento de emergencia. - El profesional sanitario Jeffrey Brown (identificado con
Practitioner/12942879-f89f-41ae-aa80-0b911b649833
) busca observaciones constatus=final
con dos fines: tratamiento e investigación. - Un administrador de TI de un hospital usa
bypass
para buscar a todos los profesionales del hospital.
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/v1/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 siguiente:
{ "entry": [ { "fullUrl": "https://healthcare.googleapis.com/v1/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/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation/?status=final" }, { "relation": "first", "url": "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation/?status=final" }, { "relation": "self", "url": "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation/?status=final" } ], "resourceType": "Bundle", "total": 1, "type": "searchset" }
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/v1/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 siguiente:
{ "link": [ { "relation": "search", "url": "https://healthcare.googleapis.com/v1/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/v1/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/v1/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 encadenada. Como se ha denegado el acceso al recurso Patient Darcy (identificado por Patient/3c6aa096-c054-4c22-b2b4-1e4a4d203de2
) en el escenario de consentimiento actor/Practitioner/12942879-f89f-41ae-aa80-0b911b649833 env/App/123
, el servidor FHIR no devuelve ninguna Observation del paciente, como si no existiera.
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/v1/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 siguiente:
{ "entry": [ { "fullUrl": "https://healthcare.googleapis.com/v1/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/v1/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/v1/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/v1/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/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation/?subject:Patient.name=Darcy" } ], "resourceType": "Bundle", "total": 2, "type": "searchset" }
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/v1/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 siguiente:
{ "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 sanitario Jeffrey Brown debería eliminar un propósito innecesario de `X-Consent-Scope` en la solicitud.
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/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Practitioner?"
Como se ha proporcionado bypass
, se han omitido las comprobaciones de consentimiento. Deberías recibir una respuesta JSON similar a la siguiente:
{ "entry": [ { "fullUrl": "https://healthcare.googleapis.com/v1/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/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Practitioner/?" }, { "relation": "first", "url": "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Practitioner/?" }, { "relation": "self", "url": "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Practitioner/?" } ], "resourceType": "Bundle", "total": 1, "type": "searchset" }
Obtener un recurso con contexto de consentimiento
La API Cloud Healthcare admite la obtención de recursos FHIR en un almacén FHIR determinado con actor
, purpose
y environment
como parámetros de consulta. La respuesta solo contiene los recursos para los que se ha obtenido el consentimiento.
Obtener recursos FHIR con ámbito de consentimiento
- El profesional sanitario Jeffrey Brown (identificado con
Practitioner/12942879-f89f-41ae-aa80-0b911b649833
) usa la aplicaciónApp/123
para leer la medición de hemoglobina del paciente (en este ejemplo,Observation/7473784b-46a8-470c-b9a6-fe38a01025aa
). - El profesional sanitario Jeffrey Brown (identificado por
Practitioner/12942879-f89f-41ae-aa80-0b911b649833
) usa una aplicación desconocidaApp/unknown
para leer la medición de hemoglobina del paciente (en este ejemplo,Observation/7473784b-46a8-470c-b9a6-fe38a01025aa
). - El profesional sanitario Jeffrey Brown (identificado con
Practitioner/12942879-f89f-41ae-aa80-0b911b649833
) realiza una investigación biomédica con la aplicaciónApp/golden
y lee la fecha de nacimiento de Darcy (en este ejemplo,Patient/3c6aa096-c054-4c22-b2b4-1e4a4d203de2
). - El profesional sanitario Jeffrey Brown (identificado por
Practitioner/12942879-f89f-41ae-aa80-0b911b649833
) solicita acceso de emergencia no autorizado al historial de un paciente mediante el protocolo "break-the-glass". En este ejemplo,Observation/7473784b-46a8-470c-b9a6-fe38a01025aa
.
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/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation/7473784b-46a8-470c-b9a6-fe38a01025aa"
Como se ha dado el consentimiento al solicitante, 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 } }
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/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation/7473784b-46a8-470c-b9a6-fe38a01025aa"
Se ha denegado la solicitud porque el acceso al límite del solicitante (`App/unknown`) no está permitido por el consentimiento del paciente.
{ "issue": [ { "code": "security", "details": { "text": "permission_denied" }, "diagnostics": "Consent access denied or the resource being accessed does not exist", "severity": "error" } ], "resourceType": "OperationOutcome" }
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/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Patient/3c6aa096-c054-4c22-b2b4-1e4a4d203de2"
Como se ha dado el consentimiento a la persona que ha enviado la solicitud, la respuesta es el contenido del recurso 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" }
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/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation/7473784b-46a8-470c-b9a6-fe38a01025aa"
Como el método de autorización del consentimiento es btg
, el servidor omite las comprobaciones del 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 } }
Configurar la cabecera de consentimiento
En las siguientes secciones se describen los métodos de aplicación del consentimiento admitidos en la API Cloud Healthcare y cómo se aplica el acceso a los recursos cuando se hace una solicitud que tiene en cuenta el consentimiento.
Cuando se envía una solicitud, el servidor de autorización es el encargado de generar tokens de acceso con el ámbito de consentimiento pertinente.
Definir encabezado HTTP
Los ámbitos de consentimiento se transfieren a la API Cloud Healthcare mediante la cabecera HTTP X-Consent-Scope
. La API Cloud Healthcare usa este encabezado para aplicar el control de acceso basado en el consentimiento a los datos de los almacenes FHIR.
Una solicitud de FHIR puede admitir un número limitado de ámbitos de entrada de consentimiento. En una solicitud FHIR determinada se pueden incluir hasta tres entradas de actor
, una de purp
y una de env
.
En el caso de los ámbitos especiales, una solicitud de FHIR puede admitir uno de los siguientes valores: btg
o bypass
.
Definir encabezados HTTP para aplicaciones de confianza
Esta sección solo es obligatoria si usas un servidor de autorización controlado por el cliente. En este caso, también debes usar un SMARTproxy o un proxy similar.
Algunas aplicaciones de confianza pueden hacer llamadas directamente a la API Cloud Healthcare con los ámbitos de consentimiento en el encabezado HTTP especificado. Esto permite aplicar el consentimiento directamente sin necesidad de un SMARTproxy u otro proxy para convertir entre servidores de autorización externos y Google Cloud.
Por ejemplo, tu aplicación puede registrarse para un subconjunto de ámbitos, como un ámbito de aplicación environment
, o bien puede presentar un widget de selección para definir algunas entradas de ámbito, como el purpose
del accesor.
Un usuario o una aplicación de confianza también podrían usar las entradas de ámbito btg
o bypass
, que están sujetas a revisiones posteriores a la auditoría.
Configurar el servidor de autorización para los ámbitos de consentimiento
La API Cloud Healthcare ofrece compatibilidad integrada con la aplicación de Consentimiento de FHIR en función de los ámbitos de consentimiento de entrada. Los administradores de almacenes FHIR son responsables de crear y configurar un servidor de autorización fuera de la API Cloud Healthcare que conceda ámbitos de consentimiento.
Token de acceso de ejemplo
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, verás 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"
}
Configurar SMARTProxy
SMARTProxy es un proxy de código abierto de Google que ofrece las siguientes funciones:
Permite que el servidor FHIR de la API Cloud Healthcare acepte y valide tokens de acceso con consentimiento.
Permite que la implementación de FHIR en la API Cloud Healthcare incluya tokens de acceso con consentimiento como parte de la gestión y el modelo de permisos de la API Cloud Healthcare.
También admite funciones de token para la compatibilidad con SMART on FHIR.
Cuando haces una solicitud para recuperar datos de la API Cloud Healthcare a través de SMARTProxy, ocurre lo siguiente:
SMARTProxy acepta una solicitud de un cliente que contiene un token que tiene en cuenta el consentimiento.
SMARTProxy valida el token con consentimiento a través de un servidor de autorización JWT que es de tu propiedad.
SMARTProxy lee los ámbitos del token que tiene en cuenta el consentimiento y los transfiere a la API Cloud Healthcare a través del encabezado HTTP.
La API Cloud Healthcare recibe los encabezados y los valida para aplicar las directivas de consentimiento en la solicitud. A continuación, la API de Cloud Healthcare devuelve una respuesta al cliente a través de SMARTProxy.
Configurar una cuenta de servicio de Google Cloud
Un proxy solo puede tener una cuenta de servicio. Google Cloud Si varios clientes usan el mismo proxy, utilizarán la misma cuenta de servicio. Ten cuidado al compartir una cuenta de servicio con varios clientes por los siguientes motivos:
Para leer los datos de FHIR en la API Cloud Healthcare, la cuenta de servicio se puede configurar para que tenga permisos de lectura y escritura amplios. Para obtener más información sobre los permisos, consulta el artículo sobre cómo controlar el acceso a los recursos de la API Cloud Healthcare. Consulta las prácticas recomendadas generales para configurar el proxy.
Registros de auditoría de Cloud
La dirección de correo principal está vinculada a la cuenta de servicio.
Por ejemplo, si llamas directamente a la API Cloud Healthcare con tu cuenta de Google para autenticarte, Cloud Audit Logs registrará tu dirección de correo como dirección de correo principal. Cuando usas un proxy para llamar a la API Cloud Healthcare, el proxy usa su propia cuenta de servicio y la dirección de correo principal es la dirección de correo de la cuenta de servicio. La cuenta original no se define.
Registros de auditoría
Los registros de auditoría se generan cuando hay una solicitud de acceso o cuando cambia la aplicación del acceso a los recursos.
de auditoría de acceso a datos.
Si los registros de auditoría están habilitados en el almacén FHIR, se incluye un campo de metadatos consentMode
en los registros de auditoría disponibles en Cloud Logging. El elemento consentMode
puede tener uno de los siguientes valores:
off
: la configuración del almacén FHIR tiene el valorconsentConfig.accessEnforced
definido comofalse
y no permite solicitudes que tengan en cuenta el consentimiento.emptyScope
: el almacén FHIR tiene el valorconsentConfig.accessEnforced
definido comotrue
, pero no se ha incluido un encabezado de ámbito de consentimiento. Por lo tanto, no se han aplicado los consentimientos.enforced
: el almacén FHIR tiene el valorconsentConfig.accessEnforced
definido comotrue
y el encabezado del ámbito de consentimiento estaba presente. Por lo tanto, los consentimientos se evaluaron y se aplicaron en la solicitud.btg
: la solicitud FHIR teníabtg
en el encabezado del ámbito de consentimiento. Por lo tanto, se han omitido las comprobaciones de consentimiento. Esta solicitud se debe usar en caso de emergencia y solo está sujeta a una revisión posterior.bypass
: la solicitud FHIR solo teníabypass
en el encabezado del ámbito de consentimiento. Por este motivo, se han omitido las comprobaciones de consentimiento. Esta solicitud está pensada para que la use un flujo de trabajo de confianza (como un administrador o una aplicación de confianza en lugar de usuarios finales) para que este registro de auditoría sea diferente delbtg
, que se usa para las comprobaciones de gobernanza de datos.
También puede definir access_determination_log_config
como VERBOSE
para registrar más información sobre por qué se concede o se deniega una solicitud.
Registros de auditoría de cambios en la aplicación del acceso
Cuando cambia el recurso base del compartimento (por ejemplo, si se elimina la etiqueta employee
de un paciente): el control de acceso al recurso modificado y a su compartimento puede cambiar debido a la política de cascada de administrador. Se volverán a indexar todos los recursos del compartimento. El progreso de la reindexación de cada actualización de recursos base de compartimento se puede monitorizar en Cloud Logging con el filtro jsonPayload.@type="type.googleapis.com/google.cloud.healthcare.logging.FhirConsentCascadeLogEntry"
.
Registro de progreso de reindexación en cascada de ejemplo
{ "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 el número de recursos de compartimento reindexados y jsonPayload.lastUpdated
es la marca de tiempo de la actualización del recurso de paciente. Si la operación acaba de iniciarse, no aparecerán jsonPayload.state="STATE_STARTED"
ni jsonPayload.affectedResources
.
Restricciones y limitaciones
En esta sección se muestran las restricciones y los límites de FHIR R4, pero las mismas restricciones y límites se aplican a FHIR STU3.
Tipo | Restricciones y límites |
---|---|
Recurso Consent |
|
Modelo de cumplimiento |
|
X-Consent-Scope |
|
Métodos admitidos |
|
Rendimiento |
|
Prácticas recomendadas
En las siguientes secciones se describen las prácticas recomendadas al usar el control de acceso de FHIR.
Prácticas recomendadas generales
No importes recursos FHIR y llames a
ApplyConsents
oApplyAdminConsents
en paralelo. Te recomendamos que primero importes recursos FHIR y, después, llames aApplyConsents
oApplyAdminConsents
. Sin embargo, si los recursos que se van a importar no incluyen ningún recurso Patient o Consent, el modelo de cumplimiento no se verá afectado y no será necesario procesar consentimientos ni políticas de administrador.No crees búsquedas personalizadas y llames a
ApplyConsents
en paralelo. Te recomendamos que los hagas uno después del otro.Si tus flujos de trabajo requieren llamar a varios
ApplyConsents
enPatientScope
disjuntos, se pueden llamar en paralelo.ApplyAdminConsents
puede ejecutarse en paralelo con cualquier número deApplyConsents
, pero no con otroApplyAdminConsents
.Al configurar el proxy, restringe la cuenta de servicio de IAM con permisos de solo lectura para evitar que se escriban los datos de un paciente en los registros de otro.
No utilice el proxy de consentimiento al crear o actualizar registros.
Valida todas las solicitudes de escritura para evitar modificaciones inesperadas de datos de pacientes.
Cuando se aplican consentimientos en cascada, los recursos base de los compartimentos deben importarse primero, seguidos del resto de los recursos del compartimento. También puedes envolver todos los recursos de compartimento en un solo paquete e ingerirlos mediante
fhir.executeBundle
.
Eliminar recurso Patient
Cuando elimine un recurso Patient, si también quiere eliminar la aplicación del consentimiento de ese paciente (sobre todo cuando FhirStore.disableReferentialIntegrity
sea true), le recomendamos que siga este orden de operaciones:
Elimina todos los recursos Consent que pertenezcan al recurso Patient.
Llama a
ApplyConsents
con el filtroPatientScope
.
Configurar una tienda para acceder al consentimiento
Para configurar una tienda que ya tengas para que pueda acceder a los consentimientos, sigue estos pasos:
Usa
UpdateFhirStore
para definir elConsentConfig
con la opción de cumplimiento del consentimientoversion
comoV1
y asigna el valortrue
aaccessEnforced
.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/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID?update_mask=consentConfig"
Procesar consentimientos de pacientes o políticas de administración
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/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID:applyConsents"
ApplyAdminConsents
para las políticas de administrador y las políticas de administrador en cascada.
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/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID:applyAdminConsents"
Con qué frecuencia se deben ejecutar ApplyConsents o ApplyAdminConsents
Cuando el campo
ConsentConfig
no está definido: el campoConsentConfig
no está definido tanto cuando se crea un almacén FHIR por primera vez como cuando se borra el campoConsentConfig
. Una vez que se haya anulado el campoConsentConfig
, debes repetir el proceso para configurar la tienda para el acceso al consentimiento antes de enviar solicitudes que tengan en cuenta el consentimiento para evitar que se evalúen políticas de cumplimiento obsoletas.Cuando cambia el modelo de cumplimiento: cuando se crea, actualiza o elimina un recurso Consent, cambia el modelo de cumplimiento. En esos casos, debes llamar al
ApplyConsents
o alApplyAdminConsents
para que se apliquen los cambios.Si puedes hacer un seguimiento de los cambios de los pacientes con consentimiento, te recomendamos que uses el filtro
PatientScope
para evitar tener que volver a procesar toda la tienda. Este filtro es útil para actualizar inmediatamente la aplicación de un pequeño conjunto de pacientes.También puedes ejecutar
ApplyConsents
periódicamente con elTimeRange
filtro. Este filtro es útil cuando no es fundamental que los datos se actualicen de inmediato. Por ejemplo, la siguiente solicitud actualiza la aplicación de las medidas por los cambios en el consentimiento entre las 00:00 (UTC) del 20/09/2022 y las 00:00 (UTC) del 21/09/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/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID:applyConsents"
Usar la vista de consentimiento de FHIR
El visor de consentimiento de FHIR muestra las políticas de control de acceso. Proporciona una tabla que contiene ámbitos de consentimiento para representar las reglas de control de acceso de FHIR.
Antes de usar el visor de consentimiento de FHIR, asegúrate de que se cumplen los siguientes requisitos:
El ajuste
disableResourceVersioning
del almacén FHIR debe serfalse
. Este ajuste no se puede cambiar una vez que se haya creado el almacén FHIR. Para crear un almacén FHIR, consulta Crear un almacén FHIR.El almacén FHIR está configurado para aplicar el consentimiento.
Para ver el visor de consentimiento de FHIR, sigue estos pasos:
Consola
En la Google Cloud consola, ve a la página Navegador.
Selecciona el conjunto de datos que contiene el almacén FHIR cuyas políticas de consentimiento obligatorias quieres ver.
En la página Almacenes de datos, en la lista Almacenes de datos, selecciona el almacén FHIR cuyas políticas de consentimiento obligatorias quieras ver.
En la página Detalles del almacén de datos, haga clic en la pestaña Consentimiento. Se muestran los ámbitos de consentimiento.