Skip to main content
emnode
Compliance Medium severity MCSB PV-2

Microsoft Defender for Cloud · Azure Functions

Function apps should have Client Certificates (Incoming client certificates) enabled

Written and reviewed by Emnode · Last reviewed

What does the recommendation "Function apps should have Client Certificates (Incoming client certificates) enabled" check?

Flags any function app where 'Client Certificates (Incoming client certificates)' is not enabled, meaning the platform never requests a certificate from callers and accepts any request that reaches the front end. The control reads the 'clientCertEnabled' property on the app; it does not check the certificate mode (Required, Optional or OptionalInteractiveUser), it does not validate the presented certificate, and it does not confirm that your code actually inspects the forwarded certificate. App Service injects the certificate as the X-ARR-ClientCert header and leaves verification entirely to your function. The audit applies to apps on HTTP/1.1, because incoming client certificates are ignored when HTTP/2.0 is enabled.

Why does "Function apps should have Client Certificates (Incoming client certificates) enabled" matter?

A function app with anonymous or key-based access alone is reachable by anything that can resolve its hostname, so a leaked function key or a misconfigured authorisation level is enough to invoke it. Function keys are long-lived secrets that travel in URLs, get pasted into pipelines and logs, and rarely rotate, which makes them a soft target. Requiring an incoming client certificate adds mutual TLS: a caller must present a certificate your code trusts before the request is processed, which is how internal-only or partner-only functions stay genuinely private even if a key escapes. Without it, an endpoint meant to be consumed by one trusted system is exposed to credential-replay and direct invocation, and a single compromised key can drive data exfiltration, run up consumption-plan billing, or abuse of downstream resources the function's managed identity can reach.

How do I fix "Function apps should have Client Certificates (Incoming client certificates) enabled"?

  1. Turn on incoming client certificates: 'az functionapp update --name <app> --resource-group <rg> --set clientCertEnabled=true', then set the enforcement level with '--set clientCertMode=Required' so callers without a valid certificate are rejected at the platform.
  2. In Bicep, set 'clientCertEnabled: true' and 'clientCertMode: 'Required'' under the Microsoft.Web/sites resource properties, and add the validation logic in your function to check the X-ARR-ClientCert header, because App Service forwards the certificate but does not verify it for you.
  3. Audit the estate at scale by assigning the built-in policy without hardcoding its GUID: pid=$(az policy definition list --query "[?displayName=='Function apps should have Client Certificates (Incoming client certificates) enabled'].name" -o tsv); az policy assignment create --name require-funcapp-clientcert --policy "$pid" --scope <scope>.

Remediation script · bash

# Close the highest-impact Function app exposure first: wildcard CORS, remote
# debugging, weak TLS, and missing client certificates, app by app.
RG=my-rg
APP=ordersapiprod

# 1. Replace wildcard CORS with the origins that actually call the app.
az functionapp cors remove -g "$RG" -n "$APP" --allowed-origins "*"
az functionapp cors add    -g "$RG" -n "$APP" \
  --allowed-origins https://app.contoso.com https://admin.contoso.com

# 2. Turn off remote debugging and require modern TLS.
az functionapp config set -g "$RG" -n "$APP" \
  --remote-debugging-enabled false \
  --min-tls-version 1.2

# 3. Require incoming client certificates where the app expects them.
az functionapp update -g "$RG" -n "$APP" \
  --set clientCertEnabled=true --set clientCertMode=Required

# 4. Put App Service Authentication (Easy Auth) in front of an HTTP-triggered app
#    so anonymous callers are rejected before they reach your code.
az webapp auth update -g "$RG" -n "$APP" \
  --enabled true \
  --action LoginWithAzureActiveDirectory \
  --aad-client-id "$CLIENT_ID" \
  --aad-token-issuer-url "https://sts.windows.net/$TENANT_ID/"

# 5. Ratchet it shut: audit any future app that ships without authentication.
#    Look the built-in policy up by its exact display name, never hardcode the GUID.
pid=$(az policy definition list \
  --query "[?displayName=='Function apps should have authentication enabled'].name" -o tsv)
az policy assignment create \
  --name audit-funcapp-auth \
  --policy "$pid" \
  --scope "/subscriptions/00000000-0000-0000-0000-000000000000"

Full walkthrough (console steps, edge cases and verification) in the lesson Harden Azure Function apps.

Is "Function apps should have Client Certificates (Incoming client certificates) enabled" a false positive?

A function app fronted by Azure API Management or Application Gateway that already terminates mutual TLS and forwards only authenticated traffic over a private endpoint can legitimately leave incoming client certificates off, since the certificate check happens one hop earlier. It will still flag, because the control reads the app's own clientCertEnabled property rather than the trust boundary in front of it. The same is true of an app deliberately running HTTP/2.0, where the platform ignores incoming client certificates by design. In both cases, record a policy exemption on the resource rather than disabling the gateway's authentication or weakening the protocol just to clear the finding.