Repository navigation
Fix first-time provisioning; add serverless Cosmos, custom domain, and Front Door options - #27
Merged
Merged
Conversation
…options A fresh `azd provision` could never finish: the Container App timed out with "Operation expired". Two independent bugs caused it, and both are fixed here alongside opt-in options found while deploying a new tenant. - Pull images from ACR with the user-assigned identity. The system-assigned identity only exists once the app does, so its AcrPull grant was created after the app and the first revision waited on it indefinitely. - Replace the containerapps-helloworld placeholder (port 80) with mcr.microsoft.com/dotnet/samples:aspnetapp, which listens on 8080 and serves /healthz, so the first revision passes the template's probes. - Add COSMOS_SERVERLESS for subscriptions whose single free-tier Cosmos account is already taken. Defaults to provisioned throughput. - Add CUSTOM_DOMAIN_NAME, which drives OAuth__BaseUrl, AllowedHosts, and the redirect URI output instead of hand-editing main.bicep. - Add optional publishing through an existing Front Door Standard/Premium profile: dedicated endpoint, route, origin, managed-cert custom domain, Azure DNS records, and a custom-rule WAF policy (path allow list, OAuth and overall per-IP rate limits, optional country allow list). Nothing existing on the profile is modified. - Add an opt-in FrontDoor:Id origin check that rejects requests without the matching X-Azure-FDID header (except /healthz), so the Container Apps host name can't bypass the WAF. - Add DEVBRAIN_PUBLIC_URL and DEVBRAIN_MCP_URL outputs and point the README's verify step at them. - Fix the README's az CLI app-role snippet, which nested the role array and truncated it at the default ConvertTo-Json depth. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
dsghi
force-pushed
the
feat/serverless-cosmos-option
branch
from
October 5, 2026 02:24
71b8eff to
14378d4
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
A brand-new
azd provisionof DevBrain 2.0 can't finish: the Container App sits in "InProgress" for 20 minutes and fails withContainerAppOperationError: … Operation expired. Deploying into a new tenant turned up two independent causes, plus a broken README snippet. This PR fixes all three and adds opt-in options that new tenants are likely to need.Fixes
Failed to construct registry secret … Ensure the managed identity 'system' has the correct permissionsuntil the operation expired. Image pulls now use the existing user-assigned identity, which is granted AcrPull before the app is created. The old system-identity assignment is left in place so existing deployments see no churn.containerapps-helloworldlistens on port 80, while ingress and the/healthzstartup, readiness, and liveness probes target port 8080, so the placeholder revision could never become healthy. It's replaced withmcr.microsoft.com/dotnet/samples:aspnetapp, which listens on 8080 and serves/healthz.ConvertTo-Json -AsArray @(@{…})wraps the array a second time and truncates it at the default depth of 2, soaz ad app update --app-rolesfails with'list' object has no attribute 'get'. It now pipes the array with-Depth 5.New opt-in options (all default off; existing deployments are unchanged)
COSMOS_SERVERLESSCUSTOM_DOMAIN_NAMEOAuth__BaseUrl,AllowedHosts, and theOAUTH_REDIRECT_URIoutput, replacing the README's "edit main.bicep" instructionFRONT_DOOR_PROFILE_NAME/_RESOURCE_GROUP/_SKUDNS_ZONE_NAME/_RESOURCE_GROUP_dnsauthTXT validation records into an existing Azure DNS zoneFRONT_DOOR_ALLOWED_COUNTRIESThe WAF policy has these rules: a path allow list (
/mcp,/.well-known/*,/register,/authorize,/callback,/token,/healthz); 30 requests per minute per IP on the OAuth endpoints (/registeris open by design under RFC 7591); and 1,000 requests per 5 minutes per IP overall.App change: a new opt-in
FrontDoor:Idsetting. When it's set, the server rejects requests whoseX-Azure-FDIDheader doesn't contain this profile's ID, except/healthz, which Container Apps probes reach directly. This follows Microsoft's origin-lockdown guidance and stops the*.azurecontainerapps.iohost name from bypassing the WAF. Provisioning sets it automatically when Front Door is enabled.New outputs:
DEVBRAIN_PUBLIC_URLandDEVBRAIN_MCP_URL. The README's verify step now uses them, because with the origin check the platform host name returns 403 for everything except/healthz.Testing
dotnet test devbrain.slnx: 162 passed, including new server tests for the Front Door check (missing header, wrong ID, comma-separated chain, and/healthzexemption)./healthzand both/.well-knownmetadata documents return 200;POST /mcpwithout a token returns 401 with the correctresource_metadata;/,/wp-login.php,/.env, and/mcpfooreturn 403 from the WAF;/.well-known/oauth-protected-resource/mcppasses the WAF and gets the app's 404, which MCP clients rely on for discovery fallback; HTTP redirects to HTTPS; the OAuth rate limit returns 403 after the threshold while other paths stay reachable.*.azurecontainerapps.io:/healthzreturns 200, and every other path returns 403.az deployment group what-ifshowed only creates on the shared Front Door profile and DNS zone, with no modifications or deletes to existing routes, WAF policies, or security policies.🤖 Generated with Claude Code