Azure to reject SAS tokens not issued using Stored Access Policies - azure

Is there a way to get Azure to reject SAS (Shared Access Signatures) tokens that are NOT issued from a Stored Access Policy? In other words, I'd like to prevent Application Services from using ad-hoc access policies. That way, we not only manage the policies centrally, but we can quickly and with little impact revoke them.
I wish I could do all the reviews myself to ensure nobody does anything like that in the code, but I don't and not everyone does thorough code reviews. So I want to save us from ourselves.

The only way is change the account key.
As per this doc:
A shared access signature URI is associated with the account key used to create the
signature, and the associated stored access policy (if any). If no stored access policy is
specified, the only way to revoke a shared access signature is to change the account key.

Related

What good a service principal does over exposing a password

I am looking at the documentation of service principals , and come across these phrases
It's important to remove old service principals for the same reason that you delete old user accounts: attackers might gain access to their keys. It's best not to have credentials that aren't actively used.
You might wonder why you need to create this whole new type of object
just to authenticate a pipeline, when you have user accounts that work
perfectly well. User accounts aren't designed for unattended use. The
authentication process for a user account often checks that a human is
the entity that's trying to sign in. Increasingly, organizations use
additional security checks during authentication. These checks include
MFA, CAPTCHA checks, and inspecting the device and network that the
user is using so that they can verify the legitimacy of a request to
sign in.
It's also a bad idea to save your username and password anywhere, because someone else might get access to them and then use them to impersonate you.
In "both" theories, it seems it is not a good idea to keep / share service principals ( aka passwords ). Is it only reason that passwords are not designed for unattended use we should use service principals which offers secure measures on a case to case basis ?
As per the Official Microsoft Documentation,
When you have applications, hosted services, or automated tools that needs to access or modify resources, you can create an identity for the app. This identity is known as a service principal. Access to resources is restricted by the roles assigned to the service principal, giving you control over which resources can be accessed and at which level.
The user accounts and passwords are not designed for unattended use. Service princpals can be used to give the access to the resources based on the Role-based access control(RBAC).
What service principal object exactly do is it sets the information about a particular app and its resources access.
If you want to avoid the need to manage the credentials you can use Managed Identity.
Reference:
https://learn.microsoft.com/en-us/azure/active-directory/develop/app-objects-and-service-principals#service-principal-object

Why does Azure recommend User Delegation Shared Access Signatures

In the Microsoft documentation, it is recommended that professionals use User Delegation Shared Access Signatures rather than key-based Shared Access Signatures. Specifically, why is this the case?
In this document, it is specified that:
Microsoft recommends that you use Azure AD credentials when possible
as a security best practice, rather than using the account key, which
can be more easily compromised. When your application design requires
shared access signatures for access to Blob storage, use Azure AD
credentials to create a user delegation SAS when possible for superior
security.
This Azure official document explains why it is recommended to use User Delegation Shared Access Signatures.
When a client accesses a blob service resource with a user delegation SAS, the request to Azure Storage is authorized with the Azure AD credentials that were used to create the SAS. The role-based access control (RBAC) permissions granted for that Azure AD account, together with the permissions explicitly granted on the SAS, determine the client's access to the resource. This approach provides an additional level of security and avoids the need to store your account access key with your application code. For these reasons, creating a SAS using Azure AD credentials is a security best practice.

What are proper scopes for API requests

I need to give permission for one application to access some data from another account. I do OAuth2 authentication, but in the v2.0 we need to pass not resources, but scopes. For example I want to start/stop VirtualMachines, or just List them, what would be the proper scope for this?
I have found just this reference but I guess it is not valid for new flow https://learn.microsoft.com/en-us/azure/role-based-access-control/resource-provider-operations#microsoftaad
If you are signing in as yourself (i.e. with a signed-in user), then the scope value you want to request is https://management.azure.com/user_impersonation. After signing in (and granting consent, if needed), access to Azure resources will be dependent on the permissions the signed-in user.
If instead this is a secure server doing unattended access, then you simply use the "place-holder" scope parameter value https://management.azure.com/.default (as a way of indicating that you want an access token to https://management.azure.com).

Micorsoft Azure blob storage secruity

