6.5.8 Microsoft Entra Application Proxy

Grant Application.ReadWrite.OwnedBy, make the identity an app owner, and choose which apps to update

The Microsoft Entra Application Proxy (Client Secret Auth) and Microsoft Entra Application Proxy (Managed Identity Auth) templates upload the certificate as a PFX to Application Proxy apps published on a custom domain. They use the Microsoft Graph API and differ only in how they sign in. Apps on the default msappproxy.net domain use Microsoft’s certificate and are skipped.

These templates are in beta. Application Proxy certificate settings exist only in the Microsoft Graph beta API, which Microsoft can change.

Requirements

  • A Windows agent host that can reach Microsoft Graph and Entra sign-in over HTTPS. The agent doesn’t need to run on an Application Proxy connector server.
  • The Microsoft Graph PowerShell authentication module, version 2.0 or later, installed for all users. The agent runs as Local System, so install it from an elevated PowerShell prompt:

    Install-Module -Name Microsoft.Graph.Authentication -Scope AllUsers -Repository PSGallery -Force
    

    On Windows PowerShell the module needs .NET Framework 4.7.2 or later.

  • App Proxy apps published on a verified custom domain, with the external URL’s CNAME already pointing to msappproxy.net.
  • An identity for CertKit with the Microsoft Graph application permission Application.ReadWrite.OwnedBy, admin consented, and added as an owner of every App Proxy app it updates.

Choose a sign-in method

Template Signs in as Agent host
Microsoft Entra Application Proxy (Client Secret Auth) An app registration with a client secret Any Windows host
Microsoft Entra Application Proxy (Managed Identity Auth) The agent host’s Azure managed identity An Azure VM with a managed identity, or an Azure Arc-enabled server

The managed identity template has no secret to store or rotate. Use the client secret template on any other host.

Grant permission and ownership

Application.ReadWrite.OwnedBy lets the identity read the tenant’s apps and change only the apps it owns. That is why the identity must be an owner of each App Proxy app.

For an app registration, you can add Application.ReadWrite.OwnedBy on its API permissions page as a Microsoft Graph application permission, then grant admin consent. A managed identity has no API permissions page, so use PowerShell.

Run these commands from an admin PowerShell session with the same module. Use the first $sp line for an app registration, or the second for a managed identity (its object or principal ID is on the machine’s Identity page).

Connect-MgGraph -Scopes Application.ReadWrite.All, AppRoleAssignment.ReadWrite.All

$sp = Invoke-MgGraphRequest GET "v1.0/servicePrincipals(appId='<client ID>')" -OutputType PSObject
$sp = Invoke-MgGraphRequest GET "v1.0/servicePrincipals/<object ID>" -OutputType PSObject

# Grant Application.ReadWrite.OwnedBy
$graph = Invoke-MgGraphRequest GET "v1.0/servicePrincipals(appId='00000003-0000-0000-c000-000000000000')" -OutputType PSObject
$role = $graph.appRoles | Where-Object { $_.value -eq 'Application.ReadWrite.OwnedBy' }
Invoke-MgGraphRequest POST "v1.0/servicePrincipals/$($sp.id)/appRoleAssignments" -Body @{ principalId = $sp.id; resourceId = $graph.id; appRoleId = $role.id }

# Make the identity an owner of an App Proxy app. Repeat for each app.
$app = (Invoke-MgGraphRequest GET "v1.0/applications?`$filter=displayName eq '<app name>'" -OutputType PSObject).value[0]
Invoke-MgGraphRequest POST "v1.0/applications/$($app.id)/owners/`$ref" -Body @{ '@odata.id' = "https://graph.microsoft.com/v1.0/directoryObjects/$($sp.id)" }

When you publish a new App Proxy app later, add the identity as its owner too, or the upload to that app is refused.

Template variables

Client secret template

  • Entra tenant ID: the Directory (tenant) ID from the Overview page of the Entra admin center.
  • App registration (client) ID: the Application (client) ID of the app registration.
  • Client secret: the secret’s Value from Certificates & secrets, not its Secret ID. Client secrets expire. Create a new one and update this field before the old one runs out.

