Pages

Monday, May 31, 2021

Configuring App-only authentication with certificates for unattended scripts with EXO V2 module

Those who have worked with Exchange Online PowerShell for a while will know how much a challenge it was to move from basic to modern authentication with MFA for unattended scripts that are scheduled to run non-interactively. The introduction and enforcement of modern authentication and MFA meant attempting to run unattended scripts would no longer work because it would require an administrator to interactively enter credentials and authenticate with the 2nd authentication. As such, many administrators continued to use basic authentication or modern authentication with accounts without MFA enforced to work around the issue, which leads to vulnerability issues. Microsoft originally had plans to disable basic authentication in 2020 but delayed it indefinitely.

Given the challenge as described above, I was extremely excited when Microsoft released the EXO V2 2.0.3 module for public preview in July 2020 where it introduced certificate based authentication. This meant it was now possible to connect to Exchange Online with unattended scripts that no longer passed a username and password, and therefore eliminating the issue where MFA is required upon authentication. I haven’t been working with Exchange Online for sometime due to my new role but was asked by an ex-colleague about setting up unattended scripts so I took the opportunity to capture the process while demonstrating the setup, which I will now use for this blog.

The Scenario

An organization wants to use a PowerShell script to export Office 365 audit logs of users’ events from Exchange Online, SharePoint Online, OneDrive for Business, Azure Active Directory, Microsoft Teams, Power BI, and other Microsoft 365 services with the Audit Log search feature in the following two Microsoft 365 consoles:

Office 365 Security & Compliance
https://protection.office.com/unifiedauditlog

Microsoft 365 compliance
https://compliance.microsoft.com/auditlogsearch

The log will then get emailed for review at the end of the month with a scheduled task.

The Challenge

As this will be an automated process that runs at the end of each month, attempting to setup a PowerShell script that requires using Connect-ExchangeOnline with basic or modern authentication means a username and password will be used with an account without MFA.

The Solution

With the release of EXO V2 2.0.3, unattended scripts (automation) scenarios can now authenticate using Azure AD applications and self-signed certificates.

How does it work?

The EXO V2 module uses the Active Directory Authentication Library to fetch an app-only token using the application Id, tenant Id (organization), and certificate thumbprint. The application object provisioned inside Azure AD has a Directory Role assigned to it, which is returned in the access token. Exchange Online configures the session RBAC using the directory role information that's available in the token.

image

The Tools

