Utilizing a System-assigned managed identification in an Azure VM with an Azure Key Vault to safe an AppOnly Certificates in a Microsoft Graph or EWS PowerShell Script

Utilizing a System-assigned managed identification in an Azure VM with an Azure Key Vault to safe an AppOnly Certificates in a Microsoft Graph or EWS PowerShell Script One frequent and lengthy standing safety situation round automation is the bodily storage of the credentials your script must get, no matter process your making an attempt to automate executed. The more severe factor you are able to do from a safety standpoint is retailer them as plain textual content within the script (and there are nonetheless loads of folks on the market doing this) a greater choice is to do some encryption (ensuring you employ the Home windows Information Safety API) eg https://sensible365.com/weblog/saving-credentials-for-office-365-powershell-scripts-and-scheduled-tasks/ . Azure additionally affords some higher choices with potential to safe the credentials and certificates in RunBooks, so it’s just some clicks within the Gui and a few easy code to safe your credentials when utilizing a RunBooks.

On this put up I’m going to have a look at the problems round storing and accessing SSL certificates related to App solely token authentication that you simply is perhaps trying to make use of in Automation scripts. That is  extra for when you possibly can’t reap the benefits of Azure Runbooks and want the pliability of a VM.

In Change (and Change On-line) EWS Impersonation has been round for fairly a while, it affords the power to have a set of credentials that may impersonate any Mailbox proprietor. With the Microsoft Graph you could have App Solely tokens which affords an identical kind of entry with the extra performance to restrict the scope vastly to sure mailboxes and Merchandise sorts . With App Solely tokens you don’t have a username/password mixture however a SSL certificates or software secret (the later needs to be averted in manufacturing). So as an alternative of the priority across the bodily safety of the username and password mixture, your concern now’s across the safety of the underlying certificates.

One of the crucial vital factors is the time to begin occupied with the safety of the certificates is earlier than you generate it. Eg simply having a developer or Ops particular person generate it on their workstation leaving copies of the certificates file anyplace is the equal of the postit word on the monitor. That is the place the Azure KeyVault (or AWS KMS) can be utilized to safe each the creation of the certificates and supply the continuing storage and importantly Entry Management and Auditing. So from the purpose of the creation of the AppOnly cert you must be capable of have an audit path of who created it and who accessed it. The opposite benefit of getting the cert in a KeyVault is that it additionally makes it simple so that you can have a brief expiry on the certificates and automate the renewal course of which in tern makes your auth course of safer.

As soon as the authentication Certificates is saved within the KeyVault then the weakest hyperlink might be the authentication technique you then use to entry the KeyVault. Eg a person account might be granted rights to the KeyVault (which then make that person account the weakest hyperlink) or you might use one other Software secret or SSL Certificates to safe entry to the info plain of the KeyVault. In some unspecified time in the future all of those develop into self defeating from a safety standpoint as your nonetheless storing a credential (particularly should you then retailer that as plain textual content) and for a persistent risk actor this nonetheless leaves you uncovered.

