Microsoft Azure Blob Storage is the cheapest pure-object store for migrations that need to stay inside the Azure ecosystem. This guide walks through the standard connection string auth flow — which works on personal Azure subscriptions, Pay-As-You-Go, and full Enterprise Agreements alike.
Step 1 — Create or pick a Storage Account
Sign in to portal.azure.com. Search for Storage accounts → Create (or pick an existing one).
Subscription + Resource group
Pick the subscription that will be billed and a resource group (create one namedasset-migrator-rgif you don't have one).Storage account name
Globally unique, lowercase, 3–24 characters, letters and numbers only. Example:acmemigration2026.Region
Pick a region close to your other infrastructure. Cross-region egress is the largest hidden cost for Azure migrations.Performance + Redundancy
Standard performance + LRS (Locally Redundant Storage) is cheapest and fine for most migrations. GRS if you need geo-redundancy.Review + Create
Click through, validate, deploy. Takes about 30 seconds.
Step 2 — Create a container
Open the Storage Account → Data storage → Containers → + Container.
- Name: something specific like
migrated-assetsoracme-prod. Lowercase, 3–63 chars, no underscores. - Public access level: Private (no anonymous access) — this is the only safe default. Univaultport authenticates per-call; assets don't need to be publicly readable.
Click Create.
Step 3 — Copy the connection string
Go to Security + networking → Access keys.
You'll see two access keys (key1 and key2). Each has a Connection string below it.
DefaultEndpointsProtocol=https;
AccountName=acmemigration2026;
AccountKey=<long-base64-key>==;
EndpointSuffix=core.windows.netClick Show next to key1's Connection string, then Copy. This is the credential — paste the entire single-line string into Univaultport.
Step 4 — (Optional) Scope access with SAS instead of AccountKey
For least-privilege deployments, generate a Shared Access Signature (SAS) scoped to just the container you'll migrate to/from. The connection string format is the same — just replace AccountKey=... with SharedAccessSignature=...:
BlobEndpoint=https://acmemigration2026.blob.core.windows.net/;
SharedAccessSignature=sv=2024-11-04&ss=b&srt=co&sp=rwdlacx&se=2026-12-31T...To generate one:
Open Shared access signature
Storage Account → Security + networking → Shared access signature.Pick allowed permissions
For source+destination use: Read, Write, Delete, List, Add, Create. For read-only: just Read + List.Pick allowed resource types
Container + Object. Service-level is not needed.Set an expiration
Don't pick "never" — pick a date matching your migration timeline (90 days is a reasonable maximum).Generate SAS and connection string
Copy the bottom "Connection string" output, not the URL.
Both auth methods work identically once pasted into the connector.
Step 5 — Paste credentials into Univaultport
In the connector wizard:
Connection String
Paste the full single-line string from Step 3 or 4.Container Name
Just the container name — no slashes, noblob.core.windows.netURL prefix. e.g.migrated-assets.Blob Prefix (optional)
Scopes this connector to a sub-path. Example:images/2026/. All listings and writes happen under this prefix.
Click Save & test. Univaultport does two checks in one call:
getProperties()on the container — confirms the connection string is valid.listBlobsFlat({ maxPageSize: 1 })— confirms list permission, which the next migration step actually needs.
A green check means the credentials work for migrations, not just for ping.
RBAC roles (when using Azure AD principals)
If you're using Azure AD authentication via a SAS or a service principal connection string instead of AccountKey, the principal must have one of these roles at the container or storage account scope:
| Role | What it allows |
|---|---|
Storage Blob Data Reader | List + download |
Storage Blob Data Contributor | Read, write, delete |
Storage Blob Data Owner | Includes setting POSIX ACLs on HNS-enabled accounts |
For Univaultport's source-and-destination use, Contributor is the right choice. Grant via Azure Portal → Storage Account → Access Control (IAM) → Add role assignment.
Hierarchical Namespace (Data Lake Gen2) caveat
If your storage account has Hierarchical namespace enabled (visible under Advanced settings during account creation), it's technically a Data Lake Gen2 account. The standard Blob SDK that Univaultport uses:
- Reads work normally
- Lists work normally
- Writes work for most HNS containers
- POSIX ACLs (file-level Unix-style permissions) are NOT preserved on writes — only RBAC
For deep Data Lake migrations that need ACL preservation, use AzCopy with --preserve-permissions. For standard blob-style use cases on HNS accounts, Univaultport is fine.
File size limits
The Blob SDK's uploadStream handles arbitrary sizes via block uploads:
- Per-block max: 4000 MB (we configure 4 MB blocks)
- Per-blob max: 200000 blocks × 4000 MB = ~190 TB
- Practical limit for Univaultport migrations: limited by source-side timeouts, not Azure
For files over 100 GB, consider running the migration in a job split by folder rather than as a single all-at-once job.
Cost considerations
Approximate pricing for typical migrations (East US, Hot tier, as of mid-2026):
| Operation | Cost |
|---|---|
| Storage (LRS Hot) | $0.018/GB/month |
| Write operations | $0.055 per 10,000 |
| Read operations | $0.0044 per 10,000 |
| Egress to internet | $0.087/GB (first 10 TB) |
| Egress to other Azure regions | $0.02/GB |
For a one-time 100 GB migration into Azure:
- Storage cost while resident: ~$1.80/mo
- Write operations: < $1
- Ingress is free
For migrations out of Azure to another cloud, factor egress at ~$0.087/GB.
Troubleshooting
| Error | Cause | Fix |
|---|---|---|
AuthenticationFailed | Connection string is malformed or key was rotated | Re-copy from Access keys |
AuthorizationPermissionMismatch | Using SAS/Azure AD without the right RBAC role | Add Storage Blob Data Contributor at the container scope |
ContainerNotFound | Wrong container name, or container in a different account | Verify the name and re-check the connection string's AccountName |
BlobNotFound | Source asset path doesn't exist | Confirm prefix + path in the Azure Portal Blob browser |
ServerBusy | Azure throttling (rare for typical workloads) | Worker auto-retries with back-off |
RequestBodyTooLarge | Single block over 4000 MB | Shouldn't happen — Univaultport's chunks are 4 MB |
Soft delete (worth knowing)
If you enable Blob soft delete on the container (Data protection → Blob soft delete), every delete() call from Univaultport becomes a soft delete. The blob is recoverable for the retention window (1–365 days, default 7) but counts toward your storage cost. To permanently delete, either:
- Disable soft delete, OR
- Wait out the retention window, OR
- Manually purge via Azure Portal
For most migration workflows where you're cleaning up source after a successful move, soft delete provides a safety net — leave it on.
Next steps
With Azure Blob connected, common patterns are:
- Azure → S3 / GCS for multi-cloud distribution
- Cloudinary / Drive → Azure for archival of legacy assets in a Microsoft-heavy enterprise
- Azure → Azure between containers in the same or different storage accounts for re-organization
Univaultport preserves the folder hierarchy on writes since Azure supports / in blob names as virtual folders.



