ServicesAboutGet Started
Microsoft 365Entra IDGraph API

Creating a Microsoft Graph API App Registration

Register an application in Microsoft Entra ID for server-to-server access to the Microsoft Graph API. This guide covers app registration, API permissions, client secret creation, and recommended security hardening.

💡

This guide uses the client credentials OAuth 2.0 flow — designed for background services and automation scripts that run without user interaction. No user sign-in is required.

Microsoft Entra ID (formerly Azure Active Directory) is the identity platform behind Microsoft 365. To call the Graph API from a script or service, you need an app registration that defines what the application is allowed to do and a client secret that proves its identity.


1. Sign in to the Entra admin center

Open entra.microsoft.com and sign in with a Global Administrator or Application Administrator account.


2. Create a new app registration

Navigate to Identity → Applications → App registrations and click New registration.

Fill in the registration form:

FieldValue
NameA descriptive name for your application (e.g. Proxmox Mail Alerts)
Supported account typesAccounts in this organizational directory only (single tenant)
Redirect URILeave blank — not needed for client credentials

Click Register.


3. Note the application identifiers

After registration, you are taken to the app's Overview page. Copy these two values — you will need them for your application's configuration:

Label in portalConfig variable
Application (client) IDGRAPH_CLIENT_ID
Directory (tenant) IDGRAPH_TENANT_ID

4. Add API permissions

Navigate to API permissions in the left sidebar and click Add a permission.

In the panel that opens:

  1. Select Microsoft Graph
  2. Select Application permissions (not Delegated)
  3. Search for Mail.Send and check the box
  4. Click Add permissions
⚠️

Application permissions and Delegated permissions are different. Application permissions run as the app itself (no user context). Delegated permissions require a signed-in user. For background services and scripts, you need Application permissions.

Grant admin consent

After adding the permission, click Grant admin consent for [your org] and confirm. The status column should change to a green checkmark with Granted for [your org].


5. Create a client secret

Navigate to Certificates & secrets in the left sidebar, select the Client secrets tab, and click New client secret.

FieldValue
DescriptionA label to identify this secret (e.g. proxmox-pve1)
ExpiresChoose an expiration period (maximum 24 months)

Click Add. The secret Value is shown only once — copy it immediately. This is your GRAPH_CLIENT_SECRET.

⚠️

The secret value is only displayed once. If you navigate away without copying it, you must delete the secret and create a new one. Store it securely.

💡

Record the expiration date and set it as CREDENTIAL_EXPIRES in your application's configuration file. Scripts like our Proxmox and DNF mail handlers will warn you when credentials are within 60 days of expiring.


6. Verify your configuration values

At this point you should have all four values needed for Graph API authentication:

text
GRAPH_TENANT_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
GRAPH_CLIENT_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
GRAPH_CLIENT_SECRET=your-secret-value-here
GRAPH_SENDER=alerts@yourdomain.com
💡

GRAPH_SENDER is the mailbox the app will send as. This must be a licensed mailbox (or shared mailbox) in your Microsoft 365 tenant. See the hardening section below for restricting which mailboxes the app can impersonate.


7. Test authentication

You can verify the credentials work by requesting an access token from the command line:

bash
curl -s -X POST "https://login.microsoftonline.com/TENANT_ID/oauth2/v2.0/token" \
  -d "client_id=CLIENT_ID" \
  -d "client_secret=CLIENT_SECRET" \
  -d "scope=https://graph.microsoft.com/.default" \
  -d "grant_type=client_credentials" | python3 -m json.tool

A successful response contains an access_token field. If you see an error, double-check your tenant ID, client ID, and client secret.


8. Recommended hardening

Restrict the sender mailbox

By default, Mail.Send application permission allows the app to send as any mailbox in your tenant. Use an application access policy in Exchange Online to restrict it to a specific mailbox.

In Exchange Online PowerShell:

powershell
# Create a mail-enabled security group containing only the allowed sender(s)
New-DistributionGroup -Name "Graph Mail Senders" -Type Security -Members alerts@yourdomain.com

# Create the access policy
New-ApplicationAccessPolicy \
  -AppId "YOUR_CLIENT_ID" \
  -PolicyScopeGroupId "Graph Mail Senders" \
  -AccessRight RestrictAccess \
  -Description "Restrict Graph app to alerts mailbox only"
💡

Application access policies can take up to 30 minutes to propagate. Test after waiting. If sending fails with an access denied error immediately after policy creation, wait and retry.

Use certificate authentication (optional)

For higher security environments, consider using a certificate credential instead of a client secret. Certificates cannot be accidentally exposed in logs and do not need to be rotated as frequently. Microsoft's documentation covers the certificate credential flow.


Summary

You now have a registered application in Microsoft Entra ID with:

  • A client ID and tenant ID for identification
  • A client secret for authentication
  • Mail.Send application permission with admin consent
  • (Optional) An application access policy restricting the sender mailbox

Use these credentials in any application that needs to send email via the Microsoft Graph API — including our Proxmox email notification and DNF5 automatic email guides.