Fetching user-delegation SAS from an application hosted on external environment using service principal

Najam ul Saqib 360 Reputation points
2025-01-14T10:16:50.4033333+00:00

I have been trying hard these days to architect a secure solution to consume data from storage accounts and I have came up with a solution that I think is fool-proof and matches the best practices, let me know if you think this approach to be faulty in any case or if you can think of a better & simpler implementation.

Scenario:

Our application is hosted outside Azure in an external environment, the web app allows login for different users and each user has its own set of data available in the storage account. We want to access the storage account with optimal security.

Architecture:

As Microsoft suggests to use User-delegation SAS so we will register our external backend application with Entra ID as service principal. That service principal will be granted access to generate user delegation key. When backend will get that key it will generate a SAS (with proper expiry and scope) and return back to the frontend (client-facing application).

To avoid anyone to call backend and get the SAS, backend will ensure that the request is coming from an authenticated user on the frontend using external auth mechanisms e.g. JWT

Once frontend gets the SAS it will call the storage account and display the files on frontend.

Azure Storage Accounts
Azure Storage Accounts
Globally unique resources that provide access to data management services and serve as the parent namespace for the services.
3,317 questions
Azure Blob Storage
Azure Blob Storage
An Azure service that stores unstructured data in the cloud as blobs.
3,024 questions
Microsoft Entra ID
Microsoft Entra ID
A Microsoft Entra identity service that provides identity management and access control capabilities. Replaces Azure Active Directory.
22,847 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Luis Arias 7,846 Reputation points
    2025-01-14T14:55:19.78+00:00

    Hello Najam ul Saqib,

    Based on your description this is the architecture of how your external application will work to get the storage account objects:

    User's image

    It looks like quite good , however there is here some points of improvements:

    • Enforce Least Privilege Principle: Limit SAS tokens to the minimum permissions and scope required for each operation. Best Practices for SAS.
    • Shorten SAS Token Expiry: Set short-lived expiry times for SAS tokens to reduce the risk of misuse. Regenerate tokens dynamically if needed. SAS Token Expiry Recommendations.
    • Use User-Specific Claims: Embed user-specific claims (e.g., roles or IDs) in JWTs to enable fine-grained access control. Secure Azure Storage with Identity-Based Access.
    • Introduce Server-Side Mapping: Maintain a mapping of external users to Azure Storage permissions for centralized and dynamic access control. Custom Authorization Techniques

    Mapping Example:

    A database table might look like this:

    User ID Allowed Containers
    JohnDoe container1, container2
    JohnDoe container1, container2
    JaneDoe container3
    • Strengthen Backend Security:
      • Use certificates instead of client secrets for service principal authentication. Azure AD Certificates and Secrets.
      • Restrict backend access via IP allowlists, VPNs.
    • Monitor SAS Usage: Enable Azure Storage logging to track SAS token activities and detect anomalies. Azure Storage Analytics Logging.
    • Encrypt Data in Transit and at Rest: Enforce HTTPS (TLS 1.2+) for all communication and use Azure Storage Customer-Managed Keys for data encryption. Azure Storage Encryption.
    • Rate-Limit Backend SAS Requests: Implement rate-limiting and caching for SAS generation to prevent abuse and improve performance. Designing Resilient Applications. If the information helped address your question, please Accept the answer.

    Luis

    1 person found this answer helpful.
    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.