Security

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.

Alexandre Agius

Alexandre Agius

AWS Solutions Architect

9 min read
Share:

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:

  1. 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.

  2. 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.

  3. 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 anywhereWAF IP allowlist or Verified Access
Leaked pre-signed S3 URLsCloudFront 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 scanningWAF + rate limiting
All of the aboveAWS 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.

Decision flow for securing internal AWS applications — from strict VPC privatization to Zero Trust with Verified Access

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.

Perimeter security vs Zero Trust architecture comparison — VPN-based access with VPC isolation versus Verified Access with identity and device verification

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:

CheckAttacker’s laptopCorporate laptop
Azure AD identityPass (valid creds)Pass
MFAMay pass (if token stolen too)Pass
Enrolled in IntuneFailPass
Disk encrypted (BitLocker)UnknownPass
OS patched / compliantUnknownPass
Machine certificateMissingPresent

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:

SignalWhat it detects
Impossible travelLogin from Paris then Tokyo in 30 minutes
Anonymous IPConnection via Tor, public VPN
Known malicious IPIP from threat intelligence feeds
Password sprayMass attempts across accounts
Leaked credentialsCreds found in dark web breach databases
Token anomalyToken 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

ApproachMonthly costSecurity levelComplexityZero Trust?
VPC Private~$150+Perimeter-basedVery highNo
WAF IP Allowlist~$7Network + AuthVery lowPartial
CloudFront + Auth~$5-10Auth onlyLowPartial
Verified Access~$200Identity + DeviceMediumYes

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
Alexandre Agius

Alexandre Agius

AWS Solutions Architect

Passionate about AI & Security. Building scalable cloud solutions and helping organizations leverage AWS services to innovate faster. Specialized in Generative AI, serverless architectures, and security best practices.

Related Posts

Back to Blog