Cloud Healthcare API の FHIR リソースへのアクセスを制御する

このページでは、FHIR 同意リソースを使用して、Cloud Healthcare API での FHIR ストアのデータアクセスを判断する方法について説明します。

同意の適用によって FHIR を構成するには、次の手順を行います。

  1. FHIR ストアをまだ作成していない場合は、作成します。

  2. 同意の適用を有効にするには、次の FHIR ストアの ConsentConfig パラメータを設定します。

    • version: FHIR ストアで使用されている同意の適用バージョンを指定します。この値は、CreateFhirStore または UpdateFhirStore で 1 回だけ設定できます。設定後は、ApplyConsents または ApplyAdminConsents を呼び出してバージョンを変更する必要があります。

    • access_enforced: true に設定すると、FHIR リソースにアクセスする際に、指定した同意ヘッダーが消費者から提供された同意ディレクティブと照合されます。

    • consent_header_handling: PERMIT_EMPTY_SCOPE(デフォルト)に設定すると、サーバーは X-Consent-Scope ヘッダーがない(または空の)リクエストを許可します。REQUIRED_ON_READaccess_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': true
      }
    }" "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 を使用して 同意の適用あり versionV1 として ConsentConfig を設定し、accessEnforcedtrue に設定します。

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

ポリシーは、同意リソースで表されます。リソース フィールドの目的と使用方法については、データモデルのドキュメントをご覧ください。

以下は、この特定の例で作成できるすべてのリソースの例です。

FHIR リソースを作成する

次のサンプルは、[FHIR バンドル](/healthcare-api/docs/how-tos/fhir-bundles) を実行して次のリソースを入力する方法を示しています。

  • Jeffrey Brown という名前の従事者リソース
  • Darcy Smith という名前の患者リソース
  • Happy Hospital が収集した Dancy(LOINC718-7)のヘモグロビン測定値を表す Observation リソース。
  • Darcy の血糖測定値を示す Observation リソース(LOINC15074-8
  • アプリケーション App/123 を使用して Happy Hospital が収集したデータへのアクセスを Jeffrey Brown に許可することについての Darcy の同意
  • 緊急時対応のために Jeffrey Brown が自分のデータのいずれかにアクセスできることについての Darcy の同意(ETREAT
  • アプリケーション App/golden を使用して生物医学研究(BIORCH)を行う際に、Jeffrey Brown がすべてのデータにアクセスすることに関する Happy Hospital からの同意

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

次のような 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"
      }
    ],
    "securityLabel": [
      {
        "system": "http://terminology.hl7.org/CodeSystem/v3-Confidentiality",
        "code": "R"
      },
      {
        "system": "http://terminology.hl7.org/CodeSystem/v3-ActCode",
        "code": "PSY"
      }
    ]
  }
}

上記の例は、TREAT で表される定期的な治療の提供を目的として、患者 f001 がプラクティショナー f002 に権限を付与する患者の同意リソースを表しています。この医者は、位置情報 iso3166-1/CA から取得されています。この同意リソースは、データが次の条件をすべて満たした場合に、医者が患者データにアクセスすることを許可します。

  • これは ID が Encounter/e001Encounter 型です。
  • 送信元 http://somesystem.example.org/foo から取得されます。
  • タグに関する次の条件のうち少なくとも 1 つを満たしている必要があります。Meta.tagsystem フィールドと code フィールドを設定することで、リソースにタグを付けることができます。
    • タグあり(system = http://terminology.hl7.org/CodeSystem/common-tagscode = actionable
    • 両方のタグあり(system = http://example.com/custom-tagscode = archivedおよびsystem = http://example.com/custom-tagscode = insensitive
  • 次のセキュリティ ラベルが少なくとも 1 つ含まれている
    • system = http://terminology.hl7.org/CodeSystem/v3-Confidentialitycode は、RNMLU のいずれかです。
    • system = http://terminology.hl7.org/CodeSystem/v3-ActCodecode = 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"
      }
    ],
    "securityLabel": [
      {
        "system": "http://terminology.hl7.org/CodeSystem/v3-Confidentiality",
        "code": "R"
      },
      {
        "system": "http://terminology.hl7.org/CodeSystem/v3-ActCode",
        "code": "PSY"
      }
    ]
  }
}

