本页面介绍了如何使用 FHIR 同意资源确定 Cloud Healthcare API 中 FHIR 存储区的数据访问权限。
配置启用了 FHIR 访问权限控制的存储区
如需配置强制执行意见征求的 FHIR 存储区,请完成以下步骤:
如果您还没有 FHIR 存储区,请创建一个。
设置以下 FHIR 存储区的
ConsentConfig
参数,以启用意见征求强制执行:version
:指定正在用于 FHIR 存储区的意见征求强制执行版本。此值只能由CreateFhirStore
或UpdateFhirStore
设置一次。设置后,您必须调用ApplyConsents
或ApplyAdminConsents
来更改版本。access_enforced
:如果设置为true
,则在访问 FHIR 资源时,将根据使用方提供的意见征求指令来验证提供的意见征求标头。consent_header_handling
:如果设置为PERMIT_EMPTY_SCOPE
(默认值),则服务器允许不带(或为空)X-Consent-Scope
标头的请求。如果设置为REQUIRED_ON_READ
且access_enforced
=true
,则服务器会拒绝所有不含(或为空)X-Consent-Scope
标头的请求。
使用 ConsentConfig
设置新的 FHIR 存储区
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': false } }" "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores?fhirStoreId=FHIR_STORE_ID"
您应该收到类似以下内容的 JSON 响应:
{ "name": "projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID", "version": "R4", "enableUpdateCreate": true, "consentConfig": { "version": "V1" } }
如果您已有商店,请使用 UpdateFhirStore
将具有意见征求强制执行 version
的 ConsentConfig
设置为 V1
,并将 accessEnforced
设置为 false
。
curl -X PATCH \ -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \ -H "Content-Type: application/json" \ --data "{ 'consentConfig': { 'version': 'V1', 'accessEnforced': false } }" "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID?update_mask=consentConfig"
使用 Consent 资源定义政策
政策通过意见征求资源表示。如需了解资源字段的用途和用途,请参阅数据模型文档。
以下是可为此特定示例创建的所有资源的示例。
创建 FHIR 资源
以下示例展示了如何执行 [FHIR 软件包](/healthcare-api/docs/how-tos/fhir-bundles) 以填充以下资源:
- 名为 Jeffrey Brown 的从业者资源
- 名为 Darcy Smith 的患者资源
- 显示 Darcy (LOINC
718-7
) 的血红蛋白测量结果的观察资源,这些数据是由 Happy Hospital 收集的 - 显示 Darcy 的血糖测量结果的观察资源 (LOINC
15074-8
)。 - Darcy 同意 Jeffrey Brown 使用
App/123
应用访问她由 Happy Hospital 收集的数据 - Darcy 的同意书,允许 Jeffrey Brown 访问她的任何数据进行紧急治疗 (
ETREAT
) - 来自 Happy Hospital 的同意书,允许 Jeffrey Brown 在进行生物医学研究时访问所有数据 (
BIORCH
),只需申请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" }], "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"
您应该收到类似以下内容的 JSON 响应:
{ "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" }
以下是 R4 意见征求资源的更多示例,演示了如何表示复杂的政策。
患者同意指令示例
{ "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" } ], "systemLabel": [ { "system": "http://terminology.hl7.org/CodeSystem/v3-Confidentiality", "code": "R" }, { "system": "http://terminology.hl7.org/CodeSystem/v3-ActCode", "code": "PSY" } ] } }
上述示例代表了患者意见征求资源,其中患者 f001
向从业者 f002
授予了权限,以提供 TREAT
表示的常规治疗。从业者来自地理位置iso3166-1/CA
。如果数据满足以下所有条件,则此 Consent 资源允许从业者访问患者数据:
- 它是一种
Encounter
类型,ID 为Encounter/e001
。 - 它来自
http://somesystem.example.org/foo
源代码。 - 该代码至少满足以下其中一个条件:
- 具有标记(
system
=http://terminology.hl7.org/CodeSystem/common-tags
且code
=actionable
) - 同时包含这两个标记(
system
=http://example.com/custom-tags
和code
=archived
)且(system
=http://example.com/custom-tags
和code
=insensitive
) - 它至少具有以下某一安全标签
system
=http://terminology.hl7.org/CodeSystem/v3-Confidentiality
且code
是R
、N
、M
、L
、U
中的一个。system
=http://terminology.hl7.org/CodeSystem/v3-ActCode
且code
=PSY
。
管理政策指令示例
{ "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" } ], "systemLabel": [ { "system": "http://terminology.hl7.org/CodeSystem/v3-Confidentiality", "code": "R" }, { "system": "http://terminology.hl7.org/CodeSystem/v3-ActCode", "code": "PSY" } ] } }
上面的示例表示管理员政策 Consent 资源向从业者 f002
授予权限,用于提供常规服务(以 TREAT
表示)。从业者来自地理定位 iso3166-1/CA
。如果数据满足以下所有条件,则此 Consent 资源允许从业者访问患者数据:
- 它是一种
Encounter
类型,ID 为Encounter/e001
。 - 它来自
http://somesystem.example.org/foo
源代码。 - 该代码至少满足以下其中一个条件:
- 具有标记(
system
=http://terminology.hl7.org/CodeSystem/common-tags
且code
=actionable
) - 同时包含这两个标记(
system
=http://example.com/custom-tags
和code
=archived
)且(system
=http://example.com/custom-tags
和code
=insensitive
) - 它至少具有以下某一安全标签
system
=http://terminology.hl7.org/CodeSystem/v3-Confidentiality
且code
是R
、N
、M
、L
、U
中的一个。system
=http://terminology.hl7.org/CodeSystem/v3-ActCode
且code
=PSY
。
管理员级联政策指令示例
{ "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" } } ] } }
上面的示例表示管理员级联政策意见征求资源,该资源向从业者 f002
授予权限,用于提供常规服务(以 TREAT
表示)。从业者来自地理定位 iso3166-1/CA
。此意见征求资源允许从业者访问带有 employee
标记患者的房间数据。所有资源条件仅适用于房间基本资源(即患者资源),因为它控制着哪些资源进行级联。
强制执行患者同意书或管理政策
在 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"
您应该收到类似以下内容的 JSON 响应:
{ "name": "projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID" }
响应包含操作名称。如需跟踪操作的状态,您可以使用 [操作 `get` 方法](/healthcare-api/docs/reference/rest/v1/projects.locations.datasets.operations/get):
curl -X GET \ -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \ "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID"
操作完成后,服务器会以 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" } }
此响应表明服务器成功处理了 2 份同意声明,并更新了 5 项资源的同意访问数据(1 名患者、2 份同意声明和 2 项观察数据)。
请在 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"
您应该收到类似以下内容的 JSON 响应:
{ "name": "projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID" }
响应包含操作名称。如需跟踪操作的状态,您可以使用 [操作 `get` 方法](/healthcare-api/docs/reference/rest/v1/projects.locations.datasets.operations/get):
curl -X GET \ -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \ "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID"
操作完成后,服务器会以 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" } }
此响应表明服务器成功处理了 1 项管理员政策并更新了 7 项资源的同意访问(1 名从业者、1 名患者、2 项观察、2 份患者同意书和 1 项管理员政策)。
只有在调用并成功完成 ApplyConsents
(针对患者同意)或 ApplyAdminConsents
(针对管理员政策和管理级联政策)之后,对存储在 FHIR 存储区中的同意声明才会生效。如果您在运行 ApplyConsents
或 ApplyAdminConsents
后添加、修改或移除用户意见,则必须再次运行该程序,才能将这些意见纳入到执行模型中。
FHIR 资源是异步编入索引的,因此 ApplyConsents
或 ApplyAdminConsents
完成时间与强制执行模型在搜索结果中反映出来之间可能会略有延迟。只有搜索请求会出现这种延迟。
如果这是您第一次为 FHIR 存储区设置意见征求强制执行,请等待 ApplyConsents
或 ApplyAdminConsents
长时间运行的操作完成,然后再发出知晓用户意见的请求。
如需对一部分患者调用 ApplyConsents
,您可以使用以下过滤器:
PatientScope
:针对多达 10,000 位患者的 ID 列表运行ApplyConsents
TimeRange
:针对特定时间范围内更新其同意资源的患者资源 ID 列表运行ApplyConsent
如需调用 ApplyAdminConsents
:您需要提供要应用的所有政策的完整列表(而非增量列表)。因此,空列表会使存储区的所有管理政策的强制执行无效。如果 FHIR 存储区进行版本控制,则每个政策都必须是资源版本名称,否则必须是资源名称。
您可以使用 operations.get
检索该操作的 ProgressCounter
。完成后,将会有一个 ApplyConsentsResponse 包含在 Operation.response
中。下表介绍了 ProgressCounter
和 ApplyConsentsResponse
或 ApplyAdminConsentsResponse
中的计数器。
ProgressCounter |
ApplyConsentsResponse 或 ApplyAdminConsentsResponse |
说明 |
---|---|---|
success |
consentApplySuccess |
操作成功处理的 Consent 资源的数量。 |
failure |
consentApplyFailure |
不受支持或无效的 Consent 资源的数量。您可以在 Cloud Logging 中查看错误日志;当 validateOnly 为 false 时,使用 CheckConsentEnforcementStatus 或 CheckPatientConsentEnforcementStatus 检查意见征求强制执行状态,以检索错误详情。 |
secondarySuccess |
affectedResources |
当 validateOnly 为 false 时,它表示由于意见征求更改的影响而成功重新编入索引的 FHIR 资源数量。 |
secondaryFailure |
failedResources |
当 validateOnly 为 false 时,它表示可以更改同意情况但未能重新编入索引的 FHIR 资源数量。这可能会影响在提供用户意见的情况下进行搜索,但不会影响其他方法。如需查看错误详情,您可以在 Cloud Logging 中查看错误日志。 |
处理 FHIR 同意资源后,您可以使用以下 API 检查单个同意或患者所有同意的强制执行状态:
CheckConsentEnforcementStatus
:返回列出以下参数的Parameters
(STU3、R4)资源:id
:表示同意资源的 IDlastUpdated
:表示上次强制执行同意的时间versionId
:表示用于同意强制执行的版本 IDconsent-enforcement-status
:表示同意强制执行状态
CheckPatientConsentEnforcementStatus
:返回Parameters
(STU3、R4)资源的Bundle
(STU3、R4),该资源包含来自单个患者的所有同意的强制执行状态
对于管理政策,CheckConsentEnforcementStatus
只能用于检查单项意见征求管理政策的强制执行状态。或者,您也可以使用 fhirStores.get
查看应用于商店的所有有效管理员政策。
意见征求强制执行状态
consent-enforcement-status
可以具有以下任一值:
OFF
:表示新的意见征求资源(其中从未处理过 Consent 资源)的默认强制执行状态。ENFORCEABLE
:同意资源已成功处理的状态。INACTIVE
:同意资源被忽略的非活跃状态。UNSUPPORTED
:可能符合 FHIR 规范但无法执行的同意资源状态。这是由于在当前功能支持级别下 FHIR 同意强制执行的实施有限。ENFORCEMENT_LIMIT_EXCEEDED
:FHIR 同意资源格式和资源支持级别没有错误但以下一个或多个条件为 true 时的状态:患者拥有大量同意资源。
所有活跃同意中的同意指令大小都大于 FHIR 服务器强制执行同意指令的最大大小。
针对传入请求启用访问权限
传入请求的访问权限检查通过存储区配置启用:consentConfig.accessEnforced
。以下示例演示了如何启用此 API。
更新 FHIR 存储区以针对传入请求启用强制执行同意
curl -X PATCH \ -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \ -H "Content-Type: application/json" \ --data "{ 'consentConfig': { 'accessEnforced': true } }" "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID?update_mask=consentConfig.accessEnforced"
您应该收到类似以下内容的 JSON 响应:
{ "name": "projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID", "version": "R4", "consentConfig": { "version": "V1", "accessEnforced": true } }
使用同意上下文进行搜索
Cloud Healthcare API 支持在给定的 FHIR 存储区中搜索使用 actor
、purpose
和 environment
作为查询参数的 FHIR 资源。响应仅包含已征得用户同意的资源。
搜索具有同意范围的 FHIR 资源
- 使用可信应用
App/123
的从业者 Jeffrey Brown(由Practitioner/12942879-f89f-41ae-aa80-0b911b649833
标识)使用status=final
搜索所有观察结果。 - 使用应用
App/123
的从业者 Jeffrey Brown(由Practitioner/12942879-f89f-41ae-aa80-0b911b649833
标识)搜索患者 Darcy 的所有观察结果。 - 使用应用
App/123
的从业者 Jeffrey Brown(由Practitioner/12942879-f89f-41ae-aa80-0b911b649833
标识)会搜索患者 Darcy 的所有观察结果,用于紧急治疗。 - 从业者 Jeffrey Brown(由
Practitioner/12942879-f89f-41ae-aa80-0b911b649833
标识)使用status=final
搜索观察结果,有两个目的:治疗和研究 - 医院 IT 管理员使用
bypass
搜索医院的所有实操人员。
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"
您应该收到类似以下内容的 JSON 响应:
{ "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" }
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"
您应该收到类似以下内容的 JSON 响应:
{ "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" }
上述查询为链式搜索。由于意见征求场景 actor/Practitioner/12942879-f89f-41ae-aa80-0b911b649833 env/App/123
被拒绝访问患者 Darcy 资源(由 Patient/3c6aa096-c054-4c22-b2b4-1e4a4d203de2
标识),因此 FHIR 服务器不会从患者返回任何观察结果,就像病人不存在一样。
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"
您应该收到类似以下内容的 JSON 响应:
{ "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" }
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"
您应该收到类似以下内容的 JSON 响应:
{ "issue": [ { "code": "security", "details": { "text": "permission_denied" }, "diagnostics": "the maximum number of allowed consent purpose scopes is 1, got 2", "severity": "error" } ], "resourceType": "OperationOutcome" }
在这种情况下,从业者 Jeffrey Brown 应从请求的“X-Consent-Scope”中移除不必要的用途。
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?"
由于提供了 bypass
,因此跳过了用户意见征求检查。您应该会收到类似如下所示的 JSON 响应:
{ "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" }
获取包含意见征求上下文的资源
Cloud Healthcare API 支持使用 actor
、purpose
和 environment
作为查询参数获取给定 FHIR 存储区中的 FHIR 资源。响应仅包含已征得用户同意的资源。
获取具有同意范围的 FHIR 资源
- 医护人员 Jeffrey Brown(由
Practitioner/12942879-f89f-41ae-aa80-0b911b649833
标识)使用应用App/123
读取患者的血红蛋白测量值(在此示例中为Observation/7473784b-46a8-470c-b9a6-fe38a01025aa
)。 - 使用未知应用
App/unknown
的实操人员 Jeffrey Brown(由Practitioner/12942879-f89f-41ae-aa80-0b911b649833
标识)读取患者的血红蛋白测量结果(在此示例中为Observation/7473784b-46a8-470c-b9a6-fe38a01025aa
)。 - 从业者 Jeffrey Brown(由
Practitioner/12942879-f89f-41ae-aa80-0b911b649833
标识)使用应用App/golden
进行生物医学研究,读取了 Darcy 的出生日期(在本例中为Patient/3c6aa096-c054-4c22-b2b4-1e4a4d203de2
)。 - 医护人员 Jeffrey Brown(由
Practitioner/12942879-f89f-41ae-aa80-0b911b649833
标识)使用“紧急访问权限”协议请求在未经授权的情况下访问患者的记录。 (在此示例中为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/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation/7473784b-46a8-470c-b9a6-fe38a01025aa"
由于请求者已表示同意,因此响应是观察资源的内容。
{ "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/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation/7473784b-46a8-470c-b9a6-fe38a01025aa"
由于未经患者同意,请求者(“应用/未知”)的边界访问权限(“应用/未知”),因此请求会被拒绝。
{ "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/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Patient/3c6aa096-c054-4c22-b2b4-1e4a4d203de2"
由于请求者已表示同意,因此响应是患者资源的内容。
{ "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" }, "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/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation/7473784b-46a8-470c-b9a6-fe38a01025aa"
由于意见征求的授权方法是 btg
,因此服务器会跳过用户意见检查。响应是观察资源的内容。
{ "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 } }
配置用户意见征求标头
以下部分介绍了 Cloud Healthcare API 中支持的同意强制执行方法,以及如何在发出同意感知请求时强制执行资源访问。
发出请求时,您的授权服务器负责生成具有相关同意范围的访问令牌。
设置 HTTP 标头
同意范围使用 X-Consent-Scope
HTTP 标头传递给 Cloud Healthcare API。Cloud Healthcare API 使用此标头对 FHIR 存储区中的数据实施基于同意的访问权限控制。
FHIR 请求可支持有限数量的同意条目范围。给定的 FHIR 请求中最多可以包含三个 actor
条目、一个 purp
条目和一个 env
条目。
对于特殊范围,FHIR 请求可以支持 btg
或 bypass
中的一个。
为可信应用设置 HTTP 标头
只有在使用客户控制的授权服务器时,才需要按照本部分执行操作。在此实例中,您还必须使用 SMARTproxy 或类似代理。
某些可信应用可以使用指定的 HTTP 标头中的同意范围直接调用 Cloud Healthcare API。这样一来,无需 SMARTproxy 或其他代理在外部授权服务器与 Google Cloud 之间进行转换,即可强制执行直接意见征求。
例如,您的应用可能注册了部分范围,例如一个应用 environment
范围,或者应用可能会显示选择微件来设置一些范围条目,例如访问者的 purpose
。
可信用户或可信应用也可以使用 btg
或 bypass
范围条目,它们需要接受后审核审核。
为同意范围配置授权服务器
Cloud Healthcare API 根据输入同意范围提供对 FHIR 同意强制执行的内置支持。FHIR 存储区管理员负责在 Cloud Healthcare API 之外创建和配置授予同意范围的授权服务器。
访问令牌示例
以下示例展示了用 base64 编码的访问令牌:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzM4NCJ9.eyJpc3MiOiJjb25zZW50LnRva2VuLm9yZyIsImlhdCI6MTYxMjg4NDA4NSwiZXhwIjoxNjQ0NDIwMDg1LCJhdWQiOiJ3d3cuZXhhbXBsZS5jb20iLCJzdWIiOiJkb2N0b3IuZ2FicmllbGFAZXhhbXBsZS5jb20iLCJzY29wZSI6Im9pZGMgYWN0b3IvUHJhY3RpdGlvbmVyLzEyMyBhY3Rvci9Hcm91cC85OTkgcHVycC92My9UUkVBVCBlbnYvQXBwL2FiYyJ9.fC7ljkVUUx8fwUOrJuONcrqA-WKC-k_Bclzlgds0Cq6H_gEe3nUjPlSOCTQsIdYB
对访问令牌进行解码后,您可以看到它包含以下载荷:
{
"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"
}
配置 SMARTProxy
SMARTProxy 是 Google 的开源代理,可提供以下功能:
允许 Cloud Healthcare API FHIR 服务器接受并验证同意感知访问令牌。
允许 Cloud Healthcare API 中的 FHIR 实现在 Cloud Healthcare API 管理和权限模型中包含意见征求感知访问令牌。
在 FHIR 支持上也支持 SMART 的令牌功能。
当您发出通过 SMARTProxy 从 Cloud Healthcare API 检索数据的请求时,会发生以下情况:
SMARTProxy 接受包含同意感知令牌的客户端的请求。
SMARTProxy 通过您拥有的 JWT 授权服务器验证同意感知令牌。
SMARTProxy 从意见征求感知令牌中读取范围,并通过 HTTP 标头将它们传递给 Cloud Healthcare API。
Cloud Healthcare API 会接收标头并对其进行验证,以对请求强制执行同意指令。随后,Cloud Healthcare API 通过 SMARTProxy 向客户端返回响应。
配置 Google Cloud 服务账号
一个代理只能有一个 Google Cloud 服务账号。如果多个客户端使用相同的代理,则这些客户端也将使用相同的服务账号。与多个客户端共享服务账号时,请务必小心,原因如下:
如需读取 Cloud Healthcare API 中的 FHIR 数据,可以将服务帐号配置为具有广泛的读写权限。如需详细了解权限,请参阅控制对 Cloud Healthcare API 资源的访问权限。 请参阅设置代理的一般性最佳实践。
Cloud Audit Logs
主电子邮件地址与服务账号关联。
例如,如果您使用您的 Google 账号直接调用 Cloud Healthcare API 以进行身份验证,则 Cloud Audit Logs 会将您的电子邮件地址记录为主电子邮件地址。使用代理调用 Cloud Healthcare API 时,代理使用自己的服务帐号,主帐号电子邮件地址是服务帐号的电子邮件地址,原始帐号未定义。
审核日志
当有访问请求或资源的访问强制执行发生变化时,系统会生成审核日志。
访问审核日志
如果在 FHIR 存储区中启用审核日志,则 Cloud Logging 提供的审核日志中会包含 consentMode
元数据字段。consentMode
可以具有以下某个值:
off
:FHIR 存储区配置将consentConfig.accessEnforced
设置为false
,并且不允许同意感知请求。emptyScope
:FHIR 存储区的consentConfig.accessEnforced
设置为true
,但未包含同意范围标头。因此,同意未强制执行。enforced
:FHIR 存储区将consentConfig.accessEnforced
设置为true
,并且存在同意范围标头。因此,我们根据关于患者房间(STU3、R4)的资源请求评估并强制执行了同意声明。btg
:FHIR 请求在意见征求范围标头中提供了btg
。因此,跳过了用户意见征求检查。此请求仅用于紧急情况,并且仅用于审核后审核。bypass
:FHIR 请求在意见征求范围标头中仅提供了bypass
。因此,跳过了用户意见征求检查。此请求旨在供可信工作流(例如管理员或可信应用,而非最终用户)使用,因此此审核日志与用于数据治理检查的btg
不同。
或者,您也可以将 access_determination_log_config
设置为 VERBOSE
,以记录有关请求被批准或拒绝的原因。
访问权限强制执行更改审核日志
当分区基本资源发生更改(例如,移除患者的 employee
标记)时:对已更改的资源及其分区的访问权限控制可能会因管理员级联政策而发生变化。这会触发对其所有分区资源进行重新编入索引的操作。您可以使用过滤条件 jsonPayload.@type="type.googleapis.com/google.cloud.healthcare.logging.FhirConsentCascadeLogEntry"
在 Cloud Logging 中跟踪每个分区基础资源更新的重新编入索引进度。
级联重新索引进度日志示例
{ "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
是重新编入索引操作的状态,jsonPayload.affectedResources
是重新编入索引的分区资源的数量,jsonPayload.lastUpdated
是患者资源更新的时间戳。如果操作刚刚开始,则 jsonPayload.state="STATE_STARTED"
和 jsonPayload.affectedResources
将不存在。
约束和限制
本部分介绍 FHIR R4 的限制条件和限制,但相同的限制条件和限制适用于 FHIR STU3。
类型 | 限制条件和限额 |
---|---|
单个同意资源 |
|
执行模式 |
|
X-Consent-Scope |
|
支持的方法 |
|
性能 |
|
最佳实践
以下部分介绍使用 FHIR 访问权限控制时的最佳实践。
一般最佳实践
请勿import FHIR 资源并并行调用
ApplyConsents
或ApplyAdminConsents
,我们建议您先导入 FHIR 资源,然后再调用ApplyConsents
或ApplyAdminConsents
。但是,如果要导入的资源不包含任何“患者”或“同意”资源,则强制执行模型不会受到影响,并且无需处理同意声明或管理政策。请勿创建自定义搜索并并行调用
ApplyConsents
。我们建议您逐个更新。如果您的工作流需要对不相交的
PatientScope
调用多个ApplyConsents
,则可以并行调用它们。ApplyAdminConsents
可以与任意数量的ApplyConsents
并行运行,但不能与另一个ApplyAdminConsents
并行运行。设置代理时,请对 IAM 服务帐号施加只读权限,以避免将一位患者的数据写入另一位患者的记录。
创建或更新记录时,请勿使用意见征求代理。
验证所有写入请求,以防止跨患者数据发生意外修改。
强制执行级联同意时,必须先导入分区基础资源,然后导入其余的分区资源。或者,所有分区资源都可以封装在单个 bundle 中,并使用
fhir.executeBundle
进行提取。
删除患者资源
删除患者资源时,如果您还想移除该患者的同意强制执行(尤其是当 FhirStore.disableReferentialIntegrity
为 true 时),我们建议您遵循以下操作顺序:
删除属于患者资源的所有同意资源。
使用
PatientScope
过滤条件调用ApplyConsents
。
设置现有存储区以实现同意访问
如需设置现有存储区以实现同意访问,请完成以下步骤:
使用
UpdateFhirStore
将具有同意强制执行version
的ConsentConfig
设置为V1
,并将accessEnforced
设置为false
。curl -X PATCH \ -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \ -H "Content-Type: application/json" \ --data "{ 'consentConfig': { 'version': 'V1', 'accessEnforced': false } }" "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID?update_mask=consentConfig"
处理患者同意声明或管理政策
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"
ApplyAdminConsents
适用于管理员政策和管理员级联政策。
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"
将
consentConfig.accessEnforced
设置为true
。curl -X PATCH \ -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \ -H "Content-Type: application/json" \ --data "{ 'consentConfig': { 'accessEnforced': true } }" "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID?update_mask=consentConfig.accessEnforced"
运行 ApplyConsents 或 ApplyAdminConsents 的频率
未设置
ConsentConfig
字段时:首次创建 FHIR 存储区时和清除ConsentConfig
字段时,ConsentConfig
字段都会取消设置。取消设置ConsentConfig
字段后,您必须重复设置存储区以获取同意访问权限,然后再发出同意感知请求,以避免评估已过期的同意强制执行政策。强制执行模型发生变化时:创建、更新或删除同意资源时,强制执行模型会发生变化。在这种情况下,您必须调用
ApplyConsents
或ApplyAdminConsents
,才能使这些更改生效。如果您可以使用同意更改来跟踪患者,我们建议您使用
PatientScope
过滤条件以避免重新处理整个存储区。此过滤器有助于立即刷新对一小部分患者的执行。您还可以使用
TimeRange
过滤器定期运行ApplyConsents
。当更新不重要时,此过滤器非常有用。 例如,以下请求刷新了在世界协调时间 (UTC) 2022 年 9 月 20 日上午 0 点到 2022 年 9 月 21 日凌晨 0 点之间更改意见时强制执行的刷新操作。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"