Why this lesson matters โ the brand-new mental model
The first 8 lessons of this batch lived in one world: egress. A user opens Chrome, hits the internet, ZIA intercepts that outbound request and applies policy. ZIA's whole job is forward-proxying โ outbound web traffic, decrypted, inspected, allowed or blocked. Everything you've learned so far is filtered through that lens.
From this lesson onward, flip that mental model 180 degrees. ZPA isn't about a user reaching the internet โ it's about a user reaching your internal application that lives in your data centre, your AWS VPC, your Azure subscription, your colo. The traffic direction is inverted. The protocol is different. The threats are different. The architecture is wildly different.
And here's the punchline: ZPA does this without ever giving the user a network. A VPN drops the user onto a flat subnet inside your perimeter โ the user can now ping every machine, port-scan every service, and laterally move if the laptop gets compromised. ZPA gives the user exactly one app, brokered through a cloud the user never sees, with the app itself sitting behind zero open inbound ports. That's the Zero Trust pitch in three sentences โ and from a CISO's perspective, it's the whole reason ZPA exists.
ZPA vs VPN โ the mental flip
Most engineers approach ZPA with a "it's a cloud VPN" instinct. Stop that. The two technologies share zero architectural DNA. Here's the side-by-side you should be able to recite cold in any interview:
| Dimension | Traditional VPN | ZPA |
|---|---|---|
| Connection direction | User โ VPN concentrator (inbound to the concentrator's public IP). After auth, traffic flows inside-out from the user's tunnel. | Double inside-out. User's Z-App connects outbound to ZPA Cloud. App Connector connects outbound to ZPA Cloud. ZPA Cloud brokers the two. No one ever accepts inbound. |
| What the user sees on the network | Full IP subnet (usually a /24 or larger). User can ping the file server, the printer, the build agent โ even if policy only meant to give them Jira. | One app at a time. User's OS resolves jira-internal.acme.com to a synthetic CGNAT IP inside Z-App's tunnel. Nothing else on the corporate network is reachable, visible, or pingable. |
| What you defend | The concentrator (Pulse, Cisco AnyConnect, Global Protect, FortiGate SSL-VPN). One CVE in that appliance = total network breach. Patching it is a planned downtime event. | The policy engine inside ZPA Cloud โ Zscaler-operated, multi-tenant, patched continuously by Zscaler. You don't run a concentrator. |
| Public attack surface for private apps | Concentrator listens on TCP/443 publicly. App servers usually also exposed via NAT/DNAT to be reachable. | Zero. The App Connector dials out only. The app server has no public IP and no inbound firewall rules at all. |
| Lateral movement after a pwned laptop | Attacker pivots through the VPN tunnel into a full network. Famous breaches (Solarwinds vendor pivot, every ransomware run) start here. | Attacker can reach only the apps that user was entitled to โ and even then, only on the specific TCP/UDP ports defined in the segment. |
| Scale model | Per-concentrator user cap (often 5kโ20k tunnels). Hard limit; needs HW refresh to grow. | Zscaler-operated elastic cloud. Pay per user, scale to 200k seats without an architecture change. |
| Failure modes | Concentrator down = entire workforce locked out. Tunnel CPU saturated = packet loss. | Multiple Service Edges per region (anycast). App Connector groups auto-failover. Region failure routes to next-nearest. |
If a Lesson-9 student remembers nothing else, remember this: VPN = network. ZPA = applications. Once that one substitution clicks, every other ZPA design decision in this batch becomes obvious.
The four ZPA components โ what each one is, where it lives, what ports it opens
ZPA has exactly four moving parts. Every diagram, every troubleshooting flow, every interview question maps back to these four. Memorise them:
1. Z-App (Zscaler Client Connector for ZPA)
The agent on the user's laptop, desktop, phone, or tablet. Same binary as the ZIA Client Connector โ one install, both ZIA and ZPA "service profiles" available. When ZPA is enabled in the user's profile, the agent loads a list of application segments (FQDNs and IP ranges of internal apps) the user is entitled to. It intercepts DNS queries that match those segments, returns a synthetic IP from 100.64.0.0/16 (the default ZPA synthetic-IP range โ configurable; RFC 6598 CGNAT space is the broader /10, Zscaler uses a slice โ guaranteed not to clash with any RFC1918 the user is on), and opens a TLS tunnel to the nearest healthy Service Edge. Supported on Windows, macOS, Linux, iOS, Android, ChromeOS. Z-App listens on no ports โ purely outbound TCP/443 (Z-Tunnel 2.0 over QUIC/443 in modern builds, fallback DTLS/HTTPS). TCP/9000 is the App Connector โ ZEN control channel, NOT Z-App. Don't conflate the two โ it's the #1 ZPA architecture interview trap.
2. ZPA Cloud (the broker / policy engine)
The Zscaler-operated control plane. This is where your tenant lives โ your application segments, your access policy, your user/group bindings, your IdP integration (SAML/SCIM with Okta, Entra ID, Ping, Google). Every connection from a Z-App and from an App Connector terminates here, gets authenticated, gets policy-checked, then gets stitched to the other side. ZPA Cloud doesn't run inside your data centre or your cloud โ it runs in Zscaler's. You administer it via https://admin.private.zscaler.com (or the cloud variant your tenant is on).
3. App Connector
A lightweight Linux VM (RHEL/CentOS/Ubuntu) that you deploy next to your internal apps โ one VM in each "place" you have apps. In AWS, that's one App Connector per VPC (or per region, depending on routing). In your data centre, one in each DC. Minimum spec: 2 vCPU, 4 GB RAM, 16 GB disk โ sized for ~1 Gbps throughput; scale horizontally for more. It opens zero inbound ports. It registers to ZPA Cloud over outbound TCP/443 + TCP/9000 to Zen IP ranges, then sits and waits for ZPA Cloud to push it work. When a user's session needs to reach the app this connector serves, the connector dials the app over the local network and stitches the bytes into the tunnel.
4. Service Edge
The regional broker โ the actual TCP termination point for the double tunnel. By default these run inside Zscaler's data centres (called Public Service Edges, hosted across ~150+ Zscaler data centres worldwide, anycast-routed). The ZIA Service Edge fleet and ZPA Public Service Edge fleet are architecturally separate broker pools, even though they share PoPs. For regulated industries that can't have user traffic touching Zscaler infrastructure, the same broker software runs as a Private Service Edge inside your DC or cloud โ Zscaler manages the code, you provide the compute. Microtenants are a logical isolation overlay on the Public cloud for MSPs and B2B portals serving multiple customer organisations from one ZPA tenant.
The whole architecture on one page
Six outbound arrows, all pointing inward to ZPA Cloud. Nothing in this diagram ever accepts a new connection from outside. The user's laptop initiates; the App Connector initiates. ZPA Cloud is the only thing that accepts, and it accepts only TLS sessions that present a valid Zscaler-enrolled certificate. Your private apps don't need public IPs โ they don't even need inbound firewall rules.
The famous "double inside-out" tunnel
This is the architectural idea that makes ZPA different from every VPN that came before it. Here's the mechanism in plain English:
- Z-App side โ the agent on the user's laptop dials TCP/443 outbound to the nearest healthy Service Edge. The Service Edge sees a new TLS session, validates the cert (issued by ZPA during user enrollment), authenticates the user against the bound IdP, and pulls down the user's policy bundle. The Z-App's tunnel is now "up" โ but it's just sitting there, holding the TLS session open, waiting for the user to actually click something.
- App Connector side โ at the same time (continuously, since the connector booted), the App Connector dials TCP/443 outbound to the nearest healthy Service Edge. Same TLS auth, same enrollment cert. The connector tells the Service Edge "I can serve these apps:
jira-internal.acme.com,confluence-acme.com,10.40.0.0/16:1433". The connector's tunnel is now "up" too โ also just sitting there. - User clicks the app โ say the user clicks a Jira link. The Z-App's DNS interceptor catches the lookup for
jira-internal.acme.com, returns a synthetic CGNAT IP, and the browser opens a TCP connection to that IP. The Z-App tunnels the SYN to ZPA Cloud. - ZPA Cloud brokers โ ZPA Cloud sees the inbound stream on the Z-App's side, looks up the user's access policy for this app segment, allow-list checks, posture-checks, and if allowed, finds a healthy App Connector that has advertised this app. It pushes a message down the connector's already-up tunnel saying "stream from user X coming, please dial
jira-internal.acme.com:443on your local network". - App Connector dials the app โ the connector does a normal local TCP connect to the Jira server (which is sitting in the same VPC or DC, completely unaware of ZPA's existence). The Jira server sees a connection from the connector's IP โ just like any other internal user.
- Bytes flow โ ZPA Cloud sews the user's stream and the connector's stream together. Bytes flow bidirectionally. Both legs are TLS-encrypted. Neither end ever knows the other's real IP.
Seven steps. Notice the user's browser never knew there was a tunnel โ DNS just returned an IP and TCP "just worked". The Jira server never knew the request came from outside the corporate network โ it saw a connection from the App Connector IP, like any other internal user. ZPA Cloud is the silent matchmaker.
Z-Tunnel 1.0 vs Z-Tunnel 2.0
| Z-Tunnel 1.0 | Z-Tunnel 2.0 | |
|---|---|---|
| Transport | TCP/443 per flow | QUIC/443 (DTLS/443 fallback) โ multiplexed |
| Sessions | One tunnel per app session | Single tunnel, all sessions multiplexed |
| UDP app support | No | Yes (DNS, Citrix UDP, RDP UDP) |
| Default since | โ | ZCC 4.0+ (~2022) |
Any deployment after 2022 should be on Z-Tunnel 2.0. Performance interview questions about ZPA latency almost always hinge on this.
Why the app is "dark" to the internet
This is the security implication that sells ZPA to CISOs. Walk through what a port-scan from the public internet sees against your private Jira after ZPA migration:
- jira-internal.acme.com has no public DNS A record. It only resolves inside Z-App (synthetic IP) for entitled users.
nslookupfrom the open internet returns NXDOMAIN. - If the attacker somehow gets the internal IP, that IP has no NAT/DNAT to the public internet. There's no firewall rule allowing inbound. The packet drops at the edge.
- The App Connector itself has no listening ports โ
nmap -sSshows zero open ports. Even a directly-targeted scan against the connector IP returns nothing. - ZPA Cloud is multi-tenant โ even if the attacker discovers your tenant ID and your Service Edge IP, they can't get past TLS without a valid enrolled client certificate. Three layers of trust, separately verifiable: (1) enrollment certificate (provisioned at user enrollment, persists across IdP sessions); (2) IdP-issued SAML assertion (per session); (3) optional Z-App device-posture signals (per session, refreshed every 60-90 sec).
That's "dark application" โ it doesn't show up in Shodan, doesn't get hit by automated CVE scanners, doesn't make it into mass-exploitation campaigns. The only way in is through ZPA, which means through the policy engine, which means with proper auth + posture + entitlement. The 2024-style "perimeter VPN concentrator zero-day โ ransomware in 6 hours" attack chain has nothing to grab onto.
Public vs Private vs Microtenant Service Edge โ when to use which
Public Service Edge โ the default
Hosted across ~150+ Zscaler data centres worldwide (ZIA and ZPA fleets are separate broker pools, even though they share PoPs), anycast-routed so Z-App and App Connector both reach the nearest healthy one automatically. Zero compute cost to the customer, Zscaler handles all capacity planning. 95% of deployments only ever use Public Service Edges. Pick this unless you have a specific reason not to.
Private Service Edge โ for strict data-residency or regulated industries
Same broker software, but the VM runs in your data centre or cloud account. Use cases: defence contractors who can't have user-to-app traffic touching commercial cloud infrastructure, financial institutions in jurisdictions where regulator says "all session control must stay in-country", healthcare orgs with HIPAA constraints on data flow. The control plane (your tenant config, your policy) still lives in ZPA Cloud โ only the data path stays in your premises. Sizing: same as App Connector but multiply by expected concurrent session count. HA: pair them up, ZPA Cloud round-robins.
Microtenant โ for MSPs and B2B portals
A Microtenant is a logical sub-tenant inside your main ZPA tenant. Use case: you're an MSP serving 30 customer organisations, each with their own users and their own apps, but you don't want to spin up 30 separate ZPA tenants (cost + admin overhead). Microtenants let one ZPA tenant carve into 30 isolated configuration scopes โ each customer sees only their users, their apps, their admins. Same Public Service Edges, just policy-isolated. Also useful for B2B portals where you let partner companies' employees reach a slice of your apps.
App Connector deeper โ the operational details L2/L3 engineers must know
The App Connector is the part you'll actually touch most often. Operationally, here's what matters:
What it is technically
A 64-bit Linux VM image. Zscaler ships it as an OVA (VMware), AMI (AWS Marketplace), VHD (Azure Marketplace), and as a YUM/APT package for RHEL/CentOS/Ubuntu if you want to bring your own VM. Minimum spec: 2 vCPU, 4 GB RAM, 16 GB disk. Sized for roughly 1 Gbps and a few hundred concurrent sessions per connector. Scale horizontally โ never vertically โ past that.
How it registers
You generate a provisioning key in the ZPA admin portal (Administration โ App Connectors โ Provisioning Keys โ Add). The key is one-time-use, bound to a Connector Group (logical grouping per location/cloud/DC), and has an expiry. You paste the key into the connector VM's bootstrap (cloud-init userdata or interactive prompt on first SSH). The connector dials out to ZPA Cloud, presents the key, gets back a per-connector certificate, and from then on uses the cert for all subsequent registrations.
The HA model
Connectors live in Connector Groups. A group is the unit of HA โ when ZPA Cloud needs to dial an app served by this group, it picks any healthy connector in the group (round-robin with health weighting). Always deploy โฅ2 connectors per group in each region. One connector per region is a SPOF โ if that VM patches, reboots, or the underlying hypervisor host fails, every app served by that group goes dark for the user. Two connectors with overlapping segment advertisements = zero-touch failover.
Outbound TLS to Zen โ the only ports it opens
The connector needs outbound TCP/443 and TCP/9000 to Zscaler's Zen IP ranges. The CIDR list is published at config.zscaler.com/<cloud>.net/cenr/json โ updates monthly + ad-hoc. Subscribe to the trust portal feed for change notifications and set up a cron to pull the JSON and update your egress firewall. It does not need any inbound rule. It does not need outbound to the open internet โ only to the Zen ranges. If your egress firewall is strict, allow-list those ranges; don't punch a hole for "all outbound 443".
- Connector Groups by failure domain, not by app. One group per AWS AZ (or per DC row), not one group per application. Apps come and go; the failure domain is stable. App segments are attached to groups, so multiple apps in the same AZ share the same pair of connectors and benefit from the same HA pair.
- Run the connector on a dedicated VM โ don't combine with anything else (no DB on the same box, no SSH bastion). It's a security-sensitive component; keep it minimal.
- Pre-flight a connector pair before assigning real users. Deploy the two connectors, advertise a test segment (e.g.
internal-ping.acme.compointing to a small Nginx), entitle a test user only, verify end-to-end. Then attach production app segments.
- Treating ZPA like a VPN โ building flat zones inside it. "Let's create one app segment for the whole 10.40.0.0/16 corporate range." That's a VPN. The whole point of ZPA is granular per-app entitlement; collapse it to a /16 and you've just rebuilt your old perimeter with extra steps.
- Putting App Connector in a separate VLAN with no route to the app. Connector registers fine (it can reach Zscaler over outbound 443), shows green in the portal, but every user request times out because the connector can't actually reach the app over the local network. Always verify
curl https://jira-internal.acme.comfrom the connector VM itself before declaring success. - Forgetting Z-App DNS interception requires the app FQDN to be in an app segment. Users typing the raw IP (e.g.
https://10.40.0.50) bypass DNS interception entirely and the request never enters the ZPA tunnel โ it just hits the local network and times out. Either entitle the FQDN or add IP ranges as a separate segment. - Single App Connector per region. The connector reboots for a patch, an AZ hiccups, the hypervisor decides today is the day โ all users lose all apps in that region. Always two, always with overlapping advertisements.
- Outbound 443 not allowed from connector subnet to Zen IPs. Connector boots, tries to register, can't reach Zscaler, sits in the "Pending" state forever. Easy to debug โ
journalctl -u zpa-connectorshows the connect failure โ but ten minutes wasted every time. Allow-list Zen ranges in your egress firewall before deploying the connector. - Expecting client-server protocols like SMB / RDP broadcast / mDNS / multicast to work. ZPA is TCP/UDP per-app โ no broadcast, no multicast, no NetBIOS name discovery. Plain SMB file shares to a known server IP/FQDN work; "browse the network neighbourhood" doesn't.
- Pinning the wrong identity attribute. Access policy keyed on a SAML attribute that the IdP doesn't send for that user โ entitlement evaluates to NULL โ policy denies โ "user can't access app" ticket. Always test the IdP's SAML response (use SAML-tracer or the admin portal's User Diagnostics) before pushing policy live.
- App Connector health โ ZPA Admin โ Administration โ App Connectors. State should be "Active" (green) and "Last Connected" should be within the last 60 seconds. Throughput stats should be non-zero once users are flowing.
- Z-App tunnel state โ right-click the Z-App tray icon โ "Open Zscaler". The "ZPA" tab should show "Authenticated" + Service Edge city + tunnel up time. Click "Diagnostics" โ "Service Status" for a deeper view.
- ZPA Diagnostics โ Trace a User โ ZPA Admin โ Insights โ Diagnostics โ Trace a User. Enter the user email and the app FQDN. The trace shows: SAML auth result, policy evaluation, connector pick, dial result, byte counts. This is the single most useful tool when a ticket lands โ start here.
- App reachability from inside โ from the App Connector VM itself:
curl -v https://jira-internal.acme.com. If this fails from the connector, no amount of ZPA tuning will help โ it's a local network/routing/DNS issue. - Public exposure check โ from any internet host,
nslookup jira-internal.acme.comshould return NXDOMAIN.nmapagainst the App Connector public IP should return zero open ports. If either is wrong, you've leaked something.
Real-world scenario โ Acme decommissions Pulse VPN, gives 200 contractors per-app access
Acme just acquired a smaller company. The acquired entity has its own Jira and Confluence (call them jira-acq.internal and confluence-acq.internal), hosted in the acquired entity's AWS account, which is now being absorbed into Acme's master payer account. The acquired company also has 200 contractors who need ongoing access to only these two apps โ nothing else. They should not be able to see Acme corporate file shares, Acme HR systems, Acme build infrastructure, or anything else.
The VPN-era approach: stand up VPN accounts for the 200 contractors on Acme's Pulse concentrator, drop them onto a "restricted" VLAN, write firewall ACLs from that VLAN allowing TCP/443 to the two specific Jira/Confluence IPs and denying everything else, hope nobody fat-fingers the ACL, hope nobody bypasses the ACL by routing trickery, document the ACL in the change-management system, schedule a quarterly ACL review. Realistic timeline: 6โ10 weeks involving the network team, the security team, the access-management team, and a change advisory board.
The ZPA approach:
- Deploy two App Connectors in the acquired entity's AWS VPC (one per AZ for HA). 30 minutes including AWS Marketplace install and provisioning key paste.
- Create two app segments:
jira-acq.internal:443+confluence-acq.internal:443. Attach both to the new Connector Group. 5 minutes. - Create an IdP group in Acme's Entra ID called
acme-acquired-contractors. Sync via SCIM to ZPA (automatic, runs every 40 min). 10 minutes. - Write one access policy: "Group acme-acquired-contractors โ allow โ app segments {jira-acq, confluence-acq}". 5 minutes.
- Enrol the 200 contractors via Z-App OnePass (email-based one-click enrollment). Day 1: 50 users enrolled themselves. Week 1: all 200.
- Run "Trace a User" against 3โ5 contractors as a smoke test. All pass.
- Decommission the contractor VPN accounts. Day 2.
Total elapsed time: 1 week, mostly waiting for contractors to click the enrollment email. Total infra surface added to Acme's perimeter: zero. The acquired entity's Jira and Confluence get no public IPs, no firewall rule changes, no NAT entries. The contractors can reach exactly two apps and nothing else โ not because of an ACL that has to be maintained, but because that's all their entitlement lets ZPA Cloud broker. If a contractor laptop gets pwned tomorrow, the attacker reaches Jira + Confluence and dies there โ no lateral movement possible because there's no network to move in.
This is the Acme story repeated at thousands of orgs going through the same migration. The economics โ and the security improvement โ are why VPN concentrator vendors are losing the segment one customer at a time.
๐ Quick reference โ ZPA architecture cheat-sheet
- Four components, that's it: Z-App (on user device) ยท ZPA Cloud (Zscaler-operated broker) ยท App Connector (Linux VM next to your apps) ยท Service Edge (Public/Private/Microtenant).
- One-line ZPA vs VPN: VPN = network. ZPA = applications. VPN gives a subnet. ZPA gives one app at a time.
- Double inside-out tunnel: Z-App dials outbound 443 to Service Edge. App Connector dials outbound 443 to Service Edge. ZPA Cloud sews the two streams together. No inbound ports anywhere.
- The app is "dark": no public DNS, no public IP, no inbound firewall rule, no NAT. Shodan returns nothing. Mass-exploit campaigns can't find it.
- App Connector specs: 2 vCPU + 4 GB RAM + 16 GB disk, ~1 Gbps, RHEL/CentOS/Ubuntu. Outbound TCP/443 + TCP/9000 to Zen IPs only.
- Always โฅ2 connectors per group per region. Single connector = SPOF.
- Public Service Edge = default (Zscaler-operated, anycast, ~150+ globally). Private = same software in your DC for residency. Microtenant = MSP/B2B logical isolation.
- Z-App needs the FQDN in an app segment for DNS interception to fire. Raw IP access bypasses ZPA.
- SMB/RDP work, broadcast/multicast/NetBIOS-discovery do not. ZPA is per-app TCP/UDP only.
- First tool when something breaks: ZPA Admin โ Insights โ Diagnostics โ Trace a User. Tells you SAML, policy, connector pick, byte counts in one view.
Trace a ZPA flow:
- From a Z-App-enrolled laptop, attempt to reach
app.internal.lan(a defined App Segment). Open ZCC โ Diagnostics โ see Z-Tunnel state. - In ZPA Admin โ Analytics โ Diagnostics โ enter the user + app. See the connector chosen, broker selected, RTT timings.
- Disable your local App Connector. Reload the app in browser. Confirm failover happens โ different connector picked.
- Run
ipconfig /allorip addron the laptop โ find the 100.64.x.x synthetic IP for the segment.
๐ Check your understanding
10 scenario questions โ interview + ZDTA exam depth. Pick one answer per question. You need 70% (7 of 10) to mark this lesson complete on your profile.
What's next?
Module 10 gets you hands-on โ deploying App Connectors in AWS/Azure/VMware, sizing for capacity, and adding Branch + Cloud Connectors for office and SaaS-side traffic anchoring.