A method of eliminating the storage of credentials is using Managed identities the place (“in my mind at least”) your trusting the infrastructure the place the code is operating. The only instance could be say you create an Azure compute operate and provides that operate a Managed identification, you possibly can then grant that entry to the KeyVault and your operate can now entry the certificates from the KeyVault after which authenticate to Azure and entry each Mailbox in your tenant. So now you could have positioned the belief within the code within the operate and the underlying safety of the operate (eg can the code be exploited, might any individual hack the deployment technique getting used and substitute the code with their very own And so on). With a System-assigned managed identification in an Azure VM your doing the identical factor however this time the purpose of belief is the Azure Digital Machine. So now its right down to the bodily safety measures across the Azure VM which turns into the weakest hyperlink. Nonetheless not infallible however your safety choices round securing VM are many, so with good planning and apply you ought to be in a position get a steadiness between flexibility and safety.
So lets have a look at a easy implementation of utilizing a System-assigned managed identification in a Azure VM in a Powershell Script to get a SSL Certificates from a KeyVault after which entry the Microsoft Graph utilizing an AppOnly token generated utilizing that certificates.

  1. This primary factor you want is an Azure Key Vault the place you could have enabled auditing https://docs.microsoft.com/en-us/azure/key-vault/key-vault-logging
  2. You might want to create an software registration in Azure AD on your app that shall be utilizing the SSL cert from the Keystore to generate a AppOnly token after which use Software permissions for the duty you need it to carry out. https://docs.microsoft.com/en-us/graph/auth-register-app-v2
  3. Ensure you then consent to the above software registration so it may be utilized in your tenant (The portal now make this very straight ahead)
  4. You want an Azure VM the place you could have enabled System-assigned managed identification https://docs.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/qs-configure-portal-windows-vm
  5. One your Azure VM has a System-assigned managed identification you must be capable of grant that secret-permissions so it could possibly entry the SSL certificates we’re going to retailer within the KeyVault eg 
  6. Subsequent step is create the Self Signed within the Azure Key Vault utilizing the Azure Portal
  7. At this step you must now be capable of entry the Self Signed certificates from the Key Vault in your VM with some easy PowerShell code. All you will want is the URL to Key Secret Identifier eg

      Them some code like


      $KeyVaultURL = "https://xxx.vault.azure.net/secrets/App1AuthCert/xxx99c5d054f43698f39c51f24440xxx?api-version=7.0"
      $SptokenResult = Invoke-WebRequest -Uri 'http://169.254.169.254/metadata/identification/oauth2/token?api-version=2018-02-01&useful resource=httpspercent3Apercent2Fpercent2Fvault.azure.internet' -Headers @{Metadata="true"}
      $Sptoken = ConvertFrom-Json $SptokenResult.Content material
      $headers = @{
      'Content material-Sort' = 'applicationjson'
      'Authorization' = 'Bearer ' + $Sptoken.access_token
      }

      $Response = (Invoke-WebRequest -Uri $KeyVaultURL -Headers $headers)
      $certResponse = ConvertFrom-Json $Response.Content material

      With the above instance you’ll see the next hard-coded URI

      http://169.254.169.254/metadata/identification/oauth2/token

      This isn’t one thing it's essential to change as 169.254.169.254 is

      The endpoint is obtainable at a well known non-routable IP deal with (169.254.169.254) that may be accessed solely from inside the VM

      https://docs.microsoft.com/en-us/azure/virtual-machines/home windows/instance-metadata-service

      So the above script makes use of this native Metadata Service to amass the entry token to entry the Azure KeyVault (because the System-assigned managed identification). One you could have the certificates uncooked knowledge from the KeyVault you possibly can then load it right into a Typed Certificates Object eg

      $base64Worth = $certResponse.worth
      $Certificates = New-Object System.Safety.Cryptography.X509Certificates.X509Certificate2
      $Certificates.Import([System.Convert]::FromBase64String($base64Worth))

      The final step is the certificates should be uploaded to the Software registration created in step 2 or added to the applying manifest both manually or pro-grammatically. eg the next is an instance to produces the required manifest format described right here https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-certificate-credentials

         
      $SptokenResult = Invoke-WebRequest -Uri 'http://169.254.169.254/metadata/identification/oauth2/token?api-version=2018-02-01&useful resource=httpspercent3Apercent2Fpercent2Fvault.azure.internet' -Headers @{Metadata="true"}
      $Sptoken = ConvertFrom-Json $SptokenResult.Content material
      $KeyVaultURL = "https://gspskeys.vault.azure.net/secrets/App1AuthCert/xxx99c5d054f43698f39c51f24440xxx?api-version=7.0"
      $headers = @{
      'Content material-Sort' = 'applicationjson'
      'Authorization' = 'Bearer ' + $Sptoken.access_token
      }
      $Response = (Invoke-WebRequest -Uri $KeyVaultURL -Headers $headers)
      $certResponse = ConvertFrom-Json $Response.Content material
      $base64Worth = $certResponse.worth
      $Certificates = New-Object System.Safety.Cryptography.X509Certificates.X509Certificate2
      $Certificates.Import([System.Convert]::FromBase64String($base64Worth))
      $bin = $Certificates.GetCertHash()
      $base64Thumbprint = [System.Convert]::ToBase64String($bin)
      $keyid = [System.Guid]::NewGuid().ToString()
      $jsonObj = @{ customKeyIdentifier = $base64Thumbprint; keyId = $keyid; kind = "AsymmetricX509Cert"; utilization = "Verify"; worth = $base64Worth }
      $keyCredentials = ConvertTo-Json @($jsonObj) | Out-File "c:temptmp.key"

      This places the certificates knowledge right into a file briefly which isn’t nice you possibly can truly use the Graph API to create an app registration and add the cert knowledge immediately which suggests the cert knowledge by no means must be export/import right into a file.

      Authenticating with the SSL Certifcate you retrieved from the KeyVault

      After getting the Certificates loaded you possibly can then use the ADAL library to carry out the authentication and get the AppOnly entry token you possibly can both use within the Microsoft Graph or EWS eg

      $ClientId = "12d09d34-c3a3-49fc-bdf7-e059801801ae"
      $MailboxName = "[email protected]"
      Import-Module .Microsoft.IdentityModel.Shoppers.ActiveDirectory.dll -Power
      $TenantId = (Invoke-WebRequest -Uri ('https://login.home windows.internet/' + $MailboxName.Break up('@')[1] + '/.well-known/openid-configuration') | ConvertFrom-Json).authorization_endpoint.Break up('/')[3]

      The ClientId is the ClientId from the applying registration in step 2 the next does the Authentication utilizing the configuration info from the above after which makes a easy Graph
      request that makes use of the App Solely Entry Token that's returned.

      $Context = New-Object Microsoft.IdentityModel.Shoppers.ActiveDirectory.AuthenticationContext("https://login.microsoftonline.com/" + $TenantId)
      $clientCredential = New-Object Microsoft.IdentityModel.Shoppers.ActiveDirectory.ClientAssertionCertificate($ClientId,$Certificates)
      $token = ($Context.AcquireTokenAsync("https://graph.microsoft.com", $clientCredential).Consequence)
      $Header = @{
      'Content material-Sort' = 'applicationjson'
      'Authorization' = $token.CreateAuthorizationHeader()
      }
      $UserResult = (Invoke-RestMethod -Headers $Header -Uri ("https://graph.microsoft.com/v1.0/users?`$filter=mail eq '" + $MailboxName + "'&`$Select=displayName,businessPhones,mobilePhone,mail,jobTitle,companyName") -Technique Get -ContentType "Application/json").worth
      return $UserResult

      A Gist of the complete script might be discovered right here

      Tags:

      Related Posts

      Leave a Reply