Implement a custom external storage provider
This page explains how to add support for storing DAM binaries in a third-party system (for example, Microsoft Azure or your own object storage) by implementing Magnolia’s DAM Binary API and wiring it into your Magnolia instance.
Use a custom provider when you want to decouple asset binaries from Magnolia’s JCR and store them in an external system other than the built-in options.
| An out-of-the-box AWS S3 implementation is available in the magnolia-dam-jcr-s3module. Use it if it meets your needs; implement a custom provider only when you require a different storage backend. | 
Prerequisites
Before you start, make sure you have any necessary access to the target storage SDK and the required credentials ready.
Reference implementation and API
- 
Download the S3 sample project. 
- 
Download the Binary API interfaces. 
Core types to implement or use:
- 
BinaryManagementCrud- create, remove, and list binaries for a givenparentId.
- 
BinaryReference- immutable reference that encodes the provider id and provider-specific coordinates; can optionally expose a content hash.
- 
Binary- stream access to the content.
For test coverage, extend the TCK used by the S3 provider, for example: S3BinaryManagementCrudTest.java.
Procedure
- 
Create a Magnolia module to host your provider. - 
Keep the provider implementation and its configuration in this module. 
 
- 
- 
Define a BinaryReferencetype for your backend.- 
providerId()must be a unique short id (for example,myblob) and prefix all coordinates.
- 
coordinates()should be an opaque locator your provider understands (for example,myblob:container:key:version).
- 
Implement hash()to return a stable content hash (for example, SHA‑256) when available.
 
- 
- 
Implement BinaryManagementCrudfor your storage.- 
persistBinary(String parentId, InputStream contents, long size, String hash)stores content and returns aBinaryReference.
- 
persistBinary(String parentId, File contents, String hash)stores from file and returns aBinaryReference.
- 
removeBinary(String parentId, BinaryReference reference)deletes a single binary.
- 
removeAllBinaries(String parentId)removes every binary associated with the parent.
 
- 
- 
Integrate your storage SDK. - 
Map parentId(the logical owner, for example, the asset node id) to one or more binaries (renditions/versions).
- 
Compute/validate the content hash during persist and propagate it via BinaryReference#hash().
 
- 
- 
Add configuration using MicroProfile Config. - 
Provide endpoint, bucket/container, credentials, region, and timeouts. myblob.endpoint=https://storage.example.com myblob.container=assets myblob.region=eu-central-1 myblob.accessKey=${ENV:MYBLOB_ACCESS_KEY} myblob.secretKey=${ENV:MYBLOB_SECRET_KEY} myblob.connectionTimeoutMs=10000 myblob.readTimeoutMs=30000
 
- 
- 
Register your provider in Magnolia. - 
After adding your module as a dependency, set the binary strategy to your provider id. dam.core.binary.strategy=myblob
 
- 
- 
Verify the data model behavior. - 
Magnolia writes the external reference to the asset node property mgnl:binaryReference.
- 
Examples: jcr:…(JCR),s3:…(S3),myblob:…(your provider).
 
- 
- 
Test your provider implementation. - 
Reuse the S3 tests as a blueprint and extend the TCK to validate CRUD operations, multi-binary per parent, coordinate parsing, and hash propagation. 
- 
Verify large file uploads, parallel writes, and deletion idempotency. 
 
- 
- 
Deploy and run. - 
Package your module (JAR) and add it to your Magnolia webapp or bundle. 
- 
Provide environment-specific MicroProfile Config at runtime. 
- 
Set dam.core.binary.strategyto your provider id.
 
- 
Recommendations
- 
Prefer deterministic content hashing (for example, SHA-256) and include it in BinaryReference#hash().
- 
Keep coordinates stable across versions when possible; include versioning in coordinates if your backend supports it. 
- 
Limit permissions of your storage credentials to the minimum required (read/write/delete for the target container).