SMART functional conformance passes. Inferno is green functionally; HTTPS/TLS closure is the remaining SMART gate. View the roadmap

Why Ilavrita Is Not Ready for Patient Data Yet

Ilavrita Engineering · September 20, 2026

Why Ilavrita Is Not Ready for Patient Data Yet

Version: dev
Source revision: 4c36f1c8e5983943710398c2d8c1bd4ea689dbdd
Last verified: September 20, 2026
Data used in examples: synthetic only

Ilavrita can already serve a meaningful FHIR R4 surface. That does not make it ready for patient data.

Those are separate claims, and we want to keep them separate.

At the revision this post was verified against, Ilavrita's synced documentation records tested implementations for core resource interactions, declared search, version history, project isolation, authorization, audit, transaction and batch Bundles, conditional interactions, subscriptions, validation, and backup/restore.

It is also still a developer preview.

There has been no external security review. Upgrade and rollback procedures are incomplete. SMART/OAuth is not implemented. PostgreSQL and multi-node operation are later architecture goals rather than current deployment options. Several FHIR protocol areas remain deliberately unsupported.

That distinction is the operating rule for this project:

Claims stop where the tests stop.

This post explains what that means in practice, what a developer can reasonably evaluate today, and why we still tell people not to put patient data into the current build.

What Ilavrita is trying to be

Ilavrita is an open, self-hostable FHIR R4 infrastructure project.

The immediate goal is not to implement every healthcare protocol or build the largest possible platform surface. The first goal is narrower: make the FHIR behavior we do expose predictable enough that an engineer can inspect it, test it, and determine precisely where its boundary ends.

That sounds obvious until a server accepts something it does not understand.

FHIR has a wide surface. A server can support some resource types, only certain search parameters, some interactions, one representation format, or a subset of operations. A client therefore needs more than a base URL. It needs to know what the particular server actually implements.

FHIR R4 provides the CapabilityStatement resource for that purpose.

Ilavrita exposes one at:

http
GET /fhir/R4/metadata

Our rule is that this document should describe the running server rather than the product we eventually intend to build.

That distinction matters throughout the project.

A roadmap item is not a capability.

An interface in the source tree is not a capability.

A database table is not a capability.

A route that exists but has not had its behavior verified is not something we want to advertise as finished.

The relevant R4 definition is here: HL7 FHIR R4 CapabilityStatement.

What works at this revision

The synced documentation for this revision records the following as implemented.

FHIR resource interactions

For resource types declared by the server, the core single-resource interactions include:

  • create
  • read
  • update
  • delete
  • versioned read
  • instance history

The current documentation records 126 R4 resource types as declared.

A resource type being declared means more than the storage layer being technically capable of holding arbitrary JSON with a resourceType. Ilavrita intentionally separates storage capability from public FHIR capability.

That difference is important.

The public contract should describe what authorization, compartment placement, history, error handling, and other behavior can actually support.

FHIR search is implemented through both:

http
GET /fhir/R4/{resourceType}?...

and:

http
POST /fhir/R4/{resourceType}/_search

But the supported search surface is intentionally smaller than the full set of possibilities in FHIR R4.

The server maintains a registry of search parameters that it knows how to index and execute.

If a parameter is outside that supported set, the intended behavior is to refuse it rather than silently discard it.

That is a safety property, not merely a product limitation.

Imagine asking:

text
Observation?status=final

and receiving every Observation because the server ignored status.

The HTTP request technically succeeded, but the answer is wider than the question. A caller may have no way to discover that its criterion was discarded.

For Ilavrita, unsupported search behavior should be visible.

See the known limitations for the current search boundary.

Project isolation and authorization

A Project is the isolation boundary.

The project identifier is derived by the server rather than trusted from arbitrary client FHIR content, and storage operations are designed around a project-scoped key.

Authorization predicates are pushed into the query path rather than fetching a wider dataset and filtering it afterwards.

That design exists for a simple reason: once data from another project has been fetched into the wrong request path, the isolation boundary has already been weakened.

The current build also supports policy narrowing documented in the authorization design, including compartment-aware access and field restriction.

This is a control Ilavrita implements and tests.

It is not a claim that an Ilavrita deployment is HIPAA-, GDPR-, EHDS-, or otherwise legally compliant.

Those are different questions.

Transactions and batches are now part of the implemented surface

Earlier project documentation described transaction and batch Bundles as future work.

That is no longer the current implementation state at this revision.

FHIR distinguishes the two behaviors.

A transaction is processed atomically: either the transaction succeeds as a unit or the changes do not commit as a successful transaction.

A batch is a collection of independent actions. Individual entries can succeed or fail independently.

Ilavrita's current documentation records both behaviors as implemented.

For transaction Bundles, the server also records support for resolving urn:uuid: references between entries before committing the transaction.

This is exactly the sort of claim that should remain attached to a specific revision. Bundle processing has enough edge cases that "supports transactions" is not useful evidence by itself.

Future posts will break the implementation down against the R4 transaction rules and tests instead of treating the checkbox as the end of the story.

Conditional interactions are implemented too

Conditional create, update, and delete are also recorded as working at this revision.

The important property is not simply having another endpoint form. Conditional operations combine search semantics with mutation semantics.

A conditional write first needs to determine which resource, if any, is being targeted. That search cannot bypass the authorization rules that would apply to an ordinary search.

The current design therefore runs the target search under the appropriate grant for searching that type.

That interaction between authorization and conditional writes is more interesting to us than the feature checkbox itself, and it deserves a separate implementation post.