上記の例は、TREAT で表される定期的な治療の提供を目的として、管理ポリシーの同意リソースが医者 f002 に権限を付与していることを示しています。この医者は、位置情報 iso3166-1/CA から取得されています。この同意リソースは、データが次の条件をすべて満たした場合に、医者が患者データにアクセスすることを許可します。

  • これは ID が Encounter/e001Encounter 型です。
  • 送信元 http://somesystem.example.org/foo から取得されます。
  • タグに関する次の条件のうち少なくとも 1 つを満たしてます。
    • タグあり(system = http://terminology.hl7.org/CodeSystem/common-tagscode = actionable
    • 両方のタグあり(system = http://example.com/custom-tagscode = archivedおよびsystem = http://example.com/custom-tagscode = insensitive
  • 次のセキュリティ ラベルが少なくとも 1 つ含まれている
    • system = http://terminology.hl7.org/CodeSystem/v3-Confidentialitycode は、RNMLU のいずれかです。
    • system = http://terminology.hl7.org/CodeSystem/v3-ActCodecode = 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"
        }
      }
    ]
  }
}

上記の例は、TREAT で表される定期的な治療の提供を目的として、医者 f002 に権限を付与する管理カスケード ポリシーの同意リソースを表します。この医者は、位置情報 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 つの管理ポリシー)の同意アクセスを更新したことを示しています。

FHIR ストアに格納されている同意の適用は、ApplyConsents(患者の同意の場合)または ApplyAdminConsents(管理ポリシーと管理カスケード ポリシーの場合)が呼び出され、正常に完了するまで有効になりません。ApplyConsents または ApplyAdminConsents の実行後に同意を追加、変更、削除する場合は、それらの同意が適用モデルに含まれるように、再度同意を実行する必要があります。

FHIR リソースは非同期でインデックスに登録されるため、ApplyConsents または ApplyAdminConsents が完了してから検索結果に適用モデルが反映されるまでに、わずかな遅延が発生する場合があります。この遅延は、検索リクエストに対してのみ発生します。

FHIR ストアで同意の適用を初めて設定する場合は、ApplyConsents または ApplyAdminConsents の長時間実行オペレーションが完了するまで待ってから、同意に基づくリクエストを行います。

患者のサブセットに対して ApplyConsents を呼び出すには、次のフィルタを使用します。

  • PatientScope: 最大 10,000 人の患者の患者 ID リストに対して ApplyConsents を実行する

  • TimeRange: 特定の期間に同意リソースが更新された患者リソース ID のリストに対して ApplyConsent を実行する

ApplyAdminConsents を呼び出すには、適用するすべてのポリシーの完全なリストを指定する必要があります(増分リストではなく)。その結果、ストアのすべての管理ポリシーから空のリストは適用されません。FHIR ストアがバージョニングの場合、各ポリシーはリソースのバージョン名にする必要があり、それ以外の場合はリソース名にする必要があります。

operations.get を使用して、オペレーションの ProgressCounter を取得できます。完了すると、Operation.response に含まれる ApplyConsentsResponse が追加されます。 ProgressCounterApplyConsentsResponseApplyAdminConsentsResponse のカウンタを次の表に示します。

ProgressCounter ApplyConsentsResponse または ApplyAdminConsentsResponse 説明
success consentApplySuccess オペレーションが正常に処理された同意リソースの数。
failure consentApplyFailure サポートされていない、または無効な同意リソースの数。Cloud Logging でエラーログを表示するか、validateOnlyfalse の場合は、 CheckConsentEnforcementStatus または CheckPatientConsentEnforcementStatus を使用して同意の適用ステータスを確認し、エラーの詳細を取得します。
secondarySuccess affectedResources validateOnlyfalse の場合は、同意の変更の効果で正常に再インデックス付けされた FHIR リソースの数を表します。
secondaryFailure failedResources validateOnlyfalse の場合は、同意は変更されたが、再インデックス付けできなかった FHIR リソースの数を表します。これは、同意コンテキストによる検索に影響する可能性がありますが、他の方法には影響しません。エラーの詳細を確認するには、Cloud Logging でエラーログを表示します。

