FHIR Binary File Management Guide
Secure File Attachment System for DocumentReference and Media Resources
Architectural Overview
FHIR Resource Binding Constraints
Key Implementation Decisions
-
Current Support:
- DocumentReference:
application/pdf,text/plain,image/* - Media:
audio/*,video/*,image/dicom(metadata only)
- DocumentReference:
-
Future Roadmap:
- Q3 2024: Full DICOM handling via
Media.content - Q4 2024: Streaming support for large files (>256MB)
- Q3 2024: Full DICOM handling via
Enhanced Upload Workflow
1. Authentication & Authorization
POST /graphql HTTP/1.1
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...
X-File-Metadata: {"purpose":"patient_consent"}
Required Scopes:
files.write- Upload initiationfhir.write- Resource creation
2. Upload Initialization (Optimized)
mutation SecureUpload($file: Upload!) {
uploadFile(
forEntity: "Patient/123"
data: $file
filename: "2024-annual-checkup.pdf"
contentType: "application/pdf"
security: {
encryption: AES256
accessWindow: "15m"
allowedIps: ["192.168.1.0/24"]
}
) {
url
storagePath
sasToken
expiresAt
hashSha256
}
}
New Security Parameters:
encryption: Server-side encryption typeaccessWindow: Custom SAS token validityallowedIps: Client IP restrictions
3. FHIR Resource Binding
DocumentReference with Provenance:
mutation CreateDocumentWithProvenance {
createDocumentReference(resource: {
status: "current"
category: {
coding: {
system: "http://loinc.org"
code: "34133-9"
display: "Summary of episode note"
}
}
content: [{
attachment: {
title: "Discharge Summary"
url: "azure-blob://discharge-2024.pdf"
hash: "sha256:abc123..."
creation: "2024-03-15"
}
}]
subject: { reference: "Patient/123" }
author: { reference: "Practitioner/456" }
}) {
id
meta { versionId }
content { attachment { size } }
}
}
Media Resource with Technical Context:
mutation CreateMediaWithDevice {
createMedia(resource: {
status: "completed"
content: {
contentType: "image/dicom"
url: "azure-blob://ct-abdomen.dcm"
height: 512
width: 512
frames: 120
}
device: {
identifier: {
system: "urn:oid:1.2.840.10008.2.6.1"
value: "CT-Scanner-789"
}
}
note {
text: "Abdominal CT with contrast"
}
}) {
id
content { duration }
}
}
Advanced Security Model
SAS Token Composition
# Token generation with security constraints
def generate_secure_sas(**kwargs):
sas = BlobSasSigValues(
protocol=SasProtocol.HTTPS,
start_time=datetime.utcnow(),
expiry_time=kwargs['expiry'],
permission=BlobSasPermissions(write=True),
ip_range=kwargs['ip_range'],
identifier=kwargs['policy_id'],
content_disposition="attachment",
content_type=kwargs['content_type']
)
return generate_blob_sas(**sas)
Validation Matrix
| Security Feature | Enforcement Level | Error Code |
|---|---|---|
| IP Range | Network layer | 403 FORBIDDEN |
| HTTPS Required | Protocol check | 403 INSECURE_TRANSPORT |
| Content-Type | Header validation | 415 UNSUPPORTED_MEDIA |
Operational Monitoring
File Lifecycle Events
Retention Policies:
- Unlinked files: 7 days
- Clinical documents: 7 years
- Temporary uploads: 24 hours
Compliance & Standards
-
FHIR R4 Attachments
Implements FHIR Binary and DocumentReference specs -
Azure Security Benchmarks
- Storage encryption at rest
- SAS token rotation
- Activity log auditing
-
HIPAA Considerations
- PHI encryption in transit (TLS 1.3+)
- Access audit trails
- Backup verification
Troubleshooting Guide
Common Scenarios & Solutions
| Symptom | Diagnostic Steps | Resolution |
|---|---|---|
| SAS token expired | Check expiresAt vs current time | Regenerate via refreshFileUrl |
| MIME type rejection | Validate against allowedTypes | Use fileTypeOverride parameter |
| Size limit exceeded | Check Content-Length header | Split file or request quota increase |
| Missing FHIR link | Search storage by fileId | Manual link via admin API |