Skip to main content
VisionaryAI uses Azure Blob Storage to persist generated DALL-E images. This guide explains the storage architecture and SAS token authentication.

Storage architecture

The application uses a single storage container called images to store all generated artwork. Each image is:
  • Named with the format: {prompt}_{timestamp}.png
  • Stored as a PNG file (1024x1024 pixels)
  • Secured with SAS (Shared Access Signature) tokens
  • Sorted by timestamp for chronological display

Container configuration

The images container is configured with:
  • Public access: Disabled (private)
  • Authentication: SAS tokens required
  • Permissions: Read, write, and create via SAS tokens
Never enable public blob access. All image access should go through SAS tokens to maintain security and control.

SAS token generation

The application generates short-lived SAS tokens to access blob storage securely.

Implementation

Here’s how VisionaryAI generates SAS tokens:
azure/lib/generateSASToken.js

Key features

1

Credential initialization

Creates a StorageSharedKeyCredential using the storage account name and key from environment variables.
2

Permission configuration

Sets up SAS permissions:
  • Read: View existing images
  • Write: Modify images (if needed)
  • Create: Upload new images
3

Token expiration

Tokens expire 30 minutes after generation. This provides:
  • Security through short-lived credentials
  • Sufficient time for image upload and retrieval
  • Automatic revocation without manual intervention
SAS tokens are regenerated for each request, ensuring fresh credentials and minimizing security risks.

Image upload workflow

When a user generates an image, the following process occurs:
1

DALL-E generates the image

OpenAI’s DALL-E 3 API creates the image and returns a temporary URL.
2

Download image data

The function downloads the image as an array buffer:
3

Generate SAS token

A fresh SAS token is generated with write permissions:
4

Upload to blob storage

The image is uploaded using the blob client:

Image retrieval

The getImages function retrieves all images from the container with SAS-authenticated URLs.

Implementation

azure/src/functions/getImages.js

Sorting logic

Images are sorted by timestamp (newest first):
  1. Extract the timestamp from the filename: prompt_1234567890.png → 1234567890
  2. Sort in descending order (newest first)
  3. Return the sorted array with authenticated URLs

Storage credentials

Two credentials are required for blob storage operations:
Retrieve these from the Azure Portal:
  1. Navigate to your Storage Account
  2. Select Access keys under Security + networking
  3. Copy Storage account name and Key (key1 or key2)
Store these credentials securely in your Function App’s application settings. Never commit them to source control.

Best practices

Security

  • Use SAS tokens instead of making the container public
  • Set appropriate token expiration times (30 minutes recommended)
  • Rotate storage account keys periodically
  • Use Azure Key Vault for production deployments

Performance

  • Use array buffers for efficient binary data handling
  • Generate SAS tokens per-request to avoid expiration issues
  • Consider implementing caching for frequently accessed images

Cost optimization

  • Use Standard tier (LRS replication) for cost-effective storage
  • Implement lifecycle policies to archive old images
  • Monitor storage usage in Azure Portal

Troubleshooting

”Image upload failed” error

Cause: SAS token may have expired or insufficient permissions. Solution:
  • Verify token expiration time
  • Ensure write and create permissions are enabled
  • Check storage account credentials
Cause: SAS token in image URLs may have expired. Solution:
  • Regenerate SAS tokens when fetching images
  • Ensure the getImages function generates fresh tokens

Authentication errors

Cause: Invalid storage account credentials. Solution:
  • Verify accountName and accountKey environment variables
  • Check that the credentials match your storage account
  • Regenerate access keys if compromised

Next steps