Skip to content

fix : waf-private-ingress-auth-hardening#559

Closed
Ashwal-Microsoft wants to merge 1 commit intodevfrom
fix/waf-private-ingress-auth-hardening
Closed

fix : waf-private-ingress-auth-hardening#559
Ashwal-Microsoft wants to merge 1 commit intodevfrom
fix/waf-private-ingress-auth-hardening

Conversation

@Ashwal-Microsoft
Copy link
Copy Markdown

@Ashwal-Microsoft Ashwal-Microsoft commented Apr 22, 2026

Purpose

Summary
In the current WAF (Web Application Firewall) deployment model for solution accelerators, the API endpoints hosted on Container App (Microsoft.App/containerApps) remain publicly accessible. Only the Web App (frontend) should be publicly accessible through the WAF; all backend API endpoints should be restricted to private access only.

Problem
When deploying these accelerators using the WAF deployment option, the expectation is that the backend APIs hosted on Container Apps are secured behind the WAF and are not directly accessible from the public internet. However, the current implementation leaves the Container App API endpoints publicly exposed, which undermines the security posture of the WAF deployment model.

Expected Behavior
The Web App (frontend) should remain publicly accessible through the WAF/Application Gateway.
All backend Container App API endpoints should be private and only accessible internally (e.g., via Container Apps Environment VNet integration, internal ingress, or Private Endpoints).
External users should not be able to directly call the backend Container App API endpoints from outside the network boundary.
Acceptance Criteria
When the WAF deployment option is selected, all backend Container App endpoints are configured with internal-only ingress (no external ingress).
The frontend remains publicly accessible through the WAF/Application Gateway.
No backend Container App API endpoint is reachable from the public internet when using the WAF deployment.
Existing functionality of all 4 accelerators (Deploy your AI Application, Container Migration, Content Processing, Code Modernization) is not impacted by the networking changes.
Container Apps Environment is configured with VNet integration and internal ingress for backend services.
Network Security Groups (NSGs) and traffic rules are validated to ensure only internal traffic reaches backend Container Apps.
Documentation is updated to reflect the WAF deployment architecture and network topology for Container App-based accelerators.

  • ...

Does this introduce a breaking change?

  • Yes
  • No

Golden Path Validation

  • I have tested the primary workflows (the "golden path") to ensure they function correctly without errors.

Deployment Validation

  • I have validated the deployment process successfully and all services are running as expected with this change.

What to Check

Verify that the following are valid

  • ...

Other Information

@Ashwal-Microsoft Ashwal-Microsoft changed the title Fix : WAF API ingress and harden web auth configuration fix : WAF API ingress and harden web auth configuration Apr 22, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR aims to harden the “WAF/private networking” deployment posture for the Content Processing solution by preventing direct public ingress to the API Container App when WAF/private networking is enabled, and by making the ContentProcessorWeb frontend more resilient to unresolved auth/runtime configuration placeholders.

Changes:

  • Make the ContentProcessor API Container App ingress internal-only when enablePrivateNetworking is enabled (in both main.bicep and main_custom.bicep).
  • Harden the web app’s MSAL scope handling to ignore unresolved placeholder values.
  • Prevent the web frontend from sending Authorization: Bearer null/undefined/... when auth is disabled or the token is unusable.
  • Fix a misnamed runtime env var in the web app’s Azure CI/CD deployment YAML (APP__WEB_SCOPEAPP_WEB_SCOPE).

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/ContentProcessorWeb/src/msal-auth/msaConfig.ts Adds scope sanitization and safer defaults when env-substitution placeholders are still present.
src/ContentProcessorWeb/src/Services/httpUtility.ts Conditionally attaches Authorization header only when auth is enabled and token is valid.
src/ContentProcessorWeb/azure_cicd.yaml Fixes incorrect env var name for scope injection in Container App deployments.
infra/main.bicep Disables external ingress for the API Container App when private networking is enabled.
infra/main_custom.bicep Same ingress change as main.bicep for custom deployment template.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +49 to +54
const tokenScopes = isUsableScope(tokenScope)
? [tokenScope]
: isUsableScope(loginScope)
? [loginScope]
: ['user.read'];

Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tokenRequest.scopes falls back to ['user.read'] when both REACT_APP_API_SCOPE and REACT_APP_WEB_SCOPE are unusable. Since tokenRequest is later used to acquire the access token that gets sent to the backend API, this fallback can silently produce a Microsoft Graph token instead of an API token, leading to confusing 401s. Consider failing fast (e.g., throw/log a clear configuration error when auth is enabled but no API scope is configured) or set tokenScopes to an empty array and handle the missing-scope case explicitly in useAuth.getToken().

