Storage provider auto-detection¶
Summary¶
Understand how SkyCMS selects a blob storage driver from connection string configuration and tenant-specific settings.
Where detection happens¶
Blob storage provider selection is implemented in Cosmos.BlobService.
StorageContextresolves the configured storage connection string.StorageContext.GetDriverFromConnectionString(...)asksConnectionStringParser.DetermineProvider(...)to classify that connection string.StorageContextthen creates the matching driver instance.
In single-tenant mode, this happens when StorageContext is created.
In multi-tenant mode, the same detection logic runs against the tenant-specific connection string returned by the dynamic configuration provider, and the resulting driver is cached per connection string.
Configuration precedence¶
StorageContext checks configuration in this order:
ConnectionStrings:StorageConnectionStringConnectionStrings:AzureBlobStorageConnectionString
The first non-empty value becomes the active storage connection string.
Detection rules¶
Storage driver selection is pattern-based. SkyCMS does not require a separate StorageProvider flag for the current blob storage path.
| Pattern in connection string | Detected provider | Driver |
|---|---|---|
Starts with DefaultEndpointsProtocol= |
Azure Blob Storage | AzureStorage |
Contains AccountId and Bucket |
Cloudflare R2 | AmazonStorage |
Contains Bucket and Region |
Amazon S3-compatible path | AmazonStorage |
Provider detection flow¶
%%{init: {"theme":"base","themeVariables":{"primaryColor":"#eef6ff","primaryTextColor":"#0f172a","primaryBorderColor":"#2563eb","lineColor":"#334155","secondaryColor":"#f8fafc","tertiaryColor":"#ffffff","fontFamily":"Segoe UI, Arial, sans-serif"}}}%%
flowchart TD
Config[Resolve active storage connection string] --> Detect[ConnectionStringParser.DetermineProvider]
Detect --> Azure{Azure pattern?}
Azure -- Yes --> AzureDriver[Create AzureStorage driver]
Azure -- No --> S3{S3-compatible pattern?}
S3 -- Yes --> AmazonDriver[Create AmazonStorage driver]
S3 -- No --> Unsupported[Throw UnsupportedStorageProviderException]
TenantMode[Multi-tenant mode] --> Config
Config --> Cache[Cache driver by connection string hash]
Google Cloud Storage is typically configured through an S3-compatible connection pattern, so it follows the same S3-compatible driver path instead of a dedicated GCS-specific runtime detector.
Runtime flow¶
The detection flow is straightforward:
- Resolve the active storage connection string from configuration.
- Classify it with
ConnectionStringParser.DetermineProvider(...). - Create
AzureStoragefor Azure patterns. - Create
AmazonStoragefor S3-compatible and Cloudflare R2 patterns. - Throw an
UnsupportedStorageProviderExceptionif the connection string shape is unsupported.
For Azure Blob Storage, StorageContext also checks whether the connection string points at Azurite. If it does, the Azure driver is created without DefaultAzureCredential. Otherwise, the Azure driver can use DefaultAzureCredential when the connection string indicates token-based access.
Multi-tenant behavior¶
In multi-tenant mode, provider selection is per tenant, not global.
- the current tenant is resolved through
IDynamicConfigurationProvider, - the tenant storage connection string is used to create the driver,
- the driver instance is cached using a hash of the connection string,
- different tenants can use different storage providers in the same running application.
This is why storage bugs in multi-tenant deployments should be diagnosed with the tenant-specific connection string, not only with the host application's base settings.
Debugging sequence¶
When storage detection does not behave as expected, inspect these points in order:
- Confirm which configuration key actually won:
StorageConnectionStringorAzureBlobStorageConnectionString. - Check the exact connection string shape rather than relying on provider labels in comments or environment variable names.
- Verify that S3-compatible strings include the fields the parser actually looks for.
- In multi-tenant mode, confirm the tenant-specific connection string returned by the dynamic configuration provider.
- If startup fails, inspect
UnsupportedStorageProviderExceptionorInvalidConnectionStringExceptiondetails.
Tests that cover this behavior¶
The current selection rules are exercised by the blob storage tests in the main SkyCMS solution, especially the driver selection tests that verify Azure, S3-compatible, and R2 connection-string patterns.
When changing detection behavior, add or update tests for:
- valid provider patterns,
- ambiguous patterns,
- unsupported strings,
- multi-tenant driver reuse and isolation.