FHIR 同意リソースが処理されると、次の API を使用して、単一の同意または患者のすべての同意に関する適用ステータスを確認できます。

  • CheckConsentEnforcementStatus: 次のパラメータを一覧表示する ParametersSTU3R4)リソースを返します。

    • id: 同意リソースのリソース ID を表します。

    • lastUpdated: 同意が最後に適用された時刻を表します。

    • versionId: 同意の適用に使用されるバージョン ID を表します

    • consent-enforcement-status: 同意の適用のステータスを表します。

  • CheckPatientConsentEnforcementStatus: 1 人の患者のすべての同意に関する適用ステータスで構成される ParametersSTU3R4)リソースの BundleSTU3R4

管理ポリシーの場合、CheckConsentEnforcementStatus は単一の同意管理ポリシーの適用ステータスを確認する場合にのみ使用できます。または、fhirStores.get を使用して、ストアに適用されているすべての有効な管理ポリシーを確認することもできます。

consent-enforcement-status は、次のいずれかの値になります。

  • OFF: 同意リソースが処理されていない新しい同意リソースのデフォルト適用ステータスを表します。

  • ENFORCEABLE: 同意リソースが正常に処理された状態。

  • INACTIVE: 同意リソースが無視される非アクティブな状態。

  • UNSUPPORTED: FHIR 仕様に準拠しているが適用できない同意リソースの状態。これは、現在の機能サポートレベルで FHIR 同意の適用が限定されているためです。

  • ENFORCEMENT_LIMIT_EXCEEDED: FHIR 同意リソースの形式とリソースのサポートレベルにエラーはありませんが、次の条件のうち 1 つ以上に該当する。

    • 患者には多数の同意リソースがあります。

    • すべてのアクティブな同意全体で同意ディレクティブのサイズが、FHIR サーバーが適用する同意ディレクティブの最大許容サイズを超えています。