Audit belongs to the same transaction

The current implementation records audit events for FHIR interactions and login activity.

For successful mutations, the design principle is that the audit record belongs to the same transaction as the action it describes.

We do not want this state:

text
clinical write committed
audit write failed
request returned success

If a system claims to have an audit trail, recording the event as an unrelated best-effort side effect creates exactly the gap an incident review would care about.

The audit record is also deliberately separate from a client-editable FHIR AuditEvent resource. It is infrastructure evidence about what the server did.

Again, this is a technical control.

It is not a compliance certification.

What we still cannot responsibly claim

This section matters more than the feature list.

No external security review

The security controls in the repository are our implementation and our tests.

They have not yet been validated by an independent security review.

Before a stable release, the project roadmap calls for review of areas including cross-project escape, authorization bypass, injection, file access, secret handling, dependencies, and accidental exposure of health information.

Until that happens, our own test suite should not be confused with independent assurance.

Upgrade and rollback are not finished

The current build can create and evolve the database structures it knows about, and backup/verify/restore workflows are implemented.

That is not the same as having a complete operational upgrade lifecycle.

In particular, the project does not yet document and prove the rollback path we would want operators to rely on between releases.

A database server can behave perfectly during normal API calls and still be unsafe to operate if an upgrade cannot be reversed predictably.

For patient data, operational behavior is part of correctness.

SMART App Launch and OAuth are not implemented

SMART/OAuth work is on the roadmap.

Design work exists, but that is not the same as a production authentication and authorization server.

The current authentication model should therefore be evaluated for what it is now rather than described using future SMART capabilities.

PostgreSQL is a future backend

Ilavrita currently takes a SQLite-first approach.

The public FHIR behavior sits behind storage interfaces so that future storage backends do not need to redefine the FHIR contract.

PostgreSQL, project-aware partitioning, distributed workers, and horizontal-scale deployments are architectural destinations.

They are not reasons to benchmark or describe the current server as a clustered system.

The FHIR surface is intentionally incomplete

Examples of explicitly unsupported or incomplete areas include:

  • type-level history
  • system-level history
  • Patch
  • XML representation
  • several advanced search features and parameter types
  • complete terminology services
  • SMART App Launch
  • Bulk Data
  • FHIR R5

The right response to an unsupported protocol feature is not to hide the gap.

It is to make the boundary inspectable.

That is why known limitations are part of the product surface rather than release-note trivia.

Documentation drift is itself a bug

While verifying this article, we found something worth making public.

The synced documentation at this exact revision is not perfectly internally consistent.

The capability tables in the README, known-limitations document, and roadmap record transaction and batch Bundles and conditional interactions as implemented.

But an older paragraph in the roadmap still talks about conditional interactions as the next missing capability.

Likewise, parts of the architecture document still describe an earlier stage where only the HTTP surface existed, even though the same revision documents working storage, authorization, search, audit, Bundles, validation, subscriptions, and backup/restore elsewhere.

There is also stale introductory language around validation that does not match the newer detailed capability table later in the documentation.

For a project whose promise is evidence-first engineering, documentation drift matters.

The fix is not "pick whichever document sounds newest."

The fix is to reduce the number of independently maintained claims.

Our direction is for the website's What works today surface, documentation, CapabilityStatement, tests, and future blog posts to derive as much as possible from the same machine-checkable capability source.

Until that is complete, every blog post carries a source revision and a last-verified date.

What you should use Ilavrita for today

The current build is useful for engineering evaluation.

Clone it.

Run it locally.

Use synthetic FHIR resources.

Inspect its CapabilityStatement.

Try supported searches.

Try unsupported searches and inspect the failure.

Exercise project boundaries.

Run transactions.

Break transaction entries intentionally.

Inspect history.

Test conditional operations.

Run the backup and restore flow.

Read the implementation beside the tests.

If the behavior disagrees with the documentation, open an issue.

That is exactly the kind of feedback a developer preview needs.

What you should not do yet is treat the repository's existing controls as sufficient assurance for real patient data.

Not because nothing works.

Because enough important assurance work remains that we cannot responsibly make that claim yet.

Reproducing the starting point

The documentation for this post is pinned to:

text
4c36f1c8e5983943710398c2d8c1bd4ea689dbdd

The documented local setup is:

bash
git clone https://github.com/Ilavrita/Ilavrita.git
cd Ilavrita
make bootstrap
make run

The server then exposes operational identity through:

bash
curl -s http://127.0.0.1:8090/version

and FHIR capability discovery through:

bash
curl -s \
  -H 'Accept: application/fhir+json' \
  http://127.0.0.1:8090/fhir/R4/metadata

A future article will turn that into a complete clean-clone walkthrough using synthetic resources only.

For this article, those commands come from the repository documentation at the revision above. They were not independently executed in this publishing environment, so we are not presenting their successful execution here as new verification.

That distinction is intentional.

Where the project goes next

The near-term roadmap is still about correctness before breadth.

Among the remaining gates are stronger protocol coverage, upgrade and rollback procedures, SMART/OAuth, broader terminology and profile handling, external security review, and repeatable conformance testing.

Later phases add the things that make a platform larger: PostgreSQL, higher-throughput storage, distributed queues and workers, additional interoperability protocols, enterprise deployment patterns, and developer tooling.

Those should arrive on top of a FHIR contract that already has evidence behind it.

Not instead of one.

The project is open specifically so that other engineers can challenge that evidence.

If a claim is wrong, the most valuable contribution is not agreeing with the roadmap.

It is a failing test.


Evidence for this post

Back to blog