Zero Trust Is Not a Firewall Replacement#
Let's kill the biggest misconception first: Zero Trust is not a product. It's not a next-gen firewall, it's not an SSE gateway, and it's definitely not something you "deploy on Tuesday."
Zero Trust is an architectural philosophy: never trust, always verify. Every request — whether from inside or outside your network — must be authenticated, authorized, and continuously validated.
In cloud environments, this matters even more. There is no perimeter. Your "internal network" is a shared VPC that any compromised workload can traverse. Your "trusted users" are service accounts with overprivileged IAM roles.
The Five Pillars of Cloud Zero Trust#
Before diving into provider-specific implementations, understand the five pillars:
| Pillar | What It Means | Cloud Implementation |
|---|---|---|
| **Identity** | Every access request tied to a verified identity | IAM, MFA, federation, service accounts |
| **Device** | Only trusted/compliant devices get access | MDM integration, device posture checks |
| **Network** | Micro-segmentation, no implicit trust | VPC design, security groups, private endpoints |
| **Application** | App-level auth, not network-level | Service mesh, API gateways, mTLS |
| **Data** | Classification-based access controls | Encryption, DLP, DSPM |
AWS: Building Zero Trust#
Identity: IAM Identity Center + SCPs
Start with centralized identity. AWS IAM Identity Center (formerly SSO) is your control plane:
# Enable IAM Identity Center (requires Organizations)
aws sso-admin create-instance-assignment \
--instance-arn arn:aws:sso:::instance/ssoins-1234567890 \
--target-id 123456789012 \
--target-type AWS_ACCOUNT \
--permission-set-arn arn:aws:sso:::permissionSet/ssoins-1234/ps-abcdef \
--principal-type USER \
--principal-id user-id-here
# Create SCP to deny actions without MFA
cat > deny-without-mfa.json << 'EOF'
{
"Version": "2012-10-17",
"Statement": [{
"Sid": "DenyWithoutMFA",
"Effect": "Deny",
"NotAction": ["iam:CreateVirtualMFADevice", "iam:EnableMFADevice", "sts:GetSessionToken"],
"Resource": "*",
"Condition": {
"BoolIfExists": {"aws:MultiFactorAuthPresent": "false"}
}
}]
}
EOF
aws organizations create-policy \
--name "RequireMFA" \
--type SERVICE_CONTROL_POLICY \
--content file://deny-without-mfa.jsonNetwork: VPC Design with PrivateLink
Never expose services to the internet. Use VPC endpoints and PrivateLink:
# Terraform: VPC with no internet gateway for workloads
resource "aws_vpc" "zero_trust" {
cidr_block = "10.0.0.0/16"
enable_dns_hostnames = true
enable_dns_support = true
tags = { Name = "zero-trust-vpc" }
}
# Private subnets only — no public subnets
resource "aws_subnet" "private" {
count = 3
vpc_id = aws_vpc.zero_trust.id
cidr_block = cidrsubnet("10.0.0.0/16", 8, count.index)
availability_zone = data.aws_availability_zones.available.names[count.index]
tags = { Name = "private-${count.index}" }
}
# VPC Endpoint for S3 (gateway type — free)
resource "aws_vpc_endpoint" "s3" {
vpc_id = aws_vpc.zero_trust.id
service_name = "com.amazonaws.${var.region}.s3"
vpc_endpoint_type = "Gateway"
route_table_ids = [aws_route_table.private.id]
}
# VPC Endpoint for SSM (interface type — for session manager)
resource "aws_vpc_endpoint" "ssm" {
vpc_id = aws_vpc.zero_trust.id
service_name = "com.amazonaws.${var.region}.ssm"
vpc_endpoint_type = "Interface"
subnet_ids = aws_subnet.private[*].id
security_group_ids = [aws_security_group.vpce.id]
private_dns_enabled = true
}AWS Verified Access
For application-level zero trust without a VPN:
# Create a Verified Access trust provider (using IAM Identity Center)
aws ec2 create-verified-access-trust-provider \
--trust-provider-type user \
--user-trust-provider-type iam-identity-center \
--policy-reference-name "IdentityCenter"
# Create Verified Access instance
aws ec2 create-verified-access-instance \
--description "Zero Trust App Access"
# Attach trust provider to instance
aws ec2 attach-verified-access-trust-provider \
--verified-access-instance-id vai-0123456789 \
--verified-access-trust-provider-id vatp-0123456789Detection: GuardDuty + Security Hub
# Enable GuardDuty with all protection plans
aws guardduty create-detector \
--enable \
--data-sources '{
"S3Logs": {"Enable": true},
"Kubernetes": {"AuditLogs": {"Enable": true}},
"MalwareProtection": {"ScanEc2InstanceWithFindings": {"EbsVolumes": true}},
"RuntimeMonitoring": {"Enable": true}
}'
# Enable Security Hub with CIS benchmark
aws securityhub enable-security-hub \
--enable-default-standardsAzure: Building Zero Trust#
Identity: Conditional Access + PIM
Azure's zero trust starts with Entra ID (formerly Azure AD) Conditional Access:
# Create a Conditional Access policy requiring MFA for all cloud apps
Connect-MgGraph -Scopes "Policy.ReadWrite.ConditionalAccess"
$policy = @{
displayName = "Require MFA for All Users"
state = "enabled"
conditions = @{
users = @{ includeUsers = @("All") }
applications = @{ includeApplications = @("All") }
signInRiskLevels = @("medium", "high")
}
grantControls = @{
operator = "OR"
builtInControls = @("mfa")
}
sessionControls = @{
signInFrequency = @{
value = 4
type = "hours"
isEnabled = $true
}
}
}
New-MgIdentityConditionalAccessPolicy -BodyParameter $policy
# Enable PIM for just-in-time admin access
# Activate a role assignment (time-limited)
$params = @{
action = "selfActivate"
principalId = "user-object-id"
roleDefinitionId = "role-id"
directoryScopeId = "/"
justification = "Incident response - ticket INC-2026-0142"
scheduleInfo = @{
startDateTime = (Get-Date).ToString("o")
expiration = @{
type = "afterDuration"
duration = "PT4H"
}
}
}
New-MgRoleManagementDirectoryRoleAssignmentScheduleRequest -BodyParameter $paramsNetwork: NSG/ASG + Private Link
# Create Application Security Group for web tier
az network asg create -g rg-zerotrust -n asg-web-tier
# Create NSG with micro-segmentation rules
az network nsg create -g rg-zerotrust -n nsg-app-tier
# Allow only web tier to reach app tier on port 8443
az network nsg rule create \
-g rg-zerotrust --nsg-name nsg-app-tier \
-n AllowWebToApp --priority 100 \
--source-asgs asg-web-tier \
--destination-asgs asg-app-tier \
--destination-port-ranges 8443 \
--protocol Tcp --access Allow
# Deny everything else
az network nsg rule create \
-g rg-zerotrust --nsg-name nsg-app-tier \
-n DenyAll --priority 4096 \
--source-address-prefixes '*' \
--destination-address-prefixes '*' \
--destination-port-ranges '*' \
--protocol '*' --access Deny
# Create Private Endpoint for Azure SQL
az network private-endpoint create \
-g rg-zerotrust -n pe-sql-prod \
--vnet-name vnet-zerotrust --subnet snet-data \
--private-connection-resource-id "/subscriptions/.../Microsoft.Sql/servers/sql-prod" \
--group-ids sqlServer \
--connection-name sql-prod-connectionDetection: Microsoft Sentinel
# Enable Sentinel on Log Analytics workspace
az sentinel onboarding-state create \
--resource-group rg-security \
--workspace-name law-sentinel-prod \
--name default
# Enable Entra ID data connector
az sentinel data-connector connect \
--resource-group rg-security \
--workspace-name law-sentinel-prod \
--data-connector-name AzureActiveDirectoryGCP: Building Zero Trust#
BeyondCorp Enterprise
Google invented the zero trust concept with BeyondCorp. GCP's implementation is the most mature:
# Enable BeyondCorp Enterprise API
gcloud services enable beyondcorp.googleapis.com
# Create an access level based on device policy
gcloud access-context-manager levels create corp-device-trusted \
--title="Corporate Trusted Devices" \
--basic-level-spec=level-spec.yaml \
--policy=POLICY_ID
# level-spec.yaml content:
# conditions:
# - devicePolicy:
# requireScreenlock: true
# osConstraints:
# - osType: DESKTOP_CHROME_OS
# requireVerifiedChromeOs: true
# - osType: DESKTOP_MAC
# minimumVersion: "14.0"
# regions:
# - AE
# - USVPC Service Controls
# Create a service perimeter to protect sensitive APIs
gcloud access-context-manager perimeters create prod-perimeter \
--title="Production Data Perimeter" \
--resources="projects/123456789" \
--restricted-services="bigquery.googleapis.com,storage.googleapis.com,secretmanager.googleapis.com" \
--access-levels="accessPolicies/POLICY/accessLevels/corp-device-trusted" \
--policy=POLICY_ID
# Organization policy: enforce uniform bucket-level access
gcloud resource-manager org-policies enable-enforce \
constraints/storage.uniformBucketLevelAccess \
--organization=ORG_ID
# Organization policy: restrict VM external IPs
gcloud resource-manager org-policies set-policy \
--organization=ORG_ID policy.yaml
# policy.yaml:
# constraint: constraints/compute.vmExternalIpAccess
# listPolicy:
# allValues: DENYChronicle SIEM Integration
# Forward GCP audit logs to Chronicle
gcloud logging sinks create chronicle-sink \
"chronicle.googleapis.com/projects/PROJECT/locations/REGION/instances/INSTANCE" \
--log-filter='logName:"cloudaudit.googleapis.com"' \
--organization=ORG_IDCross-Cloud Comparison#
| Capability | AWS | Azure | GCP |
|---|---|---|---|
| **Identity Provider** | IAM Identity Center | Entra ID | Cloud Identity |
| **Conditional Access** | Verified Access | Conditional Access | BeyondCorp / IAP |
| **JIT Privileged Access** | IAM Roles Anywhere | PIM | PAM (preview) |
| **Network Micro-seg** | Security Groups + PrivateLink | NSG/ASG + Private Link | VPC Firewall Rules + Service Controls |
| **API Perimeter** | VPC Endpoints | Private Endpoints | VPC Service Controls |
| **Threat Detection** | GuardDuty | Defender for Cloud | SCC + Chronicle |
| **Policy Guardrails** | SCPs + Config Rules | Azure Policy | Organization Policies |
| **MFA Enforcement** | IAM Policy Conditions | Conditional Access | Context-Aware Access |
Zero Trust Authentication Flow#
Common Pitfalls#
1. "We deployed a ZTNA tool so we're zero trust now." A tool is not an architecture. Zero trust requires changes to identity, network, application, and data layers simultaneously.
2. Overprivileged service accounts. You locked down human access but your Terraform service account has AdministratorAccess. Attackers target the weakest link.
3. Ignoring east-west traffic. Most organizations focus on north-south (ingress/egress) but lateral movement between workloads is the real killer. Implement micro-segmentation.
4. No continuous monitoring. Zero trust without detection is just access control. You need GuardDuty/Defender/SCC feeding a SIEM with automated response.
5. Skipping data classification. If you don't know which data is sensitive, you can't apply the right controls. Start with DSPM before building complex policy engines.
Where Elastyx Fits#
Elastyx provides continuous posture validation across all three clouds — the single pane of glass that tells you whether your zero trust architecture is actually working or just configured on paper. We check IAM policies, network segmentation, encryption settings, and detection coverage in real-time across AWS, Azure, and GCP simultaneously.