If you’ve been following my blog for a while, you probably know that I like to work with the Microsoft Graph API for a lot of my scripts. Graph allows you a lot of flexibility when working with Microsoft 365 and exposes parts of the platform that there just aren’t available through PowerShell cmdlets. Retrieving a list of messages in a particular Teams channel for instance is an easy process once you are familiar with working with Graph.
I’ve previously detailed my Top 7 Tips for Working with the Graph API in PowerShell, here you’ll see the different methods of connecting to the Graph, specifically, with Delegated or Application permissions. As explained in that post, Delegated permissions authenticate on behalf of the user and require and interactive sign in. Application permissions however are where we can do a lot of our automation as they authenticate in the app context. Functionality available can differ between Delegated and Application permissions so be sure to check the Microsoft documentation for the endpoint and call you are using. Essentially, if you are performing a task on behalf of a user, then you need to use Delegated permissions.
In a lot of my examples of Application permissions, I use a Client Secret to authenticate out of convenience. Generating Client Secrets are a nice easy way of authenticating but for long term, it’s preferable to use certificate authentication for additional security as a Certificate is a lot more complex than a simple secret. It’s also important to note that when using secrets, they should never be stored in plain text within your code. Leveraging something like Azure KeyVault can vastly improve the security here.
Uploading the Public Key
You can generate a certificate in a multitude of ways for Graph authentication. As usual there are public CAs, Internal CAs and Self-Signed certificates. Using an internal CA if you have one is a nice way of having some governance over your authentication certificates but if you want to go down the self signed route, you can generate one directly in PowerShell (New-SelfSignedCertificate (pki) | Microsoft Docs). Once you have your certificate public key (in .cer, .pem or .crt format), you can upload it to your Application Registration from the Azure AD Portal as shown in Figure 1.
Authenticating with the Private Key
Uploading the Public Key to the app registration allows us then to use the Private Key (which we have stored securely) to authenticate. As I detailed in my previous posts, I recommend using the MSAL.PS PowerShell module to make authenticating and obtaining a Graph access token easy. First, install the module with the below command:
Once installed, the below code can be used to obtain authenticate and return a token. Note that the certificate can be within the certificate store or in a folder on the client machine, once the Private Key is available. Make sure to include the ClientID, TenantID and CertificatePath variables for your environment.
Import-Module MSAL.PS ##Declare Variables $ClientID = #<Add the Client ID of the App Reg here># $TenantID = #<Add the Tenant ID from AAD here># $CertificatePath = #<Add the Certificate Path Including Thumbprint here e.g. cert:\currentuser\my\6C1EE1A11F57F2495B57A567211220E0ADD72DC1 ># ##Import Certificate $Certificate = Get-Item $certificatePath ##Request Token $Token = Get-MsalToken -ClientId $ClientId -TenantId $TenantId -ClientCertificate $Certificate
This code, when run will return a token object and the $token.accesstoken value can be used in our requests. An example of this value is shown in Figure 2.
In this short post I have shown how we can use a certificate to authenticate with Graph API. I recommend checking out my post on Top 7 Tips for Working with the Graph API in PowerShell for more detail on the set-up of the App Reg which I have omitted here.
One thought on “Using Certificate Authentication with Graph API”
Pingback: Using Azure KeyVault to Secure Graph API Automation Scripts – Sean McAvinue