To accomplish the task above, we will require the following components:

  1. EXO V2 2.0.3 or higher module
  2. PowerShell Version 7 and higher
  3. Self-signed certificate
  4. PowerShell Script using the Search-UnifiedAuditLog (https://docs.microsoft.com/en-us/powershell/module/exchange/search-unifiedauditlog?view=exchange-ps)

This post will focus on setting up the components required for certificate based authentication but for those who are interested in #4, I’ve written another blog post and will provide the following link to that post:

Script to export audit logs for the current month from Office 365 using Search-UnifiedAuditLog
http://terenceluk.blogspot.com/2021/05/script-to-export-audit-logs-for-current.html

Official Microsoft Documentation

As always, I’d like to provide the official Microsoft documentation and other useful reference documents here:

App-only authentication for unattended scripts in the EXO V2 module
https://docs.microsoft.com/en-us/powershell/exchange/app-only-auth-powershell-v2?view=exchange-ps

Modern Auth and Unattended Scripts in Exchange Online PowerShell V2
https://techcommunity.microsoft.com/t5/exchange-team-blog/modern-auth-and-unattended-scripts-in-exchange-online-powershell/ba-p/1497387

About the Exchange Online PowerShell V2 module
https://docs.microsoft.com/en-us/powershell/exchange/exchange-online-powershell-v2?view=exchange-ps

Basic Authentication and Exchange Online – July Update
https://techcommunity.microsoft.com/t5/exchange-team-blog/basic-authentication-and-exchange-online-july-update/ba-p/1530163

UPDATE: Exchange Online deprecating Basic Authentication (Basic Auth)
https://docs.microsoft.com/en-us/lifecycle/announcements/exchange-online-basic-auth-deprecated

Step #1 – Required Module and PowerShell

Begin by obtaining the required PowerShell and EXO V2 modules as using the incorrect version of say, PowerShell, will cause the certificate based authentication to fail. Download and install the latest versions of the following:

ExchangeOnlineManagement 2.0.5 (the latest at the time of this writing)
https://www.powershellgallery.com/packages/ExchangeOnlineManagement

v7.1.3 Release of PowerShell (the latest at the time of this writing)
https://github.com/PowerShell/PowerShell/releases/tag/v7.1.3

While not a requirement, I highly recommend using Visual Studio Code and the PowerShell extension to write and test PowerShell scripts as the Windows built-in ISE only supports version 5:

Visual Studio Code
https://code.visualstudio.com/download

Using Visual Studio Code for PowerShell Development
https://docs.microsoft.com/en-us/powershell/scripting/dev-cross-plat/vscode/using-vscode?view=powershell-7.1

image

Step #2 – Register an application in Azure AD

In order to authenticate with the EXO V2 module’s Connect-ExchangeOnline with a certificate, you must register the an application in Azure AD, which will represent the unattended script.

Begin by logging into https://portal.azure.com, navigate to Azure Active Directory > App registrations:

image

Click on the New Registration button to register a new app that will represent the identity of the unattended script:

image

Provide a name for the application and select the appropriate account types option. For the purpose of this demonstration, we’re limiting to the single tenant so the following is selected:

Accounts in this organizational directory only (<YourOrganizationName> only - Single tenant)

The Redirect URI (optional) field is not required for what we’re trying to accomplish so leave Web as the selection and the URI empty.

image

The newly created registration of the application should now be displayed:

image

With the application created, we’ll need to assign the appropriate permissions to the application that will represent our unattended script. Proceed to navigate into the configuration of the registered application:

image

----------------------------------------------------------------------------------------------------------------------------

There are two ways to configure the appropriate permissions:

Option #1 – Use the Manifest configuration

This is the easiest as you simply edit the manifest properties, which will configure the permissions and remove the default Microsoft Graph > User.Read permissions as shown here in the API permissions:

image

Navigate to the Manifest configuration and locate requiredResourceAccess entry around line 44:

image

"requiredResourceAccess": [

{

"resourceAppId": "00000002-0000-0ff1-ce00-000000000000",

"resourceAccess": [

{

"id": "dc50a0fb-09a3-484d-be87-e023b12c6440",

"type": "Role"

}

]

}

],

image

Click Save to apply the changes:

image

Navigate to API permissions should now display the Exchange.ManageAsApp permissions configured:

image

Proceed to grant admin consent for the configured permission:

image

image

image

Option #2 – Use the API permissions configuration

The second option is to use the API permissions to manually add the preproperate permissions for the app:

image

Search for Office 365 Exchange Online:

image

Select Application permissions:

image

Under Exchange (1), select Exchange.ManageAsApp:

image

Grant admin consent for the Exchange.ManageAsApp permissions that was just assigned:

image

image

Remove the Microsoft Graph permissions:

image

image

----------------------------------------------------------------------------------------------------------------------------

Step #3 – Generate a self-signed certificate for the application that will be authenticating

The next step is to generate a self-signed X.509 certificate that the application will use to authenticate against Azure AD to request the app-only access token. It is also possible to use an internal or public PKI infrastructure for the certificate but this demonstration will use a self-signed certificate that can be generated locally on a Windows Server with PowerShell version 7.

Note that next Generation (CNG) certificates are not supported for app-only authentication with Exchange. CNG certificates are created by default in modern Windows versions. You must use a certificate from a CSP key provider.

To generate a self-signed certificate for authentication, log onto any Windows Server or desktop with PowerShell version 7 or newer and execute the following:

# Create certificate
$mycert = New-SelfSignedCertificate -DnsName "contoso.org" -CertStoreLocation "cert:\LocalMachine\My" -NotAfter (Get-Date).AddYears(1) -KeySpec KeyExchange

image

A certificate with the private key will be created in the local computer store:

image

The certificate with the private key located on the computer will be used to authenticate the identity of an unattended script. A corresponding certificate with the public key (without the private key) will need to be attached to the Azure AD application. Execute the following cmdlet to create a .cer file with the public key:

# Export certificate to .cer file
$mycert | Export-Certificate -FilePath mycert.cer

image

image

If the intention is to execute Connect-ExchangeOnline from the server where this self-signed certificate is generated then we can simply reference it with its thumbprint when we authenticate. If the script will reside on another server that may not be Windows or have the certificate imported into the local computer store then it is possible to export the certificate with the private key to a .pfx file, which can then be used to authenticate. Scenarios such as having an App Service that needs to authenticate against Azure AD can have the .pfx file stored in the Azure Key Vault and retrieved during the authentication process. Use the following cmdlet to export the certificate to a pfx file:

# Export certificate to .pfx file
$mycert | Export-PfxCertificate -FilePath mycert.pfx -Password $(ConvertTo-SecureString -String "P@ssw0Rd1234" -AsPlainText -Force)

Step #4 – Attach the self-signed certificate to the Azure AD application

The next step is to upload the certificate with the public key (without the private key) to the Azure AD application. Proceed to navigate to the App registrations configuration in the Azure portal and click into the application:

image

Navigate to Certificates & secrets and click on the Upload certificate button:

image

Upload the .cer export of the certificate:

image

The uploaded certificate will be displayed:

image

Step #5 – Assign the required Azure AD roles to the application

The last step for the configuration is the RBAC roles with the required permissions for the registered application so it is able to execute the required cmdlets with the EXO V2 module because authenticating with the certificate will not be in the context of a user. Not all of the Azure AD roles are currently supported but the following ones are:

  • Global administrator
  • Compliance administrator
  • Security reader
  • Security administrator
  • Helpdesk administrator
  • Exchange administrator
  • Global Reader

Begin by navigating to Azure Active Directory > Roles and administrators, search for the Exchange administrator role and open the properties:

image

Click on Add assignments:

image

Search for the app registration we created earlier to grant the service principal permissions:

image

Note how the registered app is now assigned Exchange administrator permissions:

image

Step #6 – Authenticate against Azure AD with Connect-ExchangeOnline using the certificate

We can now use the certificate to authenticate against Azure AD with the Connect-ExchangeOnline cmdlet. Proceed to obtain the Application (client) ID from the Overview properties of the registered application:

image

And the thumbprint of the certificate from the Certificates & secrets of the registered application or the certificate on the Windows operating system’s local computer store:

image

image

With the variable properties above, the following cmdlet can be used to authenticate.

Authenticating with a certificate stored on the Windows server or desktop’s Local Computer > Personal Certificates store

Ensure that the certificate is located in the appropriate store:

image

Connect-ExchangeOnline -CertificateThumbPrint "3D057B3299A75B824F326F1A8A64262F12C60958" -AppID "b6925809-be8c-441b-8915-1bbcc2f2b6fc" -Organization "contoso.onmicrosoft.com"

image

Authenticating with an exported PFX file

Alternatively, you can also use an exported PFX to connect via the following cmdlet:

Connect-ExchangeOnline -CertificateFilePath "C:\scripts\mycert.pfx" -CertificatePassword (ConvertTo-SecureString -String "<MyPassword>" -AsPlainText -Force) -AppID "36ee4c6c-0812-40a2-b820-b22ebd02bce3" -Organization "contoso.onmicrosoft.com"

Authenticating with a certificate object (e.g. retrieved from Azure Key Vault)

The last method to provide a certificate is to use a certificate object via the following cmdlet:

Connect-ExchangeOnline -Certificate <%X509Certificate2 Object%> -AppID "36ee4c6c-0812-40a2-b820-b22ebd02bce3" -Organization "contoso.onmicrosoft.com"

When the Certificate parameter is used, the certificate does not need to be installed on the computer where the command is executed. This parameter is applicable for scenarios where the certificate object is stored remotely and fetched at runtime during script execution. An example of this is when the certificate is stored in the Azure Key Vault.

Script to export audit logs for the current month from Office 365 using Search-UnifiedAuditLog

I was recently asked by a colleague who was looking for a way to automate the export of events from Exchange Online, SharePoint Online, OneDrive for Business, Azure Active Directory, Microsoft Teams, Power BI, and other Microsoft 365 services with the Audit Log search feature in the following two Microsoft 365 consoles:

Office 365 Security & Compliance
https://protection.office.com/unifiedauditlog

image

Microsoft 365 compliance
https://compliance.microsoft.com/auditlogsearch

image

**I believe the Audit search in the Microsoft 365 compliance portal will be replacing Office 365 Security & Compliance.

I haven’t written scripts for a while so I decided to create one the best that I could and have him modify it as needed. My PowerShell script uses the Search-UnifiedAuditLog cmdlet to export the audit logs of a user and the cmdlet’s documentation can be found here: https://docs.microsoft.com/en-us/powershell/module/exchange/search-unifiedauditlog?view=exchange-ps

Note that in order for the script to work, EXO V2 2.0.3 or later with PowerShell 7 will be required as authenticating with a certificate requires these two components. This example will use EXO V2 2.0.5 with PowerShell 7.1.3.

To allow for the script to export the audit logs of multiple users, create a txt file and add the user names on a line of its own as such:

image

The following is the script and few points describing what it does:

  1. Connects to O365 with Connect-ExchangeOnline and authenticates with a certificate to work around MFA through modern authentication
  2. Gets the first and last day of the month (the assumption is that this script will be ran the last day of the month at 11:59p.m.)
  3. Gets the month name
  4. Loops through each username in the txt file
  5. Uses Search-UnifiedAuditLog to export the audit logs starting at the beginning of the month to the last day of the month for a user into a CSV file
  6. Uses Send-MailMessage to email the CSV to two users by relaying off of an on-premise Exchange server (https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/send-mailmessage?view=powershell-7.1)

#Install-Module -Name ExchangeOnlineManagement

#Import-Module ExchangeOnlineManagement

Connect-ExchangeOnline -CertificateThumbPrint "3968B23E6A91C8F7FF4A9587341E9B0FDB50DB0E" -AppID "ac28a30a-6e5f-4c2d-9384-17bbb0809d57" -Organization "contoso.onmicrosoft.com"

# Get the first day and the last day of the current month

$date = Get-Date

$year = $date.Year

$month = $date.Month

$startOfMonth = Get-Date -Year $year -Month $month -Day 1 -Hour 0 -Minute 0 -Second 0 -Millisecond 0

$endOfMonth = ($startOfMonth).AddMonths(1).AddTicks(-1)

#Get the current month name

$monthName = (Get-Culture).DateTimeFormat.GetMonthName((Get-Date).Month)

#Loop through each entry in a text file containing usernames and use Search-UnifiedAuditLog to search the unified audit log, export to CSV and email out to user.

foreach ($alias in Get-Content C:\scripts\Users.txt) {

$useralias=$alias

$domain = '@contoso.com'

$user=$userAlias+$domain

$csvFileName=($userAlias + "-O365-Activities-" + $monthName + "-" + $year + ".csv")

Search-UnifiedAuditLog -StartDate $startOfMonth -EndDate $endOfMonth -UserIds $user | Export-Csv $csvFileName -NoTypeInformation

$mailSubject=$monthName + " " + $year + " " + $user + ' O365 Audit Log'

$mailBody="Sending " + $user + " O365 Audit Log for the month of " + $monthName + " " + $year + "."

Send-MailMessage -From 'O365 Audit Job <o365audit@contoso.com>' -To 'Terence Luk <tluk@contoso.com>', 'John Smith <jsmith@contoso.com>' -Subject $mailSubject -Body $mailBody -Attachments $csvFileName -Priority High -DeliveryNotificationOption OnSuccess, OnFailure -SmtpServer 'smtp.contoso.com'

}

The following is an output of the script using EXO V2 (2.0.5) with PowerShell 7.1.3:

image

The following is a sample output in the CSV audit log:

image

Monday, May 24, 2021

What is Azure Key Vault?

Azure Key Vault is arguably one of the most important services that Microsoft Azure provides to enable organizations to centrally and securely store encryption keys, secrets, and certificates. There aren’t many configuration parameters in Azure Key Vault but having an understanding of the 3 core components it stores, their purpose, and how the service works is important so this blog post serves to provide an overview and the configuration of this service.

As always, I would like to provide the following links to the official Microsoft Azure Key Vault documentation:

Azure Key Vault basic concepts
https://docs.microsoft.com/en-us/azure/key-vault/general/basic-concepts

About Azure Key Vault
https://docs.microsoft.com/en-us/azure/key-vault/general/overview

Azure Key Vault security
https://docs.microsoft.com/en-us/azure/key-vault/general/security-features

Best practices to use Key Vault
https://docs.microsoft.com/en-us/azure/key-vault/general/best-practices

Using secrets from Azure Key Vault in a pipeline
https://azuredevopslabs.com/labs/vstsextend/azurekeyvault/

What is Azure Key Vault?

Azure Key Vault provides the service to store 3 types of entities:

  1. Keys
  2. Secrets
  3. Certificates

These 3 entities fulfill various functionalities of applications, virtual machines and other services within Azure and also on-premise networks. Having Azure Key Vault centrally store these entities allow an organization to easily provision, manage, and audit access of the objects in the vault.

What type of “Keys” does Azure Key Vault Store?

The type of keys that are stored in an Azure Key Vault are keys used for encryption and are typically asymmetric encryption keys such as RSA and EC (Elliptic-curve). AES symmetric keys are also available but a managed HSM service will be required. An example of a service that would utilize the Azure Key Vault to store encryption key would be Azure Server-side Encryption (SSE) and Azure Disk Encryption (ADE). I’ve written two blog posts about how they work:

Azure Server-side Encryption (SSE) and Azure Disk Encryption (ADE) - Part 1 of 2
http://terenceluk.blogspot.com/2021/05/azure-server-side-encryption-sse-and.html

Azure Server-side Encryption (SSE) and Azure Disk Encryption (ADE) - Part 2 of 2
http://terenceluk.blogspot.com/2021/05/azure-server-side-encryption-sse-and_8.html

What type of “Secrets” does Azure Key Vault Store?

The type of secrets that Azure Key Vault stores can be:

  1. A string of characters or numbers that serves as a password
  2. A certificate that is uploaded.

Note that #2 has been deprecated and will eventually be removed because of the certificate store feature. Attempting to use a secret to store a certificate will display the following message:

This feature has been deprecated. Click here to go to your list of certificates and import a new certificate.

image 

An example of a service that would utilize the Azure Key Vault to store secrets would be an Azure App Service or Function that requires a place to safely store SQL Database connection strings, which contains information such as the credentials password. Rather than storing sensitive information in the application’s code, it can now use a URI to retrieve the string as a secret.

What type of “Certificates” does Azure Key Vault Store?

The Azure Key Vault provides management of x509 certificates that are used in many internet protocols with SSL/HTTPS being one of the most popular. Administrators are able to create self-signed and Certificate Authority generated certificates, as well as importing existing certificates. Certificate owners can implement secure storage and management of X509 certificates without interaction with private key material. Policies can be created to direct Key Vault to manage the life-cycle of a certificate and allow certificate owners to provide contact information for notification about life-cycle events of expiration and renewal of certificate. Certain level of automation for renewals are available selected issuers - Key Vault partner X509 certificate providers / certificate authorities.

An example of a service that would utilize the Azure Key Vault to store certificates can be an Azure Front Door service accessing the key vault to retrieve an X509 certificate to secure the frontend or an App Service similarly retrieving a certificate for its TLS/SSL binding.

----------------------------------------------------------------------------------------------------------------------------

With each feature described, I would like to provide the following diagram outlining the Azure Key Vault’s services and some resources that uses the service. Note that many services require one or more of Azure Key Vault’s services in order to secure their functionality or data.

image

Creating an Azure Key Vault

Creating an Azure Key Vault is fairly straight forward as there aren’t many configuration parameters available. The configuration settings that require consideration are as follows:

Key vault name
This value needs to be unique across all of the customers in Azure as the name will be used for the the access URL.

Region
The region placement of the key vault is important because you cannot move a key vault from one region to another and you cannot encrypt VMs with SSE or ADE if the Key Vault is not in the same region as the VM.

Pricing tier
There are two pricing tiers: Standard and Premium. The specifications for both versions are identical aside from Premium having the ability to use HSM-protected keys. Note that there is also a Managed HSM option that is not presented by the Azure Portal GUI but can be created through CLI or PowerShell (https://docs.microsoft.com/en-us/azure/key-vault/managed-hsm/quick-create-powershell#create-a-managed-hsm). I won’t be covering a Managed HSM in this post.

image

image

Soft-delete and Days to retain deleted vaults
Moving further down the Basics tab will display the Soft-delete and this is enabled by default with 90 days set. Losing keys, secrets, and certificates can mean losing access to services or data and having soft-delete provides a layer of protection against accidental deletion.

Purge protection
Purge protection is disabled by default but highly suggested to be enabled as this protects accidental purge of vaults as well as protection against malicious attempts to delete vaults and purge them in the event where there is unauthorized access.

image

The Access policy tab contains settings for the controlling access to the new key vault.

Enable Access to
The 3 access settings are not enabled by default but should be reviewed and enabled if the intention of the key vault is to be used with those services.

Azure Virtual Machines for deployment
Specifies whether Azure Virtual Machines are permitted to retrieve certificates stored as secrets from the key vault.

Azure Resource Manager for template deployment
Specifies whether Azure Resource Manager is permitted to retrieve secrets from the key vault. Instead of putting a secure value (like a password) directly in a template or parameter file, this value can retrieve the value from an Azure Key Vault during a deployment.

Azure Disk Encryption for volume encryption
Specifies whether Azure Disk Encryption is permitted to retrieve secrets from the vault and unwrap keys. Enabling this will allow ADE to use this key vault to store keys and secrets for BitLocker to encrypt a VMs.

Permission model
The permission model provides 2 methods of controlling access to the key vault.

Vault access policy
The default Vault access policies allows specific rights to be granted to an identity to operate with keys, secrets, and certificates. These settings are configured on a per vault basis and cannot be applied to Azure resource hierarchies such as Management Groups, Subscriptions, and Resource Groups.

The following are the specific rights that can be granted to an identity:

  • Key, Secret, Certificate Management
  • Key & Secret Management
  • Secret & Certificate Management
  • Key Management
  • Secret Management
  • Certificate Management
  • SQL Server Connector
  • Azure Data Lake Storage or Azure Storage
  • Azure Backup
  • Exchange Online Customer Key
  • SharePoint Online Customer Key
  • Azure Information BYOK

Azure role-based access control
Azure role-based access control, also known as Azure RBAC, is a more modern method to control access to the Key Vault that allows permissions to be granted based on predefined or custom created roles to an identity such as a user, group, service principal, or managed identity. Scope level such as management groups, subscriptions, and resource groups can be used as well

The following are RBAC Key Vault built-in roles for keys, certificates, and secrets access management:

  • Key Vault Administrator
  • Key Vault Reader
  • Key Vault Certificate Officer
  • Key Vault Crypto Officer
  • Key Vault Crypto User
  • Key Vault Crypto Service Encryption User
  • Key Vault Secrets Officer
  • Key Vault Secrets User

More information about the differences between the two types of permission model can be found here:

Migrate from vault access policy to an Azure role-based access control permission model
https://docs.microsoft.com/en-us/azure/key-vault/general/rbac-migration

image

As with other PaaS services, Service Endpoints and Private Endpoints are available:

image

Creating a Standard Azure Key Vault generally doesn’t take much time.

Azure Key Vault Keys

Once the Azure Key Vault is created, the first of the 3 types of objects is the Keys and as mentioned earlier in this post, these keys can be used for cryptographic operations like for SSE (CMK option) and ADE. To create a key for SSE or ADE, simply navigate to the Keys setting then click Generate/Import:

image

Options to create an RSA or EC keys with activation and expiration dates are presented:

image

Other than generating a key, Import and Restore Backup options are also available. These features are useful for scenarios for migrating services that previously stored encryption keys elsewhere into the key vault or restoring a backup if the key vault had been deleted:

image

image

The properties of the key can be reviewed by clicking onto the key:

image

The version of the key will be displayed and further details of the key can be reviewed by clicking on the version of interest:

image

Notice that it is possible to download the public key (this is an asymmetric key) but not the private key. It is also possible to modify the Activation date and Expiration date, and the Permitted operations on this key:

image

It is possible to back up the key:

image

Note the following message about where the backup can be restored:

The backup of this key will be encrypted to Azure Key Vault and can only be restored in Azure Key Vault within the same subscription. Please download and save this backup somewhere secure, as it will not be persisted following this browser session.

image

A .keybackup file will be available for download:

image

New versions of the key can be generated:

image

The options to generate a new key will be presented:

image

Then a new key will be generated and placed under CURRENT VERSION, while the previous key will be placed under OLDER VERSIONS:

image

With soft-delete enabled on the vault, any deleted keys will be recoverable with the Managed deleted keys within the retention configured:

image

Azure Key Vault Secrets

Secrets can be a string of characters for any service that needs to securely store the value (e.g. ARM template with an administrator password, an App Service with a SQL connection string). To create a secret, simply navigate to the Secrets setting then click Generate/Import:

image

As mentioned earlier, secrets used to be the service that can store certificates but the feature has since been deprecated:

image

image

Proceed to select Manual as the Upload options and configure the secret’s parameters as required:

image

The new secret will be displayed as such once created:

image

As with keys, versioning of the secret is provided:

image

Opening the properties of the secret will display configuration and the Secret Identifier of the secret which could be used by App Services to retrieve the secret from the key vault (permissions for the App Service will need to e configured):

image

Note how you can review the secret by clicking on the Show Secret Value button:

image

----------------------------------------------------------------------------------------------------------------------------

Example of how the Secret Identifier would be used for an App Service

The process of configuring an App Service to store and retrieve secrets in an Azure Key Vault is fairly straight forward so I would like to quickly demonstrate storing a SQL database connection string here.

Begin by creating an Azure Key Vault with Azure role-based access control as the Permissions Model:

image

You can also alternatively change the Permissions model of an existing Key Vault via the Access Policies configuration:

image

You won’t be able to browse the keys, secrets or certificates with Azure role-based access control set as the Permissions Model even though you may be an owner:

image

image

To correct this, grant yourself the Key Vault Administrator role via the Access Control (IAM):

image

image

With the Key Vault Administrator role assigned, you should now be able to browse the keys, secrets, and certificates:

image

Proceed to create a secret with the SQL connection string, open the secret and copy the Secret Identifer:

https://my-test-keyvault01.vault.azure.net/secrets/appService-to-SQLDB/e49822276fab4f28ac24a75bbfb5e104

image

Proceed to add the secret identifier reference to the Azure App Service Settings by opening the App Service configuration settings, then click on New Connection String:

image

Type the Name of the connection string (you can use the same name as the secret name in the key vault, configure the Value as:

@Microsoft.KeyVault(SecretUri=<Value of the Secret Identifier>)

For example:

@Microsoft.KeyVault(SecretUri=https://my-test-keyvault01.vault.azure.net/secrets/appService-to-SQLDB/e49822276fab4f28ac24a75bbfb5e104)

image

Next, we’ll need to grant the App Service permissions to access the secret in the key vault by using a System assigned identity. Proceed to select the Identity setting in the App Service, under the System assigned tab, turn on the Status:

image

Note the message indicating the app service will be registered with Azure Active Directory so it can be granted permissions to access resources protected by Azure AD (Azure role-based access control set as the Permissions Model for the key vault):

image

Proceed to click on Azure role assignments to assign permissions to the App Service:

image

Click on Add role assignment:

image

Grant the permissions to the App Service:

Scope: Key Vault
Subscription: <the subscription>
Resource: <the key vault>
Role: Key Vault Secrets User

image

image

With the connection string configured on the App Service, the connection string contents of the web.config can now be cleared.

----------------------------------------------------------------------------------------------------------------------------

Similar to keys, secrets can also be backed up. Instead of a .keybackup file, a .secretbackup file is created:

image

image

Attempting to open the backup file will display a series of scrambled text even though there is only 1 secret stored in the backup:

image

Another example of how a secret is used is for Azure Disk Encryption to store its secrets. Below is a screenshot of an Azure Key Vault used by ADE to store BitLocker BEKs (BitLocker Recovery Key):

image

Opening the secret will allow you to browse the BitLocker Recovery Key (BEK) details:

image

Azure Key Vault Certificates

The last object that the key vault stores are certificates. To create a certificate, simply navigate to the Certificates setting then click Generate/Import:

image

The Create a certificate menu will provide various certificate options:

image

The ability to generate a certificate request or import a certificate (PFX or PEM):

image

If a new certificate is to be created there are 3 options:

image

Lifecycle management can be managed by the Lifetime Action Type where the following options are available:

  • Automatically renew at a given percentage lifetime
  • Automatically renew at a given number of days before expiry
  • E-mail all contacts at a given percentage lifetime
  • E-mail all contacts at a given number of days before expiry

The automatically renew options will be dependent on whether the certificate was generated from an integrated CA.

image

Additional advanced policy configuration are available for the certificate:

image

The following is a request generated for a non-integrated CA:

image

image

Navigating into the request will allow you to browse the certificate request information:

image

Navigating back out to the Overview section and clicking on Certificate Operation will allow you to download the CSR as well as merge the signed request the signing CA provides:

image

image

Another method of place certificates into the key vault is to import a PEM or PFX. The following is an example of importing a PFX:

image

image

image

With the certificate imported in the key vault, we can now allow resources such as App Services to import the certificate from the key vault. Before proceeding to import the certificate, we’ll need to grant the App Service the required RBAC role to retrieve the certificate and this process and the role required is the Key Vault Secrets User. Once the appropriate role is assigned to the App Service, use the Import Key Vault Certificate feature under the Private Key Certificates (.pfx) tab to import the certificate from the key vault:

image

----------------------------------------------------------------------------------------------------------------------------

Note that if you attempt to import a certificate from a key vault that is not in the same region as the App Service then the process will fail with the following message with no other detail:

Import Key Vault Certificate
Failed to import Key Vault Certificate

image

----------------------------------------------------------------------------------------------------------------------------

Other services such as Azure Front Door can also leverage key vaults to import certificates:

image

How many Key Vaults should an organization have?

Microsoft general guideline is to have 1 key vault per application, per environment, per region. With that said, this can quickly grow to many key vaults in a large environment.

How can an organization manage Key Vaults at scale?

When a large organization has many key vaults distributed across the Azure because of the amount of applications and divisions, it is suggested to use Azure Policy manage organization compliance and set standards such as key sizes and validity periods. Auzre Policy can be applied to a scope within the organization (managemend group, subscription, resource group or individual key vault) and ensure all resources within the scope to be evaluated for compliance against the rule. Policies can be configured to only evaluate whether the resource meets a compliance rule or not, or enforce compliance and block the creation or import of objects that don’t meet the policy rule.

I will not go further into the details and will provide the following Microsoft document:

Integrate Azure Key Vault with Azure Policy
https://docs.microsoft.com/en-us/azure/key-vault/general/azure-policy?tabs=certificates

----------------------------------------------------------------------------------------------------------------------------

I hope this post is able to help anyone who may be looking for more information about how Azure Key Vault works, what the differences are between keys, secrets, and certificates, and what the configuration looks like.