Cloud Healthcare API では、actorpurposeenvironment をクエリ パラメータとして指定した FHIR ストアでの同意リソースの検索がサポートされています。レスポンスには、同意されたリソースのみが含まれます。

  1. 信頼できるアプリケーション App/123 を使用してプラクティショナー Jeffrey Brown(Practitioner/12942879-f89f-41ae-aa80-0b911b649833 によって識別)が status=final ですべての所見を検索します。
  2. curl -X GET \
        -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
        -H "X-Consent-Scope: actor/Practitioner/12942879-f89f-41ae-aa80-0b911b649833 env/App/123" \
        "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation?status=final"

    次のような 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"
    }
    
  3. アプリケーション App/123 を使用してプラクティショナー Jeffrey Brown(Practitioner/12942879-f89f-41ae-aa80-0b911b649833 によって識別)は、患者 Dancy のすべての所見を検索します。
  4. curl -X GET \
        -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
        -H "X-Consent-Scope: actor/Practitioner/12942879-f89f-41ae-aa80-0b911b649833 env/App/123" \
        "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation?subject:Patient.name=Darcy"

    次のような 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 では、患者 Dancy リソース(Patient/3c6aa096-c054-4c22-b2b4-1e4a4d203de2 によって識別)へのアクセスが拒否されるため、FHIR サーバーは、患者が存在しないかのように、患者からの測定値を返しません。

  5. アプリケーション App/123 を使用してプラクティショナー Jeffrey Brown(Practitioner/12942879-f89f-41ae-aa80-0b911b649833 によって識別)は、緊急治療目的のために患者 Darcy のすべての所見を検索します。
  6. curl -X GET \
        -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
        -H "X-Consent-Scope: actor/Practitioner/12942879-f89f-41ae-aa80-0b911b649833 purp/v3/ETREAT env/App/123" \
        "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation?subject:Patient.name=Darcy"

    次のような 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"
    }
    
  7. プラクティショナー Jeffrey Brown(Practitioner/12942879-f89f-41ae-aa80-0b911b649833 によって識別)は、status=final による所見を 2 つの目的である治療研究のために検索します。
  8. curl -X GET \
        -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
        -H "X-Consent-Scope: actor/Practitioner/12942879-f89f-41ae-aa80-0b911b649833 purp/v3/TREAT purp/v3/HRESCH" \
        "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation?status=final"

    次のような 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」から不要な目的を削除する必要があります。

  9. 病院の IT 管理者が bypass を使用して、病院内のすべてのプラクティショナーを検索します。
  10. curl -X GET \
        -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
        -H "X-Consent-Scope: bypass actor/Admin/ef0592c9-6724-467e-878d-f879e537cd15 env/net/HappyNet" \
        "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Practitioner?"

    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 は、クエリ パラメータとして actorpurposeenvironment を持つ特定の FHIR ストアでの FHIR リソースの取得をサポートしています。レスポンスには、同意されたリソースのみが含まれます。

  1. アプリケーション App/123 を使用するプラクティショナーの Jeffrey Brown(Practitioner/12942879-f89f-41ae-aa80-0b911b649833 によって識別)は、患者のヘモグロビン測定値(この例では Observation/7473784b-46a8-470c-b9a6-fe38a01025aa)を読み取ります。
  2. curl -X GET \
        -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
        -H "X-Consent-Scope: actor/Practitioner/12942879-f89f-41ae-aa80-0b911b649833 env/App/123" \
        "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation/7473784b-46a8-470c-b9a6-fe38a01025aa"

    リクエスト送信者に同意が得られたため、Observation リソースのコンテンツが返されます。

    {
      "code": {
        "coding": [
          {
            "code": "718-7",
            "display": "Hemoglobin [Mass/volume] in Blood",
            "system": "http://loinc.org"
          }
        ]
      },
      "effectivePeriod": {
        "start": "2021-12-10T05:30:10+01:00"
      },
      "id": "7473784b-46a8-470c-b9a6-fe38a01025aa",
      "issued": "2021-12-10T13:30:10+01:00",
      "meta": {
        "lastUpdated": "2022-09-01T17:31:40.423469+00:00",
        "source": "http://example.com/HappyHospital",
        "versionId": "VERSION_ID"
      },
      "resourceType": "Observation",
      "status": "final",
      "subject": {
        "reference": "Patient/3c6aa096-c054-4c22-b2b4-1e4a4d203de2"
      },
      "valueQuantity": {
        "code": "g/dL",
        "system": "http://unitsofmeasure.org",
        "unit": "g/dl",
        "value": 7.2
      }
    }
    
  3. 不明なアプリケーション App/unknown を使用してプラクティショナー Jeffrey Brown(Practitioner/12942879-f89f-41ae-aa80-0b911b649833 によって識別されたもの)は、患者のヘモグロビン測定値(この例では Observation/7473784b-46a8-470c-b9a6-fe38a01025aa)を読み取ります。
  4. curl -X GET \
      -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
      -H "X-Consent-Scope: actor/Practitioner/12942879-f89f-41ae-aa80-0b911b649833 env/App/unknown" \
      "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation/7473784b-46a8-470c-b9a6-fe38a01025aa"

    リクエスト送信者の境界アクセス(「App/unknown」)は患者の同意によって許可されていないため、リクエストは拒否されます。

    {
      "issue": [
        {
          "code": "security",
          "details": {
            "text": "permission_denied"
          },
          "diagnostics": "Consent access denied or the resource being accessed does not exist",
          "severity": "error"
        }
      ],
      "resourceType": "OperationOutcome"
    }
    
  5. アプリケーション App/golden を使用して生物医学研究を行う医者の Jeffrey Brown(Practitioner/12942879-f89f-41ae-aa80-0b911b649833 によって識別)は、Darcy の生年月日(この例では Patient/3c6aa096-c054-4c22-b2b4-1e4a4d203de2)を読み取ります。
  6. curl -X GET \
      -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
      -H "X-Consent-Scope: actor/Practitioner/12942879-f89f-41ae-aa80-0b911b649833 purp/v3/BIORCH env/App/golden" \
      "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Patient/3c6aa096-c054-4c22-b2b4-1e4a4d203de2"

    リクエスト送信者が同意を得られたため、患者リソースのコンテンツが返されます。

    {
      "active": true,
      "birthDate": "1990-01-01",
      "gender": "female",
      "id": "3c6aa096-c054-4c22-b2b4-1e4a4d203de2",
      "meta": {
        "lastUpdated": "2022-09-01T17:31:40.423469+00:00",
        "versionId": "VERSION_ID",
        "tag": [{
          "system": "http://terminology.hl7.org/CodeSystem/common-tags",
          "code": "employee"
        }]
      },
      "name": [
        {
          "family": "Smith",
          "given": [
            "Darcy"
          ],
          "use": "official"
        }
      ],
      "resourceType": "Patient"
    }
    
  7. プラクティショナーの Jeffrey Brown(Practitioner/12942879-f89f-41ae-aa80-0b911b649833 によって識別)は、「ブレークグラス」プロトコルを使用して、患者の記録への緊急承認をリクエストしています(この例では Observation/7473784b-46a8-470c-b9a6-fe38a01025aa)。
  8. curl -X GET \
      -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
      -H "X-Consent-Scope: btg actor/Practitioner/12942879-f89f-41ae-aa80-0b911b649833" \
      "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation/7473784b-46a8-470c-b9a6-fe38a01025aa"

    同意の認可方法が 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 リクエストには、actorpurp の一つ、env の一つの、最大 3 つのエントリを含めることができます。

