Your Security Team Wants to Privatize Your App — Here's What They Actually Need
When your security team says 'make it private', they usually mean 'make it secure.' This post compares four approaches — VPC privatization, WAF IP allowlisting, CloudFront + auth hardening, and AWS Verified Access — and explains why Zero Trust beats network perimeters for internal applications.
Table of Contents
- The Problem
- The Solution
- How It Works
- Approach 1: Full VPC Privatization
- Approach 2: WAF IP Allowlist
- Approach 3: CloudFront + Auth Hardening
- Approach 4: AWS Verified Access (Zero Trust)
- Why Verified Access Blocks Stolen Credentials
- Detecting Compromised Credentials
- The Cost Comparison
- What I Learned
- What’s Next
Your security team says “privatize the app.” You hear “move everything into a VPC, add a VPN, remove CloudFront.” But is that actually the right move? In most cases, the answer is no — and the modern standard (Zero Trust) actually argues against network-based security.
The Problem
You have a serverless application on AWS: CloudFront serves a frontend from S3, API Gateway handles the backend, Lambda processes business logic, and Azure AD provides authentication. It works. Users authenticate, do their work, go home.
Then your security team flags it: “The endpoints are public. We need to privatize access.”
The instinct is to reach for VPC privatization: remove CloudFront, deploy everything behind a VPN, route all traffic through VPC Endpoints. But this approach has three problems:
-
CloudFront is public by nature. You can’t make a CDN private — that defeats its purpose. Replacing it requires a reverse proxy (ALB + Lambda or Nginx on Fargate) just to serve static files from S3.
-
It multiplies complexity. VPN, VPC Endpoints for every service (S3, Athena, KMS, STS, CloudWatch Logs…), Lambda in VPC with longer cold starts, NAT Gateways, DNS changes, inter-account connectivity for multi-account setups.
-
VPN is perimeter security, not Zero Trust. Once on the VPN, an attacker with stolen credentials has full access. The network boundary provides a false sense of security.
The real question isn’t “how do we privatize?” — it’s “what threat are we actually mitigating?”
The Solution
Before choosing an approach, identify the actual risk:
| If the risk is… | The right solution is… |
|---|---|
| Stolen Azure AD credentials used from anywhere | WAF IP allowlist or Verified Access |
| Leaked pre-signed S3 URLs | CloudFront signed URLs + OAC |
| Security policy: “no public endpoints” (but WAF IP OK) | WAF IP + OAC |
| Security policy: “no public endpoints” (strict) | Full VPC privatization |
| Reconnaissance / port scanning | WAF + rate limiting |
| All of the above | AWS Verified Access (Zero Trust) |
The modern standard — NIST SP 800-207 — is Zero Trust: verify identity, verify device, verify continuously. Network location is irrelevant. AWS Verified Access implements this pattern natively.
How It Works
Approach 1: Full VPC Privatization
Remove all public endpoints. Everything goes through a VPN or Direct Connect.
User (VPN) → VPC → ALB Internal → Lambda (VPC) → S3 (Gateway Endpoint)
What you need:
- VPN or Direct Connect from corporate network to VPC
- Remove CloudFront, replace with internal ALB or API Gateway PRIVATE
- Deploy Lambda in VPC (private subnets)
- VPC Endpoints for every AWS service: S3, STS, KMS, CloudWatch Logs, API Gateway, DynamoDB…
- NAT Gateway if Lambda needs outbound internet (e.g., Azure AD token validation)
- Route 53 Private Hosted Zone for internal DNS
Cost: ~$150+/month (VPC Endpoints + NAT Gateway + ALB)
Verdict: Maximum isolation, but maximum complexity. Every new AWS service integration requires another VPC Endpoint. Lambda cold starts increase. Users need VPN always-on, including remote workers. And critically: stolen VPN credentials + stolen AD credentials = full access with zero additional checks.
Approach 2: WAF IP Allowlist
Keep the current architecture. Add a WAF rule that only allows traffic from corporate IP ranges.
User (corporate IP) → CloudFront + WAF → S3 / API GW → Lambda
What you need:
- WAF WebACL on CloudFront with an IP Set containing corporate IP ranges
- Default action: Block. Allow rule: match IP Set.
- OAC on CloudFront to prevent direct S3 access
Cost: ~$7/month (WebACL + 1 rule)
Verdict: Simple and effective. Zero architecture change. The main limitation: remote workers must be on VPN so their traffic exits through corporate IPs. If the company uses an always-on VPN (Zscaler, GlobalProtect), this is seamless. If not, remote users are locked out.
Approach 3: CloudFront + Auth Hardening
Keep everything public but harden authentication at every layer.
User → CloudFront (WAF + geo-restrict) → OAC → S3
User → API GW (Cognito authorizer) → Lambda → S3
What you need:
- OAC on CloudFront (S3 only accessible via CloudFront)
- WAF with rate limiting, geo-restriction, and anti-bot rules
- Migrate S3 pre-signed URLs to CloudFront signed URLs
- Cognito authorizer on API Gateway verifying Azure AD tokens
Cost: ~$5-10/month (WAF)
Verdict: Good baseline security. But if credentials are compromised, an attacker can access the app from anywhere with a valid token. No device verification.
Approach 4: AWS Verified Access (Zero Trust)
The modern standard. Verify identity AND device posture on every request. No VPN needed.
User (anywhere) → Verified Access → checks identity + device → CloudFront / API GW
What you need:
- AWS Verified Access endpoint
- Trust providers: Azure AD (identity) + Intune (device posture)
- Access policy combining both checks
- CloudFront + OAC stays in place
Cost: ~$0.27/hour per endpoint + $0.02/GB
Verdict: Best security posture. Even with stolen Azure AD credentials, an attacker on a non-corporate device is blocked. No VPN complexity. Users work from anywhere. Continuous verification, not just at login.
Why Verified Access Blocks Stolen Credentials
This is the core advantage over every other approach. When an attacker steals Azure AD credentials (phishing, infostealer), here’s what happens:
| Check | Attacker’s laptop | Corporate laptop |
|---|---|---|
| Azure AD identity | Pass (valid creds) | Pass |
| MFA | May pass (if token stolen too) | Pass |
| Enrolled in Intune | Fail | Pass |
| Disk encrypted (BitLocker) | Unknown | Pass |
| OS patched / compliant | Unknown | Pass |
| Machine certificate | Missing | Present |
The attacker can’t fake Intune enrollment or a machine certificate — these are tied to the device hardware/TPM. Stolen credentials without the corporate device are worthless.
Detecting Compromised Credentials
Zero Trust doesn’t just block — it detects. Azure AD Identity Protection calculates a risk score on every sign-in:
| Signal | What it detects |
|---|---|
| Impossible travel | Login from Paris then Tokyo in 30 minutes |
| Anonymous IP | Connection via Tor, public VPN |
| Known malicious IP | IP from threat intelligence feeds |
| Password spray | Mass attempts across accounts |
| Leaked credentials | Creds found in dark web breach databases |
| Token anomaly | Token used from different device/IP than issuance |
When risk is high, Conditional Access kicks in automatically: block the session, force re-MFA, or require a password reset. No human intervention needed.
Continuous Access Evaluation (CAE) goes further: even if the attacker gets a valid OAuth token, it’s revoked in real-time when an anomaly is detected — not after the 1-hour expiry.
On the AWS side, GuardDuty detects anomalous API behavior: unusual S3 access patterns, credential exfiltration attempts, mass data reads. Combined with CloudTrail logging and Verified Access logs, you get a complete audit trail.
The Cost Comparison
| Approach | Monthly cost | Security level | Complexity | Zero Trust? |
|---|---|---|---|---|
| VPC Private | ~$150+ | Perimeter-based | Very high | No |
| WAF IP Allowlist | ~$7 | Network + Auth | Very low | Partial |
| CloudFront + Auth | ~$5-10 | Auth only | Low | Partial |
| Verified Access | ~$200 | Identity + Device | Medium | Yes |
The cost difference between VPC privatization and Verified Access is marginal, but the security model is fundamentally different. VPC gives you a wall. Verified Access gives you a security guard that checks credentials and ID at every door.
What I Learned
-
“Privatize” is not a security requirement — it’s an implementation choice. The actual requirement is usually “prevent unauthorized access.” That can be achieved through network isolation (VPC), network filtering (WAF IP), or identity verification (Verified Access). Understanding which risk you’re mitigating determines which approach is right.
-
VPN is perimeter security, which is the opposite of Zero Trust. NIST SP 800-207 explicitly states that network location should not grant trust. An attacker who compromises VPN credentials + AD credentials has full access in a perimeter model. In Zero Trust, they’re still blocked because the device isn’t managed. This is the argument that reframes the conversation with security teams.
-
Device posture is the missing layer most organizations overlook. Identity verification (Azure AD, MFA) protects against weak passwords. Device posture verification (Intune, CrowdStrike, Jamf) protects against stolen credentials. The combination — identity AND device — is what makes Zero Trust fundamentally stronger than any network-based approach.
-
WAF IP allowlisting is an underrated middle ground. At $7/month with zero architecture changes, it blocks access from non-corporate IPs. Combined with OAC on CloudFront, it covers 90% of threat scenarios for organizations that aren’t ready for Verified Access. The only caveat: remote workers need VPN for their traffic to exit through corporate IPs.
-
Azure AD Identity Protection + Continuous Access Evaluation are powerful and underused. Real-time risk scoring, impossible travel detection, and instant token revocation mean that compromised credentials are often detected and blocked automatically — before the attacker can do anything. Most organizations have these capabilities in their Azure AD license but haven’t enabled the Conditional Access policies to act on them.
What’s Next
- Build a reference architecture with AWS Verified Access + Azure AD + Intune for a serverless application (CloudFront + API GW + Lambda)
- Test Verified Access with different device trust providers (Intune vs CrowdStrike vs Jamf) and document setup differences
- Create a cost calculator comparing the four approaches across different usage patterns
- Write a follow-up on Azure AD Conditional Access policies — the specific configurations that block stolen credentials
Related Posts
Cloud Sovereignty Deep Dive - AWS KMS Control Plane Analysis
XKS protects key material from extraction, but does it protect against legal compulsion to use those keys? Updated with AWS European Sovereign Cloud (GA January 2026).
AIOpenClaw vs NanoBot vs PicoClaw vs TinyClaw: Four Approaches to Self-Hosted AI Assistants
A deep architectural comparison of four open-source frameworks that turn messaging apps into AI assistant interfaces — from a 349-file TypeScript monolith to a 10MB Go binary that runs on a $10 board.
CloudReplacing Legacy SFTP with AWS Transfer Family in a Multi-Account Landing Zone
How to architect a secure, multi-tenant SFTP service across AWS accounts using Transfer Family, NLB, Transit Gateway, and per-partner S3 isolation.
