Blob Storage Management
Blob Storage Management allows you to configure where analysis images and results are stored. You can choose between Azure Blob Storage or S3-compatible storage (AWS S3, Hetzner Object Storage, MinIO, etc.) and manage authentication credentials.
Overview
Section titled “Overview”Each tenant has its own blob storage configuration that determines where:
- Input images are uploaded via presigned URLs
- Analysis results (heatmaps, PDF reports) are stored
The Neuramancer API uses your configured storage credentials to generate presigned URLs for secure, direct file access without exposing your credentials to end users.
Supported Storage Types
Section titled “Supported Storage Types”| Type | Description | Use Cases |
|---|---|---|
| Azure | Azure Blob Storage | Azure-native deployments, enterprise Azure environments |
| S3 | S3-compatible storage | AWS S3, Hetzner Object Storage, MinIO, DigitalOcean Spaces |
How It Works
Section titled “How It Works”sequenceDiagram
participant C as Client
participant API as Neuramancer API
participant S as Blob Storage<br/>(Azure/S3)
C->>API: POST /v1/analysis
Note over API: Uses tenant's<br/>storageConfig
API->>S: Generate presigned PUT URL
S-->>API: Presigned URL (presignedUrlExpirySeconds expiry)
API-->>C: Analysis + presigned URL
C->>S: PUT image (direct upload)
Note over API: Analysis processing
API->>S: Upload heatmaps to storage
C->>API: GET /v1/analysis?id=xxx
API->>S: Generate presigned GET URL
S-->>API: Presigned URL (presignedUrlExpirySeconds expiry)
API-->>C: Analysis + result URLs
C->>S: GET heatmap (direct download via presigned URL)
The API uses the tenant’s storage configuration to:
- Generate presigned upload URLs when analyses are created
- Upload processing results (heatmaps, reports) after inference completes
- Generate presigned download URLs for retrieving results
- Refresh presigned URLs automatically when you retrieve an analysis via GET request
Presigned URL Security
Section titled “Presigned URL Security”Presigned URLs are publicly accessible but mathematically designed to be unguessable. They contain:
- Cryptographic signatures based on storage credentials
- Expiration timestamps
- Random identifiers (analysis IDs)
While anyone with the URL can access the resource, the URL itself cannot be guessed or enumerated. The expiry time you configure balances security (shorter = better) with operational convenience (longer = fewer refresh requests).
Fetching Storage Configuration
Section titled “Fetching Storage Configuration”To retrieve your tenant’s current blob storage configuration, use the following endpoint: GET /v1/tenant.
Data model: StorageConfig
Updating Storage Configuration
Section titled “Updating Storage Configuration”Should the need arise to change your blob storage settings (e.g., rotate credentials), you can update the configuration using the following endpoint: PUT /v1/tenant.
In general, we recommend you to:
- Regularly rotate storage credentials
- Set appropriate
presignedUrlExpirySecondsbased on your application’s access patterns
Data model: StorageConfig
CORS for Browser Uploads
Section titled “CORS for Browser Uploads”When uploading files to S3 presigned URLs directly from a browser (e.g. via fetch or XMLHttpRequest), the S3 bucket must have a CORS policy that allows your application’s origin. Without this, browsers will block the upload request.
Configuration
Section titled “Configuration”Set the corsAllowedOrigins field in your tenant’s S3 configuration:
{ "storageType": "s3", "storageConfig": { "s3": { "endpoint": "s3.example.com", "port": 443, "useSSL": true, "bucketName": "my-bucket", "region": "eu-central-1", "accessKeyId": "...", "secretAccessKey": "...", "corsAllowedOrigins": [ "https://app.neuramancer.dev", "https://app.neuramancer.de", "http://app.neuramancer.localhost", "https://app.neuramancer.localhost", "https://app.example.com", "http://localhost:3000" ] } }}The CORS policy is applied automatically:
- On tenant update - whenever you
PUT /v1/tenantwith S3 config containingcorsAllowedOrigins - On first presigned URL creation - when the bucket is first accessed (idempotent, cached per process)
Default Origins
Section titled “Default Origins”If corsAllowedOrigins is not set in the tenant config, the following origins are applied by default:
https://app.neuramancer.devhttps://app.neuramancer.dehttp://app.neuramancer.localhosthttps://app.neuramancer.localhost
Set corsAllowedOrigins explicitly to override these defaults (e.g. to add your own domain or localhost port).
