When we work with Azure, we’ll often need applications, automation tools, or scripts to access Azure resources. Instead of using our personal login (which is risky and not scalable), Azure provides something called a Service Principal — an application identity used by tools and services to log in securely and perform specific tasks.
Think of a Service Principal as a “non-human user account” that Azure applications or automation tools can use to authenticate and access resources through role-based access control (RBAC). For example, Terraform, GitHub Actions, or Azure DevOps pipelines can use a Service Principal to deploy infrastructure automatically.
Most people use a client secret (like a password) for this authentication, but secrets expire quickly and can be risky if not handled properly.
A more secure and long-lived alternative is to use certificates, which rely on cryptographic keys instead of plain text credentials.
In this post, we’ll learn how to use certificates for Azure Service Principal authentication, especially useful for automation tools like Terraform, where security and stability are essential.
🧠 What Is a Certificate in This Context?
A certificate is like a digital key pair — one part public, one part private — used to prove an identity securely.
When you use a certificate for a Service Principal:
- The public certificate is uploaded to your Azure App Registration.
- The private key is stored securely on your machine, server, or key vault.
- Azure verifies your identity using the certificate — without exposing any secrets in plain text.
⚙️ Steps to Use a Certificate for Service Principal Authentication
⚙️ Prerequisites
Before you begin, make sure you have the following ready:
- An Azure subscription
- A Linux terminal — either on Ubuntu or WSL2 with Ubuntu on Windows following the post Getting Started with WSL2: Run Linux Inside Windows.
- Azure CLI installed and logged in. You can follow the blog post Getting Started with Azure CLI on Linux (Ubuntu) and Windows (WSL2 with Ubuntu) or Getting Started with Azure CLI on Your Local Machine.
- Terraform installed. You can follow the blog post Installing Terraform on Linux (Ubuntu) and Windows (WSL2 with Ubuntu) or Installing Terraform on MacOS.
1. Generate a Certificate
You can create a self-signed certificate using OpenSSL (for Linux, macOS, or WSL) or PowerShell (for Windows).
This certificate will act as a secure credential for your Service Principal.
🐧 Using OpenSSL (Linux / macOS / WSL)
If you’re on Linux, macOS, or Windows Subsystem for Linux (WSL), OpenSSL is the simplest and most common method.
Run the following commands in your terminal:
Step 1: Generate a private key
# Step 1: Generate a private key
openssl genrsa -out myazurekey.pem 2048
This creates a file myazurekey.pem, which is our private key.
Step 2: Create a self-signed certificate (valid for 1 year)
# Step 2: Create a self-signed certificate (valid for 1 year)
openssl req -new -x509 -key myazurekey.pem -out myazurecert.pem -days 365 -subj "/CN=MyAzureSPCert"
This creates a file myazurecert.pem, which is our public certificate.
Step 3: Combine Key and Certificate into One PEM (For Azure CLI Login)
The Azure CLI --certificate flag expects both the certificate and the private key together in one PEM file.
Combine them with:
cat myazurecert.pem myazurekey.pem > myazure-login.pem
💡 Order matters: Certificate first, then private key.
You can confirm with:
grep "BEGIN" myazure-login.pem
Output should show:
-----BEGIN CERTIFICATE-----
-----BEGIN PRIVATE KEY-----
You’ll use this combined file to log in with Azure CLI.
💡 Important Tips
- Keep your private key (
.pemor.pfx) safe — it’s used for authentication. - If you’re using automation tools like Terraform or Azure DevOps, you can upload the public certificate (
.pem,.cer, or.crt) to your App Registration in Azure Portal under
Microsoft Entra ID → App registrations → Certificates & secrets → Certificates.
Your automation workflow can then authenticate securely using the matching private key. - If you need a combined
.pfx(PKCS#12) file for tools that require it:openssl pkcs12 -export -out myazurecert.pfx -inkey myazurekey.pem -in myazurecert.pem
🪟 Alternate Option for Windows: PowerShell
In our post, we are using WSL in Windows. You can also create a self-signed certificate directly in PowerShell using the New-SelfSignedCertificate command. This generates a certificate inside the Windows certificate store, and you can then export it as .cer and .pfx files for use with Azure. If you’re on Windows, you can generate a self-signed certificate directly with PowerShell as:
New-SelfSignedCertificate -CertStoreLocation "Cert:\CurrentUser\My" -Subject "CN=MyAzureSPCert"
This creates a certificate in your local certificate store. After creation, export the certificate and private key (.cer and .pfx) from the certificate store, then upload the .cer file to your App Registration. We will discuss this in a separate blog post.
2. Register the Certificate in Azure
Once you have your certificate, you can either create a new Service Principal or update an existing one to use that certificate for authentication.
This approach is the most efficient for automation and scripting, especially when working with Terraform, CI/CD, or Azure DevOps.
🪄 Create a New Service Principal Using Your Existing Certificate
🐧 Using Azure CLI in Linux / macOS / WSL
Run the following command in your terminal:
az ad sp create-for-rbac \
--name MyCertSP \
--cert "@myazurecert.pem" \
--role Contributor \
--scopes /subscriptions/<your-subscription-id>
Step 1: Replace <your-subscription-id> with your actual Azure Subscription ID.
Step 2: Replace myazurecert.pem with the path to your public certificate file.
This command will:
- Create a new Service Principal
- Associate it with your existing certificate
- Assign it the Contributor role at the specified subscription scope
We should get a response similar to the following:

💡 Tip:
You can use other roles (like Reader or Owner) depending on your security needs. Always follow the least privilege principle.
💡 Note on the “@” Symbol:
When you prefix a filename with @ (like @myazurecert.pem), Azure CLI automatically reads the contents of that file and passes it as the parameter value.
In this case, it uploads your public certificate directly to Azure.
- Works in Linux/macOS/WSL as-is.
- In PowerShell, since
@has a special meaning, use'@filename'(single quotes) or$(cat filename)for compatibility.
✅ Both methods achieve the same result — securely associating your certificate with the new Service Principal.
🪟 Alternate Option for Windows: PowerShell
If you’re using PowerShell, the same command works with minor quoting differences:
az ad sp create-for-rbac --name MyCertSP --cert '@myazurecert.pem' --role Contributor --scopes /subscriptions/<your-subscription-id>
or
az ad sp create-for-rbac --name MyCertSP --cert "$(cat myazurecert.pem)" --role Contributor --scopes /subscriptions/<your-subscription-id>
Both commands securely upload your certificate’s contents and create the Service Principal.
🧩 Alternate Option: Add a Certificate to an Existing App Registration — Optional/Alternative
If your Service Principal (App Registration) already exists, attach your certificate to it instead of creating a new one.
🐧 Using Azure CLI in Linux / macOS / WSL
az ad app credential reset \
--id <appId> \
--cert "$(cat myazurecert.pem)" \
--append
Step 1: Replace <appId> with your Azure Application (Client) ID or Object ID.
Step 2: Run the command to upload your certificate and link it to the existing App Registration.
💡 Tip:
- The
--appendflag ensures existing secrets or certificates remain active. - If you don’t use
--append, existing credentials are replaced.
🪟 Alternate Option for Windows: PowerShell
In PowerShell, use one of these forms:
az ad app credential reset --id <appId> --cert '@myazurecert.pem' --append
or
az ad app credential reset --id <appId> --cert "$(cat myazurecert.pem)" --append
Both commands securely upload your certificate and link it to the existing App Registration.
💡 Cross-Platform Note:
- In Linux/macOS/WSL, you can use
--cert "@myazurecert.pem"directly. - In PowerShell, use
'@myazurecert.pem'or$(cat myazurecert.pem)for compatibility.
✅ Both methods safely upload and associate the certificate with your Service Principal for authentication.
⚙️ Alternate Option: Assign a Role (If Not Done Yet) — Optional/Alternative
If your Service Principal doesn’t already have permissions, assign a role using the following command:
az role assignment create \
--assignee <appId> \
--role Contributor \
--scope /subscriptions/<your-subscription-id>
💡 Tip:
You can also assign roles at a resource group or specific resource level if you want more granular access control.
3. Authenticate Using the Certificate
If you’re using Azure CLI, you can authenticate like this:
az login --service-principal \
-u appId \
--tenant tenantId \
--certificate myazure-login.pem
If login is successful, we should get a response similar to the following.

Alternatively, if you created the Service Principal with the certificate directly:
az ad sp create-for-rbac --name MyCertSP --create-cert
This command creates both the Service Principal and a self-signed certificate automatically.
🔒 Why Use Certificates Instead of Secrets?
| Feature | Client Secret | Certificate |
|---|---|---|
| Security | Text-based, easier to leak | Encrypted private key |
| Expiry | Usually 1–2 years | Can last up to several years |
| Rotation | Must be done manually | Easier to manage |
| Storage | Often in scripts or pipelines | Can be stored securely (e.g., Key Vault) |
In short — certificates are better for production automation where you need long-lived, secure, and compliance-friendly authentication.
🧾 Summary
| Component | Description |
|---|---|
| Service Principal | Identity used by apps or automation |
| Certificate | Digital key pair for secure authentication |
| Where to Add | Entra ID → App registrations → Certificates |
| Use Case | Production pipelines, automation, CI/CD |
💡 Pro Tip
You can combine this approach with Azure Key Vault, storing the private key securely and letting your application fetch it dynamically.
This keeps credentials out of your code and configuration files entirely.
✅ In Short
If client secrets are like a password, certificates are like a secure badge — harder to forge, safer to keep, and better for production.