Skip to main content

Binary Storage

Fire Arrow Server integrates with Azure Blob Storage to store binary files (images, documents, PDFs, etc.) alongside your FHIR resources. Binary data is referenced in FHIR resources using firearrow:// URLs, which the server automatically resolves to time-limited, pre-signed Azure Blob URLs when clients read the resources.

How It Works

  1. Upload a file via $binary-upload, receiving a firearrow:// URL
  2. Store the URL in any FHIR resource field (e.g., Patient.photo.url, DocumentReference.content.attachment.url)
  3. Read the resource -- Fire Arrow automatically replaces firearrow:// URLs with time-limited pre-signed Azure Blob URLs

Uploading Files

Multipart Upload

The most common approach for uploading files from client applications:

curl -X POST http://localhost:8080/fhir/\$binary-upload \
-H "Authorization: Bearer <your-token>" \
-F "resourceReference=Patient/123" \
-F "[email protected]"
  • resourceReference -- the FHIR resource this binary belongs to (used for authorization)
  • file -- the binary file to upload

JSON Upload (Base64)

For programmatic uploads or when multipart isn't convenient:

curl -X POST http://localhost:8080/fhir/\$binary-upload \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <your-token>" \
-d '{
"resourceReference": "Patient/123",
"data": "iVBORw0KGgoAAAANSUhEUg...",
"contentType": "image/jpeg"
}'

Upload Response

Both upload methods return a FHIR Parameters resource:

{
"resourceType": "Parameters",
"parameter": [
{ "name": "url", "valueUrl": "firearrow://my-container/a1b2c3d4-photo.jpg" },
{ "name": "contentType", "valueString": "image/jpeg" },
{ "name": "size", "valueInteger": 204800 }
]
}

Use the url value in your FHIR resources:

curl -X PUT http://localhost:8080/fhir/Patient/123 \
-H "Content-Type: application/fhir+json" \
-H "Authorization: Bearer <your-token>" \
-d '{
"resourceType": "Patient",
"id": "123",
"name": [{ "family": "Smith", "given": ["Jane"] }],
"photo": [{
"contentType": "image/jpeg",
"url": "firearrow://my-container/a1b2c3d4-photo.jpg"
}]
}'

Reading Resources with Binary URLs

When you read a resource containing firearrow:// URLs, Fire Arrow Server automatically replaces them with time-limited, pre-signed Azure Blob Storage URLs:

curl http://localhost:8080/fhir/Patient/123 \
-H "Authorization: Bearer <your-token>"

Response (note the resolved URL):

{
"resourceType": "Patient",
"id": "123",
"name": [{ "family": "Smith", "given": ["Jane"] }],
"photo": [{
"contentType": "image/jpeg",
"url": "https://myaccount.blob.core.windows.net/my-container/a1b2c3d4-photo.jpg?sv=2021-06-08&se=2026-01-15T10%3A02%3A00Z&sig=..."
}]
}

The pre-signed URL is valid for a limited time (default: 120 seconds). After expiration, clients need to re-read the resource to get a fresh URL.

tip

Pre-signed URLs are generated on every read, so clients should fetch the resource just before they need to access the binary content rather than caching the URL long-term.

Authorization

Binary upload requires two things:

  1. A binary-upload authorization rule for the client's role
  2. Write access to the resource referenced by resourceReference

Example rules:

fire-arrow:
authorization:
validation-rules:
- client-role: "Patient"
resource: "Binary"
operation: "binary-upload"
validator: "PatientCompartment"
- client-role: "Practitioner"
resource: "Binary"
operation: "binary-upload"
validator: "LegitimateInterest"

Configuration

Configure binary storage under the fire-arrow.binary-storage key in your application.yaml:

fire-arrow:
binary-storage:
enabled: true
azure:
connection-string: "${AZURE_STORAGE_CONNECTION_STRING}"
container-name: "fhir-binaries"
max-file-size: 10485760 # 10 MB
pre-signed-url-expiration-seconds: 120
PropertyDescriptionDefault
enabledEnable binary storagefalse
azure.connection-stringAzure Blob Storage connection string--
azure.container-nameBlob container name--
azure.max-file-sizeMaximum upload size in bytes10485760 (10 MB)
azure.pre-signed-url-expiration-secondsHow long pre-signed URLs remain valid120

Using Managed Identity

For production deployments on Azure, you can use managed identity instead of connection strings. Replace the connection-string with your storage account's endpoint:

fire-arrow:
binary-storage:
enabled: true
azure:
endpoint: "https://myaccount.blob.core.windows.net"
container-name: "fhir-binaries"

When endpoint is provided instead of connection-string, Fire Arrow Server uses Azure's DefaultAzureCredential chain, which supports managed identity, environment variables, Azure CLI credentials, and other standard authentication methods.

Environment Variable Overrides

YAML PathEnvironment Variable
fire-arrow.binary-storage.enabledFIRE_ARROW_BINARY_STORAGE_ENABLED
fire-arrow.binary-storage.azure.connection-stringFIRE_ARROW_BINARY_STORAGE_AZURE_CONNECTION_STRING
fire-arrow.binary-storage.azure.container-nameFIRE_ARROW_BINARY_STORAGE_AZURE_CONTAINER_NAME
fire-arrow.binary-storage.azure.max-file-sizeFIRE_ARROW_BINARY_STORAGE_AZURE_MAX_FILE_SIZE