Every organization will be implementing custom app registrations sooner or later, either for automation or to integrate third party applications. As explained in previous blogs, there is an important distinction between delegated and application permissions. Delegated permissions are used when a user interactively sign-ins to the application and needs access to Microsoft 365 resources through the application. Application permissions are used when the application has to access resources when running in the background, such as a scheduled task.
Because application with applications permissions don’t have a user signing into them, they need another form of authorization. There are two possible forms of authentication (also referred to as client credentials) to be used: certificates and client servers.
Certificates vs secrets
While the choice for the right client credential is up to you, there are a few differences between the two that you should be aware of. It’s important to know these before you choose, because either one of them have their (dis)advantages.
Secrets can be created from the console and are configured with a predefined expiration that you are able to configure. When the expiration date has passed, the secret will not be valid anymore and sign-ins from the applications will fail. An application can have zero or more secrets added to it.
When you want to use certificate authentication, you need to upload a certificate to the Azure portal for the application to use. This can be a self-signed certificate or one you have bought from a known certificate authority. That certificate needs to be uploaded (without the private key) and added to the application. Now you can authenticate to the application by using the certificate with the private key. The expiration will depend on the expiration date you have chosen for the certificate.
It’s often asked: ‘Is one safer than the other?’. In my opinion, it all depends on how you handle them. Some people prefer a certificate, because administrators are more ‘careful’ with certificates. They are not as easy stored in plain text on the desktop or in the application. This makes the chance of the certificate leaking smaller, which is a big advantage. Secrets are easier to maintain but are often stored in public places without much thought. The most important thing to remember is that both certificates and client secrets are extremely powerful and handled with a lot of care. They should be stored in a secured place (such as an Azure Key Vault) and should audited for access. When I am creating secrets, I save them into my password vault immediately. From there I add them in the secure configuration of an application and immediately remove the content of my secret to avoid saving them unnecessarily.
While managing the client credentials for an application, it’s important to come up with a plan to handle both certificate and client secret expiration. Two things should be included here:
- A set of rules what expiration time should be used
- A planning to ensure expiration is followed-up upon and secrets are replaced in the application before they have expired.
Both action points are extremely important as they will enable you to secure your app registrations within Azure AD. Choosing what the expiration needs to be is a difficult one and isn’t done in a lot of organization. When creating a new client secret you have the choice to pick an expiration between 6 or 24 months (or setup a custom expiration). Microsoft recommends only giving secrets a lifetime of 6 months, which is a nice balance between security and not having to rotate the keys every day.
Before some UI changes, it was possible to create secrets that never expire which is extremely powerful. Client secrets are essentially the passwords to a service account and should be regularly rotated to ensure no leaked credentials are used to receive access to sensitive content. It’s advised to audit your current environment and update application using application secrets which are setup to never expire.
Besides that, expiration of client secrets should be monitored. Too often than not, they are not closely monitored and are forgotten to be updated before the expiration. By letting a client credential expire, you are opening your environment up to potential downtime. That’s why it’s important to monitor for expiration.
By default, Microsoft doesn’t provide for a way to be notified when a secret will happen. By using SenservaPro you can easily use the following query to identify applications who have an expired credential or have a credential that will expire soon.
SenservaPro_CL | where ControlName_s == "ApplicationPasswordCredentialExpiring" | extend values =parse_json(Value_s) | mv-expand values | where values.Tag == "ApplicationCredentialExpiryTime" | extend expiration=parse_json(values.Value), AppName = parse_json(Value_s).Value | distinct tostring(AppName), ControlName_s, Description_s, ObjectId_g, MitreControls_s, tostring(expiration)
This query can be added as a scheduled analytic rule within Azure Sentinel for which you can add a Playbook. This allows you to create an automated notification when a secret is about to expire.
When you are adding a new client secret, you might notice there is an option to add a description. While this field is optional, I would recommend you use this field to it’s full potential. If you have multiple client secrets for one application, it’s difficult to know where each secret is used and what the steps for updating are. I like to use the description to link to the right documentation, so that it’s easy to update the secret when it’s about to expire.
Because application permissions are tenant wide, I want to point out again that it’s important to think about the owners of applications. Owners of an application can add or remove client credentials independent of the permissions added to that app. Image an application that has application permissions on Sharepoint and Exchange. If a developer is added to that application, they can potentially access every mailbox/Sharepoint site available in the tenant. When you are adding additional owners, there are two things to be aware of:
- Monitor when new secrets are added and make sure the actions are legitimate
- Monitor the sign-ins of service principals and ensure credentials are used anywhere outside the predefined scope
If you have Azure resources that are consuming client secrets/certificates (such as App Services or Logic Apps), it’s recommended to use an Azure Key Vault. By using a key vault to store secrets, you receive a couple of benefits which will improve your security posture.
- Before an Azure service is allowed to access the Key Vault, it’s needs to be allowed within the Access Policies. An access policy defines what permissions a resource has on the vault. This allows you to configure that the resource has the ability to read the secret, but not alter it. While the administrator is able to update the secret (for renewal) but not read it.
- All events in a Key Vault are audited, these logs can be easily ingested into Azure Sentinel which enables you to monitor all events for anomalies.
- By configuring the built-in firewall, you are able to limit access to the Key Vault to only resources on the virtual network the Key Vault is attached too.
While creating client credentials for an application is really easy, there are some important things to remember. The purpose of this blog post is to make you think about your current processes and to optimize these to increase the security of your Azure AD environment.