Skip to content

feat(storage-azure): add support for Entra managed identity authentication - #17598

Open
SergeyFilenko wants to merge 1 commit into
payloadcms:mainfrom
SergeyFilenko:feat/storage-azure-managed-identity
Open

feat(storage-azure): add support for Entra managed identity authentication#17598
SergeyFilenko wants to merge 1 commit into
payloadcms:mainfrom
SergeyFilenko:feat/storage-azure-managed-identity

Conversation

@SergeyFilenko

Copy link
Copy Markdown

What?

Adds Entra ID (managed identity) authentication to @payloadcms/storage-azure.

AzureStorageOptions now accepts either a connectionString (existing behaviour) or a credential, which can be any TokenCredential from @azure/identity such as DefaultAzureCredential. The two options are mutually exclusive at the type level, so misconfiguration is caught at compile time.

Why?

Connection strings require storing the storage account key as a secret. On Azure App Service, Container Apps or AKS, identity-based authentication is Microsoft's recommended approach. There are no long-lived secrets to store, rotate or leak, and access is controlled through RBAC and can be revoked at any time. It also makes it possible to harden security further by disabling storage account key access entirely.

This has been requested before in #13627 (and #12004 prior to it), which proposed the same credential option. However, #13627 doesn't address clientUploads: the SAS signing code in generateUploadInstructions unconditionally casts the container client's credential to StorageSharedKeyCredential. With a TokenCredential configured, that cast is wrong at runtime and client uploads fail.

How?

  • getStorageClient now builds the BlobServiceClient from either auth method and caches both the service and container clients per cache key. The service client is needed to request user delegation keys when signing client upload URLs.
  • generateUploadInstructions branches on the actual credential type instead of casting:
    • StorageSharedKeyCredential signs a service SAS, exactly as before, so there is no behaviour change for existing users.
    • TokenCredential fetches a user delegation key via getUserDelegationKey and signs a user delegation SAS. Keys are requested with twice the SAS lifetime and cached in a WeakMap, and only reused while their remaining validity still covers a full SAS window plus a clock-skew margin. In practice this means roughly one key fetch every three hours rather than one per upload.
  • Docs and README updated with an Authentication section covering both methods, the baseURL requirement, the Storage Blob Data Contributor role requirement, and a note on the SAS connection string limitation.
  • Unit tests added covering client construction and caching, both signing paths (asserting the sig/sp and skoid/sktid SAS parameters), delegation key caching, and the error cases.

Verified manually against a real storage account with a DefaultAzureCredential: server uploads, client uploads (delegation SAS) and downloads all work, and misconfigurations produce the intended errors.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant