Key takeaways
- Accept one authorized product image and bound its byte size before paid processing begins.
- Create a versioned WebP derivative with fit resizing and zoom disabled so small sources are not enlarged.
- Keep the Azure account, container, and key in Template Credentials rather than Assembly fields or browser code.
Product images often arrive as oversized camera files while catalog pages need a predictable delivery asset. Uploading the source directly to Azure leaves format, dimensions, metadata, cache behavior, and review access to separate code paths. A locked three-stage Template makes one derivative whose durable storage identity and temporary review URL have different roles; Azure account and container settings supply the anonymous-access boundary.
What matters most
- Set Content-Type and review-safe Cache-Control deliberately instead of relying on destination guesses.
- Treat a SAS URL as temporary bearer access and store the blob path—not the signed URL—as durable identity.
- Reconcile the successful export with the exact product, source version, workflow version, and Assembly ID before publication.
Model source, processing, and storage identity
An uploaded product photo is input to a workflow, not a catalog publication event. Authenticate the uploader, authorize the product record, validate the detected image type and byte size, and create a durable processing operation before accepting the Assembly result. Keep the editable or high-resolution source under an explicit retention policy rather than assuming the WebP derivative can replace it.
Give every derivative a workflow version. The application record should map the product and source version to that workflow, its Assembly ID, and the resulting Azure container and blob path. This lets a later quality change create a new derivative without overwriting the reviewed version or losing the route back to its source.
Source identity
The product, original upload, checksum or version, and retention role.
Processing identity
The saved workflow version and Assembly that produced the derivative.
Storage identity
The Azure account boundary, container, and versioned blob path.
Build the Azure product-image Template
The Template accepts one file through :original, sends it to /image/resize, and exports only the resulting WebP through /azure/store. Fit resizing keeps the complete image within the requested box, while zoom set to false prevents a small source from being enlarged. The versioned path contains a product identifier supplied only after application authorization plus Assembly uniqueness.
Set allow_steps_override to false so an upload client cannot replace the destination, request a larger workload, or bypass processing. The Template auth object limits the number and total size of accepted uploads. Those limits reduce accidental workload, but the application must still enforce tenant ownership, allowed product state, rate limits, and a permitted product_id value.
{
"allow_steps_override": false,
"auth": {
"max_number_of_files": 1,
"max_size": 52428800
},
"steps": {
":original": {
"robot": "/upload/handle"
},
"product_webp": {
"use": ":original",
"robot": "/image/resize",
"width": 1600,
"height": 1600,
"resize_strategy": "fit",
"zoom": false,
"format": "webp",
"quality": 82,
"strip": true
},
"azure_review": {
"use": "product_webp",
"robot": "/azure/store",
"credentials": "azure-product-images",
"path": "catalog/web-v1/${fields.product_id}/${assembly.id}/${file.url_name}",
"content_type": "image/webp",
"cache_control": "private, no-store",
"metadata": {
"workflow": "catalog-web-v1",
"source_id": "${fields.product_id}"
},
"sas_expires_in": 900,
"sas_permissions": "r",
"result": true
}
}
}Set blob properties and metadata as part of the asset contract
A versioned WebP should leave the workflow with an explicit Content-Type. The sample uses private, no-store caching during review so an expiring SAS response is not retained by a shared cache. Because /azure/store writes cache_control onto the stored blob, that private, no-store value persists on the object. Serving the same blob later with a caching policy requires resetting its Cache-Control or producing a new derivative rather than assuming the review-time value clears itself. Store stable, non-sensitive metadata such as the workflow name and source record identifier when operators need to trace a blob without opening the application database.
Do not place secrets, personal information, or an unbounded browser value in Azure metadata or paths. Treat product_id as a validated application identifier with a documented character and length limit. /azure/store converts string, number, and boolean metadata values to strings, so consumers should not expect the original JSON types to survive.
Use a SAS URL only for short-lived review
/azure/store returns the signed URL in the result’s sas_url field; the ordinary url field is unsigned. The upload creates a SAS even when sas_expires_in is omitted, using a server-default lifetime. Omitting sas_permissions uses a write-capable default, not read-only access. This sample explicitly sets sas_permissions to r and sas_expires_in to 900 seconds. Set both values rather than relying on defaults for review access.
The Robot does not configure anonymous access. Keep the destination container private and check the storage account’s AllowBlobPublicAccess setting; disallowing anonymous access at the account level overrides container settings. Anyone who obtains the SAS URL can use its delegated access during its validity period, so do not log it, place it in analytics, send it to unrelated clients, or store it as the catalog asset’s permanent URL.
Persist the container and blob path as durable identity. When a reviewer needs access later, the application should authorize that request and issue or obtain access according to its current delivery design. A successful SAS fetch proves that the object can be read with that token; it does not approve the asset, grant catalog publication, or replace product-level authorization.
Verify image behavior before catalog cutover
The resize Step sets strip to true, which removes all embedded metadata, including the ICC color profile, from the derivative. Test EXIF orientation, wide and tall images, transparent inputs, color-profile behavior, very small sources, very large dimensions, animation, and malformed data. Compare the rendered output as well as its MIME type, dimensions, byte size, and storage metadata. Profile removal and WebP conversion can each affect rendered color or other required behavior.
Verify that the Azure account and container settings prevent anonymous reads of the review blob. Reconcile the successful export with the expected product operation, then advance the catalog record through a separate authorized transition. Roll out a small traffic cohort first, observe delivery and cache behavior, and retain the previous derivative until the rollback window closes.
Recover without publishing duplicates
A timeout or missed webhook is an uncertain outcome, not proof that the blob was not written. Store the operation before creating the Assembly and process signed completion notifications idempotently. If the caller loses the response, inspect the existing Assembly and application record before starting another run.
Classify failures by intake, image processing, Azure authentication, missing container, and export. Expose stable recovery actions to operators while keeping raw provider details protected. A new workflow run should create a new versioned object and update the catalog only after review; deletion of the old blob belongs to a later retention job.
Technical details worth knowing
- /upload/handle must be named :original, must not define use, and can appear only once in a set of Assembly Instructions.
- /image/resize with resize_strategy set to fit preserves aspect ratio and keeps each side within the requested bounds. Setting zoom to false prevents enlargement of smaller inputs.
- /azure/store applies content_type, content_encoding, content_language, cache_control, and metadata to the stored blob. It accepts content_disposition but does not currently apply it to the blob.
- /azure/store returns signed review access in sas_url; the ordinary url field is unsigned. sas_expires_in controls the lifetime, with a server default when omitted. Omitting sas_permissions uses a write-capable default; explicit values accept r (read), w (write), and d (delete). This workflow grants only r for review.
- /azure/store has no access-level parameter. Anonymous access depends on both the storage account’s AllowBlobPublicAccess setting and the container’s anonymous access level. Disallowing anonymous access at the account level overrides the container setting.
- A SAS URL grants its delegated permissions to anyone holding it during the signature’s validity period.
- Azure metadata values supplied to /azure/store may be strings, numbers, or booleans; the Robot converts them to strings.
A practical approach
- 1
Define accepted image types, maximum bytes, target dimensions, quality, and source-retention policy.
- 2
Create scoped Azure Template Credentials and save the locked upload–resize–store Template.
- 3
Test the real container with orientation, transparency, color-profile, and unusually small and large fixtures.
- 4
Reconcile the blob path, review through the short-lived SAS, then publish through a separate catalog transition.
When Transloadit is useful
Use /upload/handle for controlled product-image intake, /image/resize for a bounded WebP derivative, and /azure/store for a versioned blob in a private-access container. Let the store Step return a short-lived read-only SAS URL for review, but persist the container and blob path as the durable identity.
Architecture boundary
Transloadit accepts the product image, creates a WebP derivative, and writes it to an Azure Blob Storage container that the Azure administrator or application has configured for private access. The application still owns product authorization, source retention, catalog state, delivery policy, and every decision to expose or replace the derivative.
Frequently asked questions
Should the catalog store the SAS URL?
No. A SAS URL is temporary bearer access. Store the Azure container and blob path as durable identity and authorize later delivery independently.
Does fit resizing create an exact square?
No. It preserves aspect ratio and keeps both sides within the requested bounds. Use an explicit crop or pad policy when exact dimensions are required.
Why use a versioned blob path?
It allows quality policies to coexist, makes cache behavior predictable, and supports review and rollback without overwriting a known asset.
Can the browser choose the Azure container?
No. Keep the account, container, and key in the locked Template Credential. A trusted application may supply a bounded product identifier only after authorization.
Does a successful export publish the product image?
No. It proves that the derivative reached Azure. Catalog publication remains a separate application state transition.