This check flags Azure App Services that have no built-in authentication layer, leaving every endpoint open to anonymous traffic. If your app handles internal tools, APIs, or anything not meant for the public, turn on App Service Authentication (Easy Auth) and require a login before requests reach your code.
Authentication is one of those things that feels like the application's job until you realize how often it never gets done. Internal dashboards, staging environments, admin panels, and "temporary" API endpoints all have a way of ending up on a public URL with no gate in front of them. Azure App Service gives you a way to close that gap at the platform level, and this check exists to tell you when you have not used it.
What this check detects
The appservice_noauth check looks at each Azure App Service in your subscription and reports any web app where authentication and authorization (commonly called Easy Auth) is not enabled. When this feature is off, the App Service platform passes every incoming request straight to your application code without verifying who is making it.
That is not automatically a problem. A genuinely public marketing site should serve anonymous traffic. But for the large category of apps that were never meant to be public, the absence of a platform-level auth layer means the only thing standing between an attacker and your app is whatever your code does, or fails to do.
Note: App Service Authentication runs as a module in the same sandbox as your app but before your code executes. Because it sits in the request pipeline, it can reject unauthenticated requests without your application framework being involved at all. This works for apps written in any language and even for apps you cannot modify.
Why it matters
The risk here is exposure of resources that were implicitly assumed to be private. A few patterns show up again and again in real incidents:
- Internal tools on public URLs. An ops dashboard or admin console gets deployed to App Service for convenience. It has a default
*.azurewebsites.nethostname, which is reachable from anywhere. Without auth, anyone who guesses or scans the URL can reach it. - APIs that trust the network. A backend API assumes it only ever receives traffic from a trusted frontend. In reality it answers any caller, so an attacker can hit endpoints directly and skip whatever validation the frontend was supposed to enforce.
- Forgotten staging and test slots. Non-production environments often hold real data, weaker secrets, or verbose error messages. They rarely get the same scrutiny as production, and they are frequently left wide open.
- Application auth that fails open. When authentication lives entirely in app code, a bug, a misconfigured route, or a bypassed middleware can leave endpoints unprotected. A platform-level gate gives you defense in depth so a single application mistake does not expose everything.
Once an unauthenticated endpoint is found, the attacker's path is short. They enumerate routes, probe for data leaks, look for an unprotected upload or admin function, and pivot. Search engines and scanning services index azurewebsites.net hostnames constantly, so "nobody knows the URL" is not a control.
Warning: Enabling Easy Auth changes how unauthenticated requests are handled. If you set it to require authentication on an app that legitimately serves anonymous traffic, or that uses its own auth flow, you can break existing users or API clients. Test on a slot before applying it to production.
How to fix it
You have two decisions to make: which identity provider to use, and what to do with unauthenticated requests. For most internal apps the answer is Microsoft Entra ID (formerly Azure AD) as the provider and "return HTTP 401/302" for unauthenticated requests so they are forced to log in.
Option 1: Azure Portal
- Open your App Service in the Azure Portal.
- In the left menu under Settings, select Authentication.
- Click Add identity provider.
- Choose Microsoft as the identity provider.
- Let Azure create a new app registration, or point to an existing one.
- Set Restrict access to Require authentication.
- For Unauthenticated requests, choose HTTP 302 Found redirect for browser apps, or HTTP 401 Unauthorized for APIs.
- Click Add.
Option 2: Azure CLI
First create or reference an app registration, then enable auth on the web app. The example below configures Entra ID and requires authentication for all requests.
# Variables
RG="my-resource-group"
APP="my-web-app"
TENANT_ID=$(az account show --query tenantId -o tsv)
# Create an app registration for the web app
APP_ID=$(az ad app create \
--display-name "${APP}-auth" \
--query appId -o tsv)
# Enable App Service Authentication with Entra ID
az webapp auth update \
--resource-group "$RG" \
--name "$APP" \
--enabled true \
--action RequireAuthentication \
--redirect-provider azureActiveDirectory \
--aad-client-id "$APP_ID" \
--aad-token-issuer-url "https://sts.windows.net/${TENANT_ID}/"
Danger: Running az webapp auth update with --action RequireAuthentication on a live app takes effect immediately. Any existing client that cannot complete the login flow, including unattended scripts and webhooks, will start receiving 401 or 302 responses. Apply this to a deployment slot first, validate, then swap.
Option 3: Infrastructure as Code (Bicep)
Codifying the auth config keeps it from drifting and makes the setting reviewable in pull requests.
resource authSettings 'Microsoft.Web/sites/config@2023-01-01' = {
name: 'authsettingsV2'
parent: webApp
properties: {
globalValidation: {
requireAuthentication: true
unauthenticatedClientAction: 'RedirectToLoginPage'
redirectToProvider: 'azureActiveDirectory'
}
identityProviders: {
azureActiveDirectory: {
enabled: true
registration: {
clientId: aadClientId
openIdIssuer: 'https://sts.windows.net/${tenant().tenantId}/'
}
}
}
platform: {
enabled: true
}
}
}
Tip: If you only need to restrict access to members of your organization and you do not want to manage tokens in your code, the redirect flow does all the work. Your app receives the authenticated user in injected headers like X-MS-CLIENT-PRINCIPAL-NAME, so you can read identity without writing any OAuth handling yourself.
How to prevent it from happening again
Fixing one app is easy. Stopping the next dozen from shipping without auth takes a control that runs without anyone remembering to check.
Azure Policy
Use a policy with the AuditIfNotExists effect to flag any App Service missing the authsettingsV2 resource. This surfaces non-compliant apps in the Azure Policy compliance dashboard so they cannot quietly accumulate.
{
"if": {
"field": "type",
"equals": "Microsoft.Web/sites"
},
"then": {
"effect": "auditIfNotExists",
"details": {
"type": "Microsoft.Web/sites/config",
"name": "authsettingsV2",
"existenceCondition": {
"field": "Microsoft.Web/sites/config/globalValidation.requireAuthentication",
"equals": "true"
}
}
}
}
CI/CD gates
If you deploy App Services through pipelines, scan the IaC before it reaches Azure. A Bicep or Terraform plan that creates a web app without an auth block should fail the build, not pass with a comment to "fix later." Tools like Checkov, tfsec, and your own policy-as-code checks can enforce this at the pull request stage where it is cheapest to correct.
Continuous monitoring
Policy and pipeline checks cover what you provision going forward. They do not catch a setting that someone disables manually in the portal during an incident and forgets to re-enable. Running appservice_noauth on a schedule with Lensix closes that loop by re-checking the live configuration of every App Service, not just the intended state in your templates.
Best practices
- Default to authenticated. Treat anonymous access as the exception that needs justification, not the starting point. A public site can have auth explicitly disabled with a documented reason.
- Layer your defenses. Platform auth, application-level authorization, and network restrictions are complementary. Easy Auth confirms who the caller is; your app still decides what that caller is allowed to do.
- Lock down non-production environments too. Staging and test apps deserve the same gate. They are where sensitive data hides and where attention is thinnest.
- Use managed identities downstream. Once you have authenticated the user at the edge, avoid passing static secrets between services. Pair auth with managed identities so the app's own access to storage, databases, and key vaults is identity-based.
- Restrict the public surface. Combine authentication with access restrictions or Private Endpoints so that internal apps are not even reachable from the open internet. Auth is your gate; network controls keep the gate from being the only thing between an attacker and your app.
- Review app registrations periodically. The app registration backing Easy Auth has its own permissions and redirect URIs. Audit them the way you would any other identity object.
App Service Authentication is one of the cheaper security wins in Azure. It takes minutes to enable, requires no code changes for the common case, and removes an entire class of "we forgot it was public" incidents. The hard part is consistency, and that is exactly what policy, pipeline gates, and continuous checks are for.