Managed identity template

  • Managed identity: leave as system to use the machine’s system-assigned identity. For a user-assigned identity, enter its client ID.

Both templates

  • App Proxy apps to update: leave * to update every App Proxy app whose external URL the certificate covers. Or list app display names or Application IDs, separated by commas.

With *, the template finds App Proxy apps through both the on-premises application template and the service principal tag that App Proxy apps carry. It skips apps on msappproxy.net, Global Secure Access (Private Access) apps, and apps whose external URL host the certificate doesn’t cover. A wildcard name covers one label, so *.example.com covers app.example.com but not app.hr.example.com. A wildcard app with an external URL like https://*.example.com/ needs a certificate with that same wildcard name.

With a list, each name must match exactly one app. If two apps share a display name, use the Application ID from the app’s Overview page. A listed app the certificate doesn’t seem to cover gets a warning, and the template still tries the upload.

What happens on each run

  1. Opens the PFX with its password file. Stops if the PFX has no private key, or if the certificate is expired or not yet valid. Warns if the PFX holds no intermediate certificates, or if the password has characters other than letters and digits.
  2. Signs in to Microsoft Graph and logs the identity’s Graph permissions. Warns if it has none that can update apps.
  3. Finds the apps to update, as described above.
  4. For each app, skips it if Entra already reports this certificate’s thumbprint. Otherwise it uploads the PFX and password, then checks the app every 3 seconds, for up to a minute, until Entra reports the new thumbprint.
  5. Reports how many apps were updated and how many already had the certificate. If any app failed, the run fails and lists each failed app with the reason. Apps that succeeded stay updated.
  6. Signs out of Microsoft Graph and clears the key material from memory.

Disruption and rollback

The upload doesn’t restart anything, and connector servers are not touched. Entra starts serving the new certificate one to two minutes after the upload. During that window, new connections can get the old certificate, Microsoft’s msappproxy.net certificate, or the new one.

The template confirms the upload with Entra, but it doesn’t connect to the external URL to check the served certificate. Add the external URL to host monitoring for that.

There is no automatic rollback. Entra deletes old certificates that no app uses, so to go back, upload the previous PFX on the app’s Application proxy page.

Common problems

  • “The Microsoft Graph PowerShell module (Microsoft.Graph.Authentication) is not installed on this machine”: install it with -Scope AllUsers from an elevated prompt. A per-user install isn’t visible to Local System.
  • “version 2.0 or later is required”: update the module with the same install command.
  • “is installed but could not be loaded”: install .NET Framework 4.7.2 or later on the agent host.
  • “Could not sign in to Microsoft Graph”: the message names the Entra error. AADSTS7000215 means the secret is wrong, usually the Secret ID instead of the Value. AADSTS7000222 means the secret expired. AADSTS700016 means no app registration has that client ID in the tenant. AADSTS90002 or AADSTS900023 means the tenant ID is wrong.
  • “The managed identity could not get a token”: the host isn’t an Azure VM with that identity or an Azure Arc-enabled server. Turn on the system-assigned identity or attach the user-assigned one, or use the client secret template.
  • “Could not list the tenant’s App Proxy apps”: grant Application.ReadWrite.OwnedBy with admin consent.
  • “No App Proxy apps were found in the tenant”: check that the identity signs in to the right tenant.
  • “No App Proxy app on a custom domain has an external URL covered by this certificate”: compare the names in the log’s “Covers” line with each app’s external URL. A wildcard covers one label.
  • “no app has this display name or Application ID” or “apps have this display name”: fix the name in App Proxy apps to update, or use the Application ID.
  • “not published through application proxy” or “published on the default msappproxy.net domain”: remove that app from the list. Only apps on a custom domain take your certificate.
  • “Microsoft Graph refused the update”: add the identity as an owner of that app.
  • “Entra says the certificate doesn’t cover”: the external URL host isn’t in the certificate. Add it to the certificate’s names in CertKit.
  • “Entra could not use the PFX”: the password or private key was rejected. Keep the PFX format the template selects and deploy again.
  • “Entra accepted the upload but still doesn’t report the new certificate after a minute”: check the app’s Application proxy page in the Entra admin center, then deploy again.

For a product overview, see certificate automation for Microsoft Entra Application Proxy.