POC public vs MVP private: networking as architecture for agent apps
A public POC proves the product loop. A private MVP proves you can survive enterprise networking.
Those are different architectures. Do not fake the second by adding more env files.

Figure 1. Private endpoint pattern for App Service. Source: Microsoft Learn: App Service private endpoints.
I have watched agent shells go from "works on my tenant" to "blocked by private DNS" in the same sprint. The model did not regress. The network plane changed.
The core idea
POC optimizes for learning the agent loop. MVP optimizes for who can reach what on which plane.
Public ingress (or a tight IP allowlist) is a legitimate POC choice. Private endpoints, VNet integration, private DNS zones, and Key Vault references are the MVP choice. They are not the same diagram with different .env values.
Microsoft is explicit about the split on App Service: a private endpoint covers inbound private access to the app. Regional VNet integration covers outbound calls from the app into the virtual network. You often need both. Mixing them up in a README is how teams ship "MVP" that still answers on the public hostname.
Stage the differences you actually mean
Write an architecture table before you clone folders.
POC. Public or IP-filtered ingress. Faster iteration. Agent platform endpoints that may still be internet-reachable. Short-lived secrets or scoped App Settings. Enough Entra to sign people in and prove app roles. Good for shell behavior, streaming chat, and knowledge upload loops.
MVP. Private endpoints on the shell API and on data plane dependencies that must not be public. VNet integration so the app can call private Key Vault, storage, and platform endpoints. Private DNS linked to the integration VNet so names resolve to private IPs. Clearer identity: managed identity for the app, app roles for users, Conditional Access where required. Network, private DNS, and monitoring owners become first-class.
What stays shared: product shapes (SPA, API, agent contracts), the authorization model, and the role test matrix. What must never carry forward: leftover connection strings, old registry credentials, and "temporary" public allow rules.
A model that stays explainable
1. Draw ingress and egress as separate boxes
Inbound private access is not outbound private access. Private endpoints put the app (or a dependency) on a private IP for clients on the network. VNet integration lets App Service workers reach private resources through a delegated subnet. Microsoft documents that those subnets must not be the same. If your diagram has one cloud labeled "private," redraw it.
2. Treat private DNS as a product dependency
The failure mode is almost always DNS: the hostname still resolves publicly, or privately for one subnet and not another. Link Azure Private DNS zones to the VNet the app integrates with. If you run custom DNS, make sure it forwards correctly. Do not debug this as an application bug for three days.
3. Harden Entra when the network hardens
User-facing agent apps still need a clear identity story when networking locks down. Entra decides who may open the shell. App roles on the API still decide which agents and knowledge paths exist. Network isolation reduces who can touch the plane. It does not replace per-agent authorization. Both layers matter; they solve different threats.

Figure 2. User-facing apps still need a clear identity story when networking hardens. Source: Microsoft Learn: app scenarios.
4. Move secrets out of "gitignored forever"
POC App Settings and local .env files are fine for a spike. MVP should use Key Vault references (or equivalent) reached over private networking where the tenant standard requires it. Long-lived secrets in cloneable templates become the next engagement's incident.
5. Inventory registries, plans, and roles
Container registries, App Service plan SKUs, and managed identity role assignments are not interchangeable across stages without a diagram. Private MVP often needs a higher plan tier for VNet integration and private endpoints. Budget that as architecture, not as a surprise invoice.
Failure modes I design against
Env file theater. Twelve templates named poc, mvp, prod that only change URLs while networking stays public. The README says MVP. The public internet says otherwise.
Private endpoint without private DNS. The app looks private in the portal and still resolves wrong. Symptoms look like random 403s and timeouts.
VNet integration assumed to lock ingress. Outbound integration does not make the site private. You still need private endpoints or access restrictions for inbound control.
Identity postponed until "after networking." You harden the plane and leave every signed-in user as a trusted agent operator. Network controls protect the plane; they do not replace catalog and corpus authorization.
POC secrets promoted wholesale. Old placeholders, shared keys, and public storage endpoints hitch a ride into MVP because someone copied the folder.
One subnet for everything. Private endpoints and VNet integration fight over the same delegated subnet. The platform will not invent capacity for you.
Trade-offs
Private MVP is slower to stand up. You need network, DNS, and identity owners in the room. POC velocity drops when every change waits on a private link.
You lose convenience: portal demos and curl from outside the VNet. Plan VPN or a bastion path instead of quietly reopening public ingress. On-behalf-of flows get harder to debug when egress is locked; keep identity tests separate from network tests so you know which plane broke.
What I would put on an ADR
- Ingress model per stage (public or IP-filtered for POC; private endpoint for MVP shell and critical APIs).
- Outbound model for MVP (regional VNet integration, route-all if egress must be inspected).
- Private DNS zone inventory and which VNets they link to.
- Identity for app (managed identity), users (Entra + app roles), and agent platform reachability.
- Secret store location and rotation; no long-lived secrets in gitignored files as the long-term plan.
- Promotion rule: networking and identity gate the stage label; configuration files follow. Public exceptions need an owner and a review date.
Primary references: Microsoft Learn on App Service private endpoints, VNet integration, and secure N-tier web apps.
FAQ
What separates a public agent PoC from a private MVP?
Ingress, egress, private DNS, and Entra hardening are separate boxes. A public demo network is not an MVP control plane, and secrets cannot stay "gitignored forever".
What should I harden first when moving an agent app private?
Treat private DNS as a product dependency, harden Entra when the network hardens, and inventory registries, plans, and roles before you call the environment production-shaped.
Closing
Agent apps do not fail the public-to-private jump because the chat UI was wrong. They fail because teams treated networking as packaging.
POC proves the loop. MVP proves the plane. Write the delta as architecture, then let configuration follow.
If your MVP is still reachable on a public hostname with POC secrets, you do not have an MVP. You have a louder demo.
