Zero-Trust Networking on AWS with IAM Identity Center and SCPs
Naveen Teja
3/2/2026

Traditional perimeter-based security assumes everything inside the network is trusted. In a modern cloud environment where developers work remotely, third-party contractors access systems, and microservices communicate across accounts, this model is fundamentally broken. Zero-trust security operates on the principle of 'never trust, always verify' — every request must be authenticated and authorized regardless of its origin.
On AWS, zero-trust is implemented through a layered combination of controls. IAM Identity Center (formerly SSO) provides centralized, federated identity management — developers authenticate via your corporate IdP (Okta, Azure AD) and receive time-limited role credentials. Service Control Policies (SCPs) at the AWS Organizations level act as a guardrail that cannot be overridden even by account administrators, preventing actions like disabling CloudTrail or creating IAM users with console access.
The most powerful SCP patterns include: denying all actions outside approved regions (data sovereignty), requiring MFA for sensitive operations like deleting S3 buckets, and blocking root account usage entirely. Combined with VPC Security Groups enforcing least-privilege network access, this creates a true zero-trust posture. The SCP below implements a deny-list that prevents resource creation outside pre-approved AWS regions, which is a critical compliance requirement for GDPR and data residency.
# SCP: Deny actions outside approved regions
resource "aws_organizations_policy" "region_restriction" {
name = "RestrictToApprovedRegions"
description = "Deny all resource creation outside us-east-1 and ap-south-1"
type = "SERVICE_CONTROL_POLICY"
content = jsonencode({
Version = "2012-10-17"
Statement = [
{
Sid = "DenyOutsideApprovedRegions"
Effect = "Deny"
NotAction = [
"iam:*",
"organizations:*",
"support:*",
"sts:*"
]
Resource = "*"
Condition = {
StringNotEquals = {
"aws:RequestedRegion" = ["us-east-1", "ap-south-1"]
}
}
},
{
Sid = "DenyRootAccountActions"
Effect = "Deny"
Action = "*"
Resource = "*"
Condition = {
StringLike = {
"aws:PrincipalArn" = "arn:aws:iam::*:root"
}
}
}
]
})
}
resource "aws_organizations_policy_attachment" "region_restriction" {
policy_id = aws_organizations_policy.region_restriction.id
target_id = aws_organizations_organizational_unit.workloads.id
}You might also like

Migrating from EC2 to AWS Fargate: A Step-by-Step Guide

Multi-Region Active-Active Architecture on AWS

Implementing AWS GuardDuty with Automated Threat Response

OpenTofu vs Terraform in 2024: Migration Guide and Key Differences

AWS Cost Optimization: 10 Terraform Patterns to Cut Your Bill by 40%