We are using MS Azure and developing SAAS based Multi-Tenant Application.
For each Tenant we have BLOB Container Private and assigned to each Tenant.
Also there is a requirement that Client can share files with other client users.
Eg.
Client C1 has Container "C1" and it has files "C1f1", "C1f2" and "C1f3".
User U1 and U2. U1 has access permission for C1f1 and U2 has C1f2 access only.
How can we do this in MS Azure Permission or Security? This needs to be done RUNTtime?
Please suggest How can this be done - What is BEST way to do
I believe you have two options.
Either generate and use SAS tokens per client/user with the right permissions. With a SAS token you can provide access to a specific resource up to a specific point in time. The disadvantage is that SAS tokens cannot be revoked on a per token basis. You can only revoke all tokens by rolling the storage access key that was used to generate the SAS token. Another disadvantage is that you have to provide a SAS token per item you want to grant access to. (For more info see also https://azure.microsoft.com/nl-nl/documentation/articles/storage-dotnet-shared-access-signature-part-1/)
Create a Web Service that encapsulates the Azure storage and serves files to your customers. In this service implement authorization management yourself.

how to revoke Shared Access Signature in Azure SDK

I could not find any code sample for revoking the created Shared Access Signature access on blob, can anyone provide me link or reference for removing the Shared Access Signature access created earlier.
Even if shared access signature (SAS) is based on a stored access policy (SAP), you can only revoke SAP, not individual SAS.
Azure Storage security guide has good details:
https://learn.microsoft.com/en-us/azure/storage/common/storage-security-guide#revocation
SAS not based on SAP - can't be revoked:
If you are using ad hoc URIs, you have three options. You can issue SAS tokens with short expiration policies and wait for the SAS to expire. You can rename or delete the resource (assuming the token was scoped to a single object). You can change the storage account keys. This last option can have a significant impact, depending on how many services are using that storage account, and probably isn't something you want to do without some planning.
SAS based on SAP - can be revoked by revoking SAP:
If you are using a SAS derived from a Stored Access Policy, you can remove access by revoking the Stored Access Policy – you can just change it so it has already expired, or you can remove it altogether. This takes effect immediately, and invalidates every SAS created using that Stored Access Policy. Updating or removing the Stored Access Policy may impact people accessing that specific container, file share, table, or queue via SAS, but if the clients are written so they request a new SAS when the old one becomes invalid, this will work fine.
Best practice:
Because using a SAS derived from a Stored Access Policy gives you the ability to revoke that SAS immediately, it is the recommended best practice to always use Stored Access Policies when possible.
Context
MSFT Azure storage account (live version as of 2019-11-26)
MSFT Azure storage permissions as managed by Shared Access Signature (SAS)
Problem
User user145610 wants to immediately revoke a deployed SAS
(e.g., because SAS allows authentication into Blob Storage, and the SAS has been compromised, requiring immediate remediation to prevent unauthorized data breach)
Workarounds already mentioned
Other answers already appear in this thread discussing the use of Shared Access Policy (aka Stored Access Policy) (SAP)
SAS generated based on SAP has limitations, only five SAPs can be attached to a a blob container within a storage account.
Workaround: Regenerating Account Keys
One workaround that does not appear in this thread (at the time of this posting) is the ability to regenerate the account key used to originally create the SAS, as documented in one of the links in the see also section of this answer.
Regenerating an account key will cause all application components using that key to fail to authorize until they're updated to use either the other valid account key or the newly regenerated account key. Regenerating the account key is the only way to immediately revoke an ad hoc SAS.
Consequently, one potential workaround is to generate and deploy SASs based on the secondary account key, and have the expectation that you will routinely regenerate the secondary account key whenever immediate revocation of one or more SASs becomes necessary.
(Obviously, this is not a desirable circumstance where many SAS tokens are deployed and dependent on the secondary account key, because they will all be rendered invalid upon regeneration of the key)
Solution
The inability to deploy a large number of SAPs, combined with the potentially unfavorable side-effects of having to regenerate account keys suggests that a potential solution is to re-engineer the architecture of your project to use ActiveDirectory for controlling authorization and access control, and the generation of SAS tokens.
SASs based on SAPs may be better suited for cases where there are only few clients requiring access, and the probability of the SASs getting compromised is extremely low.
As of this writing, MSFT Azure storage supports the generation and use of SAS tokens based on ActiveDirectory accounts.
See also
How many access policies can I create and add on the same one Azure container?
https://learn.microsoft.com/en-us/azure/storage/common/storage-auth
https://learn.microsoft.com/en-us/rest/api/storageservices/create-service-sas#revocation-of-a-sas
https://learn.microsoft.com/en-us/azure/storage/common/storage-sas-overview#types-of-shared-access-signatures
https://learn.microsoft.com/en-us/rest/api/storageservices/create-user-delegation-sas
https://learn.microsoft.com/en-us/azure/storage/common/storage-sas-overview#best-practices-for-using-sas
You can't revoke a shared access signature unless it is based on a stored access policy. See https://learn.microsoft.com/en-us/rest/api/storageservices/define-stored-access-policy#modifying-or-revoking-a-stored-access-policy for more information:
To revoke a stored access policy, you can either delete it, or rename
it by changing the signed identifier. Changing the signed identifier
breaks the associations between any existing signatures and the stored
access policy. Deleting or renaming the stored access policy
immediately effects all of the shared access signatures associated
with it.
Came across this topic too. As per highlighted by #IlyaBerdichevsky on the top, Best practice is to use a SAS derived from a Stored Access Policy.
TLDR;
Watch this youtube tutorial
(Step by step) How to create a SAS Derived from Store Access Policy?
First, setup Stored Access Policy
Go to your Azure Storage Resource
Click on containers (left panel under Data Storage), choose your container (because different container may setup different policy).
Click on Access Policy (left panel under Settings)
Click on Add policy
Here you may specify the desired policy you want (Sample in screenshot)
Click on OK
Tap on Save button on top (it reflects quickly actually, although it claimed to take about 30 seconds)
Second, generate SAS based on the SAP (Stored Access Policy) created
Back to Azure Storage Resource
Click on Storage Explorer (preview)
In my case I'm using Blob container, so I'll expand my blob container and click on the container I want. You shall see your file inside the container, once you've selected.
Right click on the file, click on Get Shared Access Signature.
Select the policy you have just created under the dropdown.
Tap on create
DONE! You've gotten your token now :)
How to revoke/extend the SAS token created for client?
Back to the policy you have setup
Update the expiry time
Save
TAAA-DAHH! Same link with the SAS token should expired/work now.
I had the same problem and this is how I solved it:
The communication between the redacted service and Azure Blob Storage is done through the SDK v8.0.

Resources