Skip to main content
The Microsoft 365 provider can use a Service Principal with Client Secret to authenticate to Microsoft 365 services. This is a common authentication method for automated processes and CI/CD pipelines.

How Client Secret Authentication Works

1

Load Configuration

The provider loads authentication configuration from either Terraform configuration or environment variables (M365_TENANT_ID, M365_CLIENT_ID, M365_CLIENT_SECRET)
2

Request Token

The provider constructs an OAuth 2.0 token request to Microsoft Entra ID’s token endpoint:
POST https://login.microsoftonline.com/{tenant-id}/oauth2/v2.0/token
Content-Type: application/x-www-form-urlencoded

client_id={client-id}&client_secret={client-secret}&scope=https://graph.microsoft.com/.default&grant_type=client_credentials
3

Validate Credentials

Microsoft Entra ID validates the client credentials by checking:
  • Client ID exists
  • Client secret is correct and not expired
  • App has been granted the requested permissions
4

Receive Access Token

If validation succeeds, Entra ID issues an access token in JWT format:
{
  "token_type": "Bearer",
  "expires_in": 3599,
  "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Imk..."
}
5

Make API Requests

The provider uses the access token for Microsoft Graph API requests:
GET https://graph.microsoft.com/v1.0/deviceManagement/deviceConfigurations
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Imk...

Prerequisites

  • A Microsoft Entra ID tenant
  • Permissions to create an app registration in your tenant

Setup

2

Add API Permissions

  • Navigate to “API permissions” in your app registration
  • Click “Add a permission” and select “Microsoft Graph”
  • Choose “Application permissions” for automation scenarios
  • Apply least privilege principles: Only add permissions specific to the resources you need to manage
  • Click “Grant admin consent” for these permissions
3

Create Client Secret

  • Navigate to “Certificates & secrets” in your app registration
  • Click “New client secret”
  • Provide a description and select an expiration period
  • Copy the secret value immediately (it won’t be displayed again)

Provider Configuration

HashiCorp Vault Integration

HashiCorp Vault provides a secure way to store and access secrets.

Store Credentials in Vault

vault kv put secret/microsoft365/credentials \
  tenant_id="00000000-0000-0000-0000-000000000000" \
  client_id="00000000-0000-0000-0000-000000000000" \
  client_secret="your-client-secret"

Retrieve with Vault Provider

data "vault_kv_secret_v2" "microsoft365_creds" {
  mount = "secret"
  name  = "microsoft365/credentials"
}

provider "microsoft365" {
  auth_method = "client_secret"
  tenant_id   = data.vault_kv_secret_v2.microsoft365_creds.data["tenant_id"]
  entra_id_options = {
    client_id     = data.vault_kv_secret_v2.microsoft365_creds.data["client_id"]
    client_secret = data.vault_kv_secret_v2.microsoft365_creds.data["client_secret"]
  }
}

Security Considerations

Important Security Practices
  • Follow the principle of least privilege
  • Never commit secrets to version control
  • Regularly rotate your client secrets (typically every 90 days)
  • Use a secrets manager (Azure Key Vault, HashiCorp Vault, GitHub Secrets)
  • Consider using certificate-based authentication or OIDC for production environments

Troubleshooting

Verify the tenant ID, client ID, and client secret are correct. Check for typos and ensure the values haven’t been truncated.
Ensure you’ve granted admin consent for the required permissions in your app registration.
Check if your client secret has expired and create a new one if necessary. Set up alerts before expiration.
Your app registration needs appropriate Microsoft Graph permissions. Consult the provider documentation for the specific permissions required by each resource.

Build docs developers (and LLMs) love