特別なスコープの場合、FHIR リクエストは btgbypass のいずれかをサポートします。

信頼できるアプリケーションに 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 の管理と権限モデルの一部として同意に基づくアクセス トークンを含めることができます。

  • SMART on FHIR のサポート用のトークン機能もサポートします。

SMARTProxy を介して Cloud Healthcare API からデータを取得するリクエストを行うと、次のようになります。

  1. SMARTProxy は、同意に基づくトークンを含むクライアントからのリクエストを受け入れます。

  2. SMARTProxy は、所有する JWT 認可サーバーを介して同意に基づくトークンを検証します。

  3. SMARTProxy が同意に基づくトークンからスコープを読み取り、HTTP ヘッダーを介して Cloud Healthcare API に渡します。

  4. Cloud Healthcare API は、ヘッダーを受信し、リクエストに同意ディレクティブを適用するために検証します。その後、Cloud Healthcare API は SMARTProxy を介してクライアントにレスポンスを返します。

Google Cloud サービス アカウントを構成する

プロキシに含めることができる Google Cloud サービス アカウントは 1 つだけです。複数のクライアントが同じプロキシを使用する場合、クライアントは同じサービス アカウントを使用します。サービス アカウントを複数のクライアントと共有する場合は、次の点に注意してください。

たとえば、認証に Google アカウントを使用して Cloud Healthcare API を直接呼び出した場合、Cloud Audit Logs はメールアドレスをプリンシパル メールアドレスとして記録します。プロキシを使用して Cloud Healthcare API を呼び出す場合、プロキシは独自のサービス アカウントを使用します。プリンシパル メールアドレスは、そのサービス アカウントのメールアドレスであり、元のアカウントは定義されません。

監査ログ

アクセス リクエストがあった場合、またはリソースのアクセス適用が変更されたときに監査ログが生成されます。

アクセス監査ログ

FHIR ストアで監査ログが有効になっている場合、Cloud Logging で使用可能な監査ログには consentMode メタデータ フィールドが含まれています。consentMode は次のいずれかの値になります。

  • off: FHIR ストアの構成では、consentConfig.accessEnforcedfalse に設定され、同意に基づくリクエストは許可されません。

  • emptyScope: FHIR ストアに consentConfig.accessEnforcedtrue に設定されていますが、同意スコープのヘッダーが含まれていませんでした。その結果、同意は適用されませんでした。

  • enforced: FHIR ストアで consentConfig.accessEnforcedtrue に設定され、同意スコープのヘッダーが存在していました。その結果、同意が評価され、リクエストに適用されます。

  • btg: FHIR リクエストで、同意スコープのヘッダーに btg が指定された。そのため、同意のチェックがスキップされました。このリクエストは緊急時に、事後の監査レビューを受ける場合のみに使用することを想定しています。

  • bypass: FHIR リクエストの同意スコープ ヘッダーに bypass しか指定されていません。そのため、同意のチェックがスキップされました。このリクエストは、信頼できるワークフロー(エンドユーザーではなく、管理者や信頼できるアプリケーションなど)によって使用されることを想定しており、この監査ログは、データ ガバナンス チェックに使用される btg とは異なります。

必要に応じて、access_determination_log_configVERBOSE に設定して、リクエストが承認または拒否される理由の詳細を記録できます。

アクセス適用変更の監査ログ

コンパートメント ベース リソースが変更される場合(たとえば患者の employee タグを削除する場合)には、変更されたリソースとそのコンパートメントのアクセス制御は、管理カスケード ポリシーのため、変更される場合があります。これにより、すべてのコンパートメント リソースの再インデックス登録がトリガーされます。コンパートメント ベース リソースの更新ごとの再インデックス処理の状況は、Cloud Logging でフィルタ jsonPayload.@type="type.googleapis.com/google.cloud.healthcare.logging.FhirConsentCascadeLogEntry" を使用して追跡できます。

カスケード再インデックスの進行状況のログの例

{
  "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 にも適用されます。

Type 制約と上限
単一同意リソース
  • 1 つの Consent.provision のみがサポートされます。複数のプロビジョニングやネストされたプロビジョニングはサポートされません。
  • 1 Consent.provision.actor 以上、25 以下:
    • Consent.provision.actor.rolehttp://terminology.hl7.org/CodeSystem/v3-RoleCode でなければなりません。
    • Consent.provision.actor.code は、GRANTEE または HPOWATT にする必要があります。
  • 1 Consent.provision.purpose以下:
    • Consent.provision.purpose.systemhttp://terminology.hl7.org/CodeSystem/v3-ActReason でなければなりません。
    • Consent.provision.purpose.code は空ではなく 13 文字以下です。
  • 1 以下environment:
    • Consent.provision.extension.urlhttps://g.co/fhir/medicalrecords/Environment でなければなりません。
    • システムとコードを組み合わせた長さは 15 未満にする必要があります。
  • リソースタイプでフィルタする場合、Consent.provision.class.systemhttp://hl7.org/fhir/resource-types にする必要があります。
  • データソースでフィルタする場合は、Consent.provision.extension.urlhttps://g.co/fhir/medicalrecords/DataSource にする必要があります。
  • データタグでフィルタする場合、Consent.provision.extension.urlhttps://g.co/fhir/medicalrecords/DataTag にする必要があります。
    • データタグは、指定された(論理的に解釈された)すべてのタグが付いたリソースに一致するポリシーを記述するために、1 レベルまでネストされた複雑な拡張機能である場合があります。
    • ネストされたタグは 5 個までサポートされます。
  • この行で異なる属性を記述しない限り、すべての繰り返し属性に対して最大 100 個の値。
適用モデル
  • 各患者には、一度に最大 200 個の active 同意リソースを適用できます。
  • 各ストアには、一度に最大 200 個の active 管理ポリシーを適用できます。
  • 特定の患者に対するすべての有効な同意全体で、すべての同意ディレクティブのセットを使用する特別でコンパクトなフォーマットは、設定されたしきい値のサイズを超えない必要があります。通常、リソース文字列がかなり長い場合を除き、数千の同意ディレクティブをエンコードするのに十分な容量が確保されます。例:
    • 一意のデータソースとデータタグに対する数百の同意が、それぞれかなりの容量を消費しています。
    • 多数の有効な同意にわたって 3,000 個の一意の Consent.provision.data.reference リソース識別子エントリを持つ 1 人の患者が、それぞれ固有の Consent.provision.actor を指定する場合、データ参照制約を指定しないプロビジョニングや、同じアクター参照文字列の多くを含むプロビジョニングよりも積極的にスペースを使用します。
  • それぞれのリソースは、該当するすべての同意から最大 1,000 個の同意ディレクティブを含めることができます。
X-Consent-Scope
  • 1~3 個の actor エントリ。
  • 最大 1 つの purp エントリ:
    • purp エントリは、system/code の形式である必要があります(v3http://terminology.hl7.org/CodeSystem/v3-ActReason の登録済みシステムです)。
    • コードの長さは 13 文字未満でなければなりません。
  • 最大 1 つの env エントリ:
    • env エントリは、system/code の形式にする必要があります。
    • システムとコードを組み合わせた長さは 15 未満にする必要があります。
  • btg には少なくとも 1 つの actor エントリが必要です。
  • bypass には少なくとも 1 つの actor エントリと 1 つの env エントリが必要です。
サポートされるメソッド
パフォーマンス
  • ApplyConsentsApplyAdminConsentsImportResources と同じように、またはより良好にスケーリングされます。
  • 同意に基づくリクエストについて:
    • Google の同意モデルは、CRUD オペレーション(多数のリソースや多数の患者にわたる検索など)を実施するために最適化されています。
    • 個々のリソースの読み取りはリクエストのレイテンシにわずかな影響を与える可能性がありますが、検索のパフォーマンスは、基本クエリと、検索中に有効になる、より多くのアクセサー基準につながる同意スコープの数によって異なります。
    • さまざまな代表的な FHIR リクエスト パラメータに対して独自のパフォーマンス テストを実行して、データの特性(FHIR ストア内の特定の検索リソースタイプのリソースの数など)に基づいて、ユースケースのパフォーマンス特性を判断することをおすすめします。
    • このソリューションでは、同意リソースを含むすべてのリソースの取り込みと更新が軽量のまま維持され、取り込み中のスループットやその他の形式の書き込みトラフィックが最小限の影響で継続されます。

おすすめの方法

以下のセクションでは、FHIR アクセス制御を使用する場合のベスト プラクティスについて説明します。

一般的なおすすめの方法

  • FHIR リソースのインポートと、ApplyConsentsApplyAdminConsents の呼び出しを並行して行わないでください。最初に FHIR リソースをインポートしてから、ApplyConsents または ApplyAdminConsents を呼び出すことをおすすめします。ただし、インポートするリソースに患者リソースまたは同意リソースが含まれていない場合は、適用モデルは影響を受けず、同意または管理ポリシーの処理は必要ありません。

  • カスタム検索の作成と、ApplyConsents の呼び出しを並行して行わないでください。1 つずつ順番に行うことをおすすめします。

  • ワークフローが、互いに素な PatientScope に対して複数の ApplyConsents を呼び出す必要がある場合は、並列で呼び出すことができます。

  • ApplyAdminConsents は任意の数の ApplyConsents と並行して実行できますが、別の ApplyAdminConsents とは同時に実行できません。

  • プロキシを設定する際は、IAM サービス アカウントを読み取り専用権限に制限して、1 人の患者のデータを別の患者のレコードに書き込まないようにします。

  • レコードを作成または更新するときに同意プロキシを使用しないでください。

  • すべての書き込みリクエストを検証して、患者間データが予期せず変更されないようにします。

  • カスケード同意が適用される場合、まずコンパートメント ベース リソースをインポートし、次に残りのコンパートメント リソースをインポートする必要があります。または、すべてのコンパートメント リソースを 1 つのバンドル内でラップし、fhir.executeBundle を使用して取り込むことができます。

患者リソースを削除する

患者リソースを削除するときに、その患者の同意の適用も削除したい場合は(特に FhirStore.disableReferentialIntegrity が true の場合)、次のオペレーションを行うことをおすすめします。

  1. Patient リソースに属する同意リソースをすべて削除します。

  2. PatientScope フィルタを使用して ApplyConsents を呼び出します。

同意ストアの既存のストアを設定するには、次の手順を行います。

  1. UpdateFhirStore を使用して、同意の適用 version がある ConsentConfigV1 として設定し、accessEnforcedtrue に設定します。

    curl -X PATCH \
        -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
        -H "Content-Type: application/json" \
        --data "{
          'consentConfig': {
            'version': 'V1',
            'accessEnforced': true
          }
        }" "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID?update_mask=consentConfig"
  2. 患者の同意または管理ポリシーを処理する

    1. 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"
    1. 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"

ApplyConsents または ApplyAdminConsents を実行する頻度

  • ConsentConfig フィールドが未設定の場合: ConsentConfig フィールドは、FHIR ストアが最初に作成されたときと、ConsentConfig フィールドがクリアされたときの両方で設定解除されます。ConsentConfig フィールドを設定解除したら、古い同意適用ポリシーを評価しないように、同意を確認するリクエストを行う前に、同意アクセス用のストアの設定を繰り返す必要があります。

  • 適用モデルが変更された場合: 同意リソースが作成、更新、または削除されると、適用モデルが変更されます。このような場合、これらの変更を有効にするには、ApplyConsents または ApplyAdminConsents を呼び出す必要があります。

    • 同意の変更がある患者を追跡できる場合は、PatientScope フィルタを使用してストア全体が再処理されないようにすることをおすすめします。このフィルタは、少数の患者の適用を直ちに更新するのに便利です。

    • TimeRange フィルタを使用して、ApplyConsents を定期的に実行することもできます。このフィルタは、即時更新が重要でない場合に役立ちます。たとえば、以下のリクエストは、UTC 0AM 2022-09-20 と UTC 0AM 2022-09-21 の間に適用された同意の変更について更新します。

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

次のステップ