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
- Upload a file via
$binary-upload, receiving afirearrow://URL - Store the URL in any FHIR resource field (e.g.,
Patient.photo.url,DocumentReference.content.attachment.url) - 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.
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:
- A
binary-uploadauthorization rule for the client's role - 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
| Property | Description | Default |
|---|---|---|
enabled | Enable binary storage | false |
azure.connection-string | Azure Blob Storage connection string | -- |
azure.container-name | Blob container name | -- |
azure.max-file-size | Maximum upload size in bytes | 10485760 (10 MB) |
azure.pre-signed-url-expiration-seconds | How long pre-signed URLs remain valid | 120 |
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 Path | Environment Variable |
|---|---|
fire-arrow.binary-storage.enabled | FIRE_ARROW_BINARY_STORAGE_ENABLED |
fire-arrow.binary-storage.azure.connection-string | FIRE_ARROW_BINARY_STORAGE_AZURE_CONNECTION_STRING |
fire-arrow.binary-storage.azure.container-name | FIRE_ARROW_BINARY_STORAGE_AZURE_CONTAINER_NAME |
fire-arrow.binary-storage.azure.max-file-size | FIRE_ARROW_BINARY_STORAGE_AZURE_MAX_FILE_SIZE |