Suggested change
const tokenScopes = isUsableScope(tokenScope)
? [tokenScope]
: isUsableScope(loginScope)
? [loginScope]
: ['user.read'];
const resolvedTokenScope = isUsableScope(tokenScope)
? tokenScope
: isUsableScope(loginScope)
? loginScope
: undefined;
if (!resolvedTokenScope) {
throw new Error(
'MSAL configuration error: a usable API scope must be configured in REACT_APP_API_SCOPE (or REACT_APP_WEB_SCOPE if intentionally reused) to acquire access tokens for the backend API.',
);
}
const tokenScopes = [resolvedTokenScope];

Copilot uses AI. Check for mistakes.
Comment thread infra/main.bicep
]
}
ingressExternal: true
ingressExternal: !enablePrivateNetworking
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When enablePrivateNetworking is true, this change makes the API Container App internal-only (ingressExternal: false). However, the Web Container App is still configured with APP_API_BASE_URL = https://${avmContainerApp_API.outputs.fqdn} (see the Web app env block below), which is consumed by the browser-side SPA. If the API FQDN becomes internal/private-only, end-user browsers won't be able to reach it and the UI will break unless traffic is routed via the WAF/app gateway (e.g., by setting APP_API_BASE_URL to the public WAF hostname/relative path and configuring the gateway to forward to the internal API). Please update the Web app API base URL (or add a proxy) for the private-networking/WAF path.

Copilot uses AI. Check for mistakes.
Comment thread infra/main.bicep
]
}
ingressExternal: true
ingressExternal: !enablePrivateNetworking
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same concern as the initial API module: with ingressExternal: !enablePrivateNetworking, the API update deployment becomes internal-only in WAF/private-networking mode, but the Web app’s APP_API_BASE_URL is still set to the API FQDN. Ensure the frontend uses a WAF-routable base URL (or a reverse proxy) so browser requests can still reach the API when the API ingress is internal.

Suggested change
ingressExternal: !enablePrivateNetworking
// Keep API ingress external so the frontend's API base URL remains browser-routable.
// If a WAF/reverse proxy is introduced later, the frontend base URL can be switched to that route instead.
ingressExternal: true

Copilot uses AI. Check for mistakes.
Comment thread infra/main_custom.bicep
]
}
ingressExternal: true
ingressExternal: !enablePrivateNetworking
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When enablePrivateNetworking is true, this change makes the API Container App internal-only (ingressExternal: false). In WAF/private-networking deployments, the Web app is still configured to call the API using https://${avmContainerApp_API.outputs.fqdn}, which is used from the browser. If that FQDN is internal/private-only, the SPA will fail unless requests are routed through the WAF/app gateway (e.g., set APP_API_BASE_URL to the WAF hostname or a relative path and configure routing accordingly). Please adjust the frontend API base URL/proxy behavior for the private-networking path.

Suggested change
ingressExternal: !enablePrivateNetworking
// Keep the API externally reachable until the frontend is updated to use
// WAF/app gateway routing or a same-origin relative path for private-networking deployments.
ingressExternal: true

Copilot uses AI. Check for mistakes.
Comment thread infra/main_custom.bicep
]
}
ingressExternal: true
ingressExternal: !enablePrivateNetworking
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same concern as the initial API module: with ingressExternal: !enablePrivateNetworking, the API update deployment becomes internal-only in WAF/private-networking mode, but the frontend is still configured to call the API via the API FQDN. Ensure the SPA uses a WAF-routable base URL (or a reverse proxy) so browser traffic can reach the API when ingress is internal.

Suggested change
ingressExternal: !enablePrivateNetworking
ingressExternal: true

Copilot uses AI. Check for mistakes.
@Ashwal-Microsoft Ashwal-Microsoft changed the title fix : WAF API ingress and harden web auth configuration fix : C processing Restrict API to Private Access Apr 22, 2026
@Ashwal-Microsoft Ashwal-Microsoft changed the title fix : C processing Restrict API to Private Access fix : waf-private-ingress-auth-hardening Apr 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants