Skip to main content

kestrel-feature-healthcare

Patient-owned sovereign health records (FHIR/CCDA) for Kestrel Sovereign.

An agent holds the owner's clinical records as part of its sovereign memory. This is a reusable framework capability — a sibling package alongside kestrel-feature-visual / -reflection / -observability — not a host-product feature. Any healthcare host on Kestrel consumes it.

Status

Multi-phase epic tracked in KestrelSovereignAI/kestrel-sovereign (#1274). All phases shipped:

  • Phase A — typed FHIR R4B resource store, owner-DID-scoped, PHI encrypted at rest, audited reads.
  • Phase B — CCDA document storage + header extraction (lxml), owner-DID-scoped, encrypted at rest, sharing one append-only PHI access log with Phase A.
  • Phase C — pure-Python CCDA → FHIR R4B mapper (no third-party converter): Patient + Allergies / Medications / Problems / Results / Vital Signs / Immunizations / Procedures. Normalized resources land in the Phase A FHIR store, owner-scoped and audited.
  • Phase D1 — owner-consent-gated export/import bundle (HealthcareBundle + HealthcareExporter + HealthcareImporter). Composes the DataAccessGrant primitive from kestrel-sovereign (#1273).
  • Phase D2 — owner-controlled in-process read-access surface (AccessPolicy + AccessPolicyStore + ReadDenied). Per-reader, per-resource-type, expirable, revocable.
  • D-CAR-native — sovereignty-CAR sidecar (HealthcareAssetCollector
    • HealthcareAssetRestorer). The same bundle bytes ride inside a kestrel-sovereign CAR via the AssetRestorer protocol.
  • Phase D3 — HIPAA Safe Harbor de-identification helpers (Deidentifier + deidentify_bundle). All 18 §164.514(b)(2) identifiers, configurable date-shift strategies, per-patient stable shifts that preserve clinical intervals.

PHI handling (required)

Health records are PHI. The stores are fail-closed: resource bodies are encrypted at rest with AES-256-GCM under a per-owner key HKDF-derived from the host master key, and no operation will store or return PHI in the clear. The host master key must be configured (KESTREL_DATA_KEY); without it the FHIR tools fail with a clear error rather than degrading to plaintext. Every owner read/write/query — including denials — is recorded in an append-only access log keyed by (owner_did, reader_id?). Only the resource body is encrypted — resource_type and fhir_id remain queryable metadata.

Installation

uv pip install kestrel-feature-healthcare

The package registers HealthcareFeature through the kestrel_sovereign.features entry point group; it auto-discovers when installed alongside kestrel-sovereign>=0.14.1.

Consuming the package

Initialize the stores against a DatabaseBackend (the same concrete the kestrel-sovereign host hands features):

from kestrel_feature_healthcare import (
    FhirResourceStore, CcdaDocumentStore, PhiAccessLog,
)
from kestrel_sovereign.storage.db import get_backend

backend = await get_backend({"backend": "sqlite", "db_path": "kestrel.db"})
log = PhiAccessLog(backend)
fhir = FhirResourceStore(backend, log=log)
ccda = CcdaDocumentStore(backend, log=log)
await fhir.initialize()
await ccda.initialize()

Consent-gated cross-agent transport (D1)

The patient mints an owner-signed DataAccessGrant; the exporter builds a signed HealthcareBundle; the receiving agent verifies both before any local-store mutation.

from kestrel_feature_healthcare import HealthcareExporter, HealthcareImporter
from kestrel_sovereign.identity.access_grant import (
    DataAccessGrant, sign_owner, finalize,
)

grant = finalize(sign_owner(DataAccessGrant(
    owner_did=patient_did, source_did=source_agent_did,
    host_did=receiving_agent_did, issued_at="2026-05-29T00:00:00+00:00",
), [(patient_keypair, patient_kid)]))

bundle = await HealthcareExporter(fhir_src, ccda_src).build_bundle(
    owner_did=patient_did,
    source_did=source_agent_did,
    source_verification_methods=source_agent_vms,
    source_keypairs=[(source_keypair, source_kid)],
)

result = await HealthcareImporter(fhir_dst, ccda_dst).import_bundle(
    bundle.to_bytes(),
    grant=grant, host_did=receiving_agent_did,
)

Read-access policy (D2)

Owner mints policies in-process; readers identify themselves to the store; out-of-scope reads raise ReadDenied (distinct from not-found, so denied reads can't probe for existence).

from kestrel_feature_healthcare import AccessPolicyStore, ReadDenied

policy = AccessPolicyStore(backend, log=log)
await policy.initialize()
await policy.grant(patient_did, "staff:nurse", ["Patient", "Observation"])

p = await fhir.get_resource(
    patient_did, "Patient", "pat-1",
    reader_id="staff:nurse", access_policy=policy,
)
# get_resource(...) of MedicationRequest raises ReadDenied for this reader.

Sovereignty-CAR-native transport (D-CAR-native)

Same bundle, transported inside a kestrel-sovereign CAR via the AssetRestorer protocol:

from kestrel_feature_healthcare import (
    HealthcareAssetCollector, HealthcareAssetRestorer,
)
from kestrel_sovereign.storage.sovereign_adapter import SovereignStorageAdapter

# Source side
adapter_src = SovereignStorageAdapter(storage_src.db, user_secret="…")
collector = HealthcareAssetCollector(
    HealthcareExporter(fhir_src, ccda_src),
    source_did=source_agent_did,
    source_verification_methods=source_agent_vms,
    source_keypairs=[(source_keypair, source_kid)],
    owners=[patient_did],
)
cid = await adapter_src.export_agent(
    source_agent_did, asset_collector=collector,
)

# Receive side
adapter_dst = SovereignStorageAdapter(storage_dst.db, user_secret="…")
restorer = HealthcareAssetRestorer(fhir_dst, ccda_dst)
result = await adapter_dst.import_agent(
    cid,
    grant=grant, host_did=receiving_agent_did,
    asset_restorers=[restorer],
)

HIPAA Safe Harbor de-identification (D3)

from kestrel_feature_healthcare import deidentify_bundle, DeidentifierConfig

deid = deidentify_bundle(
    bundle,
    source_keypairs=[(source_keypair, source_kid)],
    config=DeidentifierConfig(date_strategy="shift"),  # or "year_only" / "remove"
)
# deid.bundle is a new SIGNED bundle with all 18 Safe Harbor
# identifiers stripped/redacted. CCDA documents pass through
# untouched; deid.ccda_documents_skipped surfaces the count.

Development

uv sync --extra test
uv run --extra test pytest -q                       # fast default suite
KESTREL_HEALTHCARE_E2E=1 uv run --extra test pytest -m e2e  # opt-in cross-feature

The default pytest run skips the cross-feature e2e suite. The opt-in path exercises the full Phase A → D round-trip (seed → consent grant → bundle / CAR transport → de-id → read-access gating) on real stores in one continuous test. CI also exposes the e2e job via workflow_dispatch from the Actions tab.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

kestrel_feature_healthcare-0.8.2.tar.gz (49.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

kestrel_feature_healthcare-0.8.2-py3-none-any.whl (58.3 kB view details)

Uploaded Python 3

File details

Details for the file kestrel_feature_healthcare-0.8.2.tar.gz.

File metadata

File hashes

Hashes for kestrel_feature_healthcare-0.8.2.tar.gz
Algorithm Hash digest
SHA256 47a3eca11b66254f09afd044141f3327186485a7c5da5bf7fbe871b637415363
MD5 6df6d28e03922117abea5a827abc3862
BLAKE2b-256 d1819735c411438d418f8ba56316ba46bd48bbe60a88ebaf4464e510590f6b08

See more details on using hashes here.

Provenance

The following attestation bundles were made for kestrel_feature_healthcare-0.8.2.tar.gz:

Publisher: publish.yml on KestrelSovereignAI/kestrel-feature-healthcare

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file kestrel_feature_healthcare-0.8.2-py3-none-any.whl.

File metadata

File hashes

Hashes for kestrel_feature_healthcare-0.8.2-py3-none-any.whl
Algorithm Hash digest
SHA256 8a3998a48670f452ef2b649b0ccef1a730ab60568cdb39204ee29ad32f23816a
MD5 59a925503186b29461ed9287ce4e36c3
BLAKE2b-256 5a44792f451f97b94e2fc8771f097c481836d4499f0f5191c1f244f929d0a919

See more details on using hashes here.

Provenance

The following attestation bundles were made for kestrel_feature_healthcare-0.8.2-py3-none-any.whl:

Publisher: publish.yml on KestrelSovereignAI/kestrel-feature-healthcare

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.8.2 This release

2 files

0.8.1

2 files

0.8.0

2 files

0.7.2

2 files

0.7.1

2 files

0.7.0

2 files

0.6.0

2 files

0.5.0

2 files

0.4.0

2 files

0.3.0

2 files

0.2.0

2 files

0.1.1

2 files

0.1.0

2 files

0.0.1

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page