How to auto renew Azure AD App client secrets and store in Key Vault - azure-active-directory

Now that Microsoft has removed the "never expire" option from Azure AD app client secrets (and because generally it's good practice) I'm looking for a way to auto-renew a client or generate a new one and then save that value to Azure Key Vault.
I know of various ways to save a value to the Key Vault but I can't see any nice ways to programmatically track the expire of client secrets and renew/create new ones.
Does anyone know how to start going about this?

I can call this graph api to add a new secret.
The result is succeed.
But I can't see the newly created secret in Azure portal -> Azure AD -> target application -> Certificates & secrets, I can only see it in the Manifest blade. It's weird.
I also found an answer about using powershell command to create secrets. New-AzureADApplicationPasswordCredential -ObjectId "YourAppObjectId"

Related

Unexpected issuerAssignedId when trying to configure multi-tenant login using custom policies for Azure B2C

I have an existing IdentityServer4 installation that is used to federate users between things like Google & Microsoft into a single login identity. In my situation, there are no local user credentials/passwords. Just the identity with an associated external provider. I'm trying to migrate to using Azure B2C and am hitting some roadblocks.
I've found that if I use the same ClientId and ClientSecret that IdentityServer is configured with, then I get the same IDs for users when signing in via an external identity provider. Which is great because I need them to be the same in order to try and migrate accounts over by reading them from the existing MSSQL database, and importing into Azure B2C using MS Graph.
I need to allow both Microsoft work accounts, as well as personal ones. So I need to use custom policies to allow for a multi-tenant configuration, since the built in provider doesn't support this.
However as soon as I flip my implementation over from the built in user flows and provider, to using custom policies, I don't get the expected issuerAssignedId anymore. Originally, the IDs looked something like AAAAAAAAAAAAAAAAAAAAAHGFdaj94jfdsgjifdh4ngd (made up, but you get the idea). Now with the custom policies, the issuerAssignedId being recorded in the B2C user looks like a GUID. So not just a different value, but a total different format. Am I missing something here? What would happen if someone has an fully operational AzureB2C install with built in functionality, and later identified a need to move to custom policies. How would users ever be able to look into their existing accounts with an external identity provider?
My TechnicalProfile for the multi-tenant sign is is essentially copy/pasted from their documentation, so I'm not sure what the deal is here?

Interacting with Azure AD OAuth without storing the client secret

For Azure Active Directory, I created an app registration for my web app to enable SSO/OAuth 2.0 login for end users and to do AD lookups using the AD graph apis.
That requires me to use a client id and client secret and I have the requirement to not store the secret on the system when running inside of Azure VMs.
Is there a way using managed identities to either fetch the application secret or generate a token that can be used with the login.microsoftonline.com OAuth end points?
When you say "Web App" I'm making the assumption you are using something along the lines of an Azure App Service,
If the issue is with storing the client secret locally on the machine, the more secure way is to store the secrets in Azure KeyVault.
This stackoverflow post goes over why KeyVault is secure : Why is Azure Key Vault secure?
And the official docs provide a good overview/quickstart on getting started with Azure Keyvault. https://learn.microsoft.com/en-us/azure/key-vault/quick-create-portal
And this is a tutorial on using KeyVault with an Azure Web App: https://learn.microsoft.com/en-us/azure/key-vault/tutorial-net-create-vault-azure-web-app
Essentially secrets stay in Azure so that they're never exposed in code or on the development machine. And by using MSI, you won't need to keep track of credentials to access the keyvault. Keeping all important information in Azure.

Are the Azure Client Id, Tenant, and Key Vault URI considered secrets?

I'm getting up to speed with Azure and trying to follow best practices for securing my WPF and Xamarin.Forms apps.
I'm using Azure AD for authentication and Key Vault for my secrets.
What about my Client Id and Tenant settings? These are required to make the initial connection to Azure to log in.
The endpoint URI is also required to make a call to the Key Vault.
Are the Client Id, Tenant, Key Vault endpoint considered secrets or am I over thinking this. I understand without authenticating, no one can access or make use of these.
What about checking these into Source Control? Is this Ok?
Greatly appreciate your thoughts and insights.
Karl
TenantId is hardly a secret. You can get the tenant metadata of any Azure AD tenant using the following Url
https://login.microsoftonline.com/{tenantID/domain}/.well-known/openid-configuration
For example
https://login.microsoftonline.com/microsoft.onmicrosoft.com/.well-known/openid-configuration
ClientId also travels in http Urls and thus is not that hard to find out. That's why the focus should be to effectively protect access to the app using either token validation or user assignment.
Managed identities for Azure resources is available to help avoid checking in any credentials in source control and is specially useful with KeyVault.

Security Around Microsoft Azure AD AD "Application Access"

I have successfully configured qn Azure AD App Registration, allowing a client_credentials based OAuth 2.0 flow to work. This allows a third party application to access Microsoft Graph API. The app has "Calendar.Read" permission. Meaning the app can pretty much read any of the calendars (including CEO's).
I now have a conversation with security. What is out there in the Microsoft world, that I can use to lock down usage of API access via this Application Permission? Is there ability to do things like:
Restrict IP ranges the App can be accessed from?
Restrict users that can access the App? (However in Client_credentials, there is no user context)
Log traffic / activity happening via the App?
The only thing i can think of now is to say the Redirect URL configuration on the app means, no other application can get an access token using the Client_credentials, even if the application id & passkey get compromised
Any advice on further security controls that can be put in place?
Restricting access: You would need to do this in your application. The Client Credential flow doesn't allow for restricting what users as you point out. However there is nothing stopping you from adding user authentication to your application, possibly using a delegated graph auth flow to determine who they are.
IP Ranges: This is not possible currently.
Logging Traffic: This is not possible on the graph side currently, however you could/should log traffic on your applications side.
Redirect urls will not help you because they are not used int eh client credential flow.
In general application only auth (client credential flow) + a broad authorization scope is very powerful, but must be managed correctly. You don't inadvertently want to build a totally new users/permissions model over the top of the graph :)
There are very few options available currently available to offer these controls at token issuance (in Azure AD) or at API access (in Microsoft Graph). However, you can achieve similar results by carefully managing access to the app's credentials. Here are a couple steps you can take (not exhaustive):
App credentials: keep them secret, keep them safe
Use Key Vault. You can configure many of the restrictions you mention for access to data in Key Vault, including IP ranges and which users access. Key Vault also offers auditing of access to secrets. Don't forget to also be careful about which users have management access to the Key Vault (e.g. other users with access to the same Azure subscription).
Use certificates (public/private key pair), rather than client secrets (passwords), to authenticate the app. People tend to manage certificates much more carefully than they manage shared passwords, and developers are much less likely to hard-code the secret into scripts/code.
Be careful and deliberate about which users can manage the app's credentials
This is often overlooked. A user (or another app) who can access existing credentials, or add a new authorized credential to an app can act as the app and (mis)use all the permissions the app has been granted. This includes:
Users (and apps) in the "Company Administrator", "Application Administrator" and "Cloud Application Administrator" directory roles.
Users who are set as owners of the app registration (Application object) and enterprise app (ServicePrincipal object) for the app.
Users (or systems) who have access to the server or service the application resides on (which will have, or have access to, the credentials).
For all of these cases, ensure this is the smallest possible number of users, and they actually have a legitimate need. For users who do need access, wherever possible enforce just-in-time, time-limited access (not persistent access), such as with Azure AD Privileged Identity Management, for time-bound, just-in-time access for Azure AD directory roles and Azure resources.

Is there any way to access Azure Key Vault without azure AD?

I want to use azure key vault to store connection strings of console app which don't have azure ad authentication.
So, Is there any way to access Azure Key Vault without azure AD?
Unfortunately, you cannot access Azure Key Vault without Azure AD authentication for now.
Key vault client applications will need to access Azure Active Directory endpoints for authentication. The endpoint used depends on the Azure AD tenant configuration, the type of principal (user principal or service principal), and the type of account.
You can see more details about the Authentication of Azure Key Vault in this official document.
Also, if this is important to you, you can post you idea in this UserVoice Page. Azure Team will see it.
Not directly, no. Key Vault requires AAD authentication. You will need to have something/someone registered with AAD to retrieve secrets (your connection strings) from the Key Vault.
Do you specifically want to use Key Vault to store your connection strings or do you just want somewhere to keep them in Azure and aren't fixed on Azure Key Vault? If you aren't fixed on Key Vault, and aren't using it for anything else, maybe consider putting your connection strings in an Azure Storage Account? You could store the connection strings in an Azure Table, a file in an Azure Blob, or and Azure File, etc. Whatever works best for you - it'll still be encrypted at rest. https://learn.microsoft.com/en-us/azure/storage/
I'm guessing you don't want to go through authentication of the user, you'd just like to get to the connection strings. My answer is based on that assumption.
You'll still need something that acts as an intermediary for your console app. Something needs to authenticate within Azure to get to the connection strings. I'd suggest trying an https triggered Azure Function as a simple, lightweight way to do that. You can use function-level authorisation, in which you embed a function key in your native app's code. It uses that code in the GET call to the function endpoint to establish its authorisation to call the function. I found this link helpful when I did it:
http://dontcodetired.com/blog/post/Azure-HTTP-Function-Authorization-with-Function-Keys
The function can then either:
a) give out a time-limited Shared Access Signature to your Storage Account where the connection strings are, if you favour that approach, https://learn.microsoft.com/en-us/azure/storage/common/storage-dotnet-shared-access-signature-part-1
OR
b) actually store the connection strings in a local file in the function directory or as function app settings, if you're not actually wanting encryption-at-rest in Azure (local files are accessible through the function's optional ExecutionContext parameter's FunctionDirectory member)
OR
c) if you still want to use Key Vault, register your function app in AAD, and have it call through to Key Vault on behalf of your console app.
The https function app can then act as your gatekeeper, with a simple function key embedded in your console app as the authorisation. You can keep the return type of the function to just the connection strings you need, and not open anything else up to your console app.
An ASP.NET Web API service would do just as well, but the pay-for-use nature of Functions may make it more cost-effective if it's not called frequently (YMMV).
This is all based on the assumption you don't want to authenticate your users. If you do, but they're external and you don't want to use AAD, you may want to look into Azure B2C to authorise access. I haven't tried that yet, but here's the link:
https://azure.microsoft.com/en-gb/services/active-directory-b2c/

Resources