AWS Organization Policy Controls
Service Control Policies (SCP) & Resource Control Policies (RCP) act as organizational firewalls
Effective Permissions
Data Perimeter
SCP Demo
RCP Demo
Reset
Step 1: Configure Policy
SCP — Service Control Policy
Deny ec2:* if SourceVpc != vpc-prod
Deny sts:AssumeRole from unknown IPs
attached to
AWS Organization
cascades down to
OU — Production
enforced at
SCP FIREWALL
Step 2: Traffic
IAM Principals
IAM User A (legit)
IAM User B (stolen)
SSO Role
Lambda Role
BLOCKED by SCP
Evaluating request...
SourceVpc: external-ip
DENY -- vpc condition failed
VPC (vpc-prod)
Protected Resources
EC2 Instances
RDS Databases
Lambda Functions
EKS / Secrets Mgr
Scenario: Compromised Credential Blocked
Attacker steals IAM User B creds, calls ec2:RunInstances from external IP. SCP denies: SourceVpc != vpc-prod.
Result: Zero lateral movement, even with valid credentials.
Allowed
Malicious
SCP Wall
Step 1: Configure Policy
RCP — Resource Control Policy
Deny s3:* if !PrincipalOrgID
Deny PutBucketPolicy with Principal: "*"
attached to
AWS Organization
cascades down to
OU — Production
enforced at
RCP FIREWALL
Step 2: Traffic
Access Requests
Internal App
Public Anonymous
Trusted Partner
Cross-Acct Exfil
BLOCKED by RCP
Evaluating request...
PrincipalOrgID: (none)
DENY -- not in organization
S3 & PaaS
Protected Resources
customer-data
audit-logs
app-configs
backups / DynamoDB
Scenario: Public S3 Access & Cross-Account Exfil Blocked
Developer sets bucket policy with Principal:"*". Attacker attempts s3:GetObject from external account.
Result: Data stays private. RCP enforces PrincipalOrgID regardless of bucket policy.
Allowed
Malicious
Net Effective Permissions = Intersection of All Policy Layers
A request must pass EVERY layer. Any single deny = request denied.
SCOPE
Org / OU
Org / OU
Per Resource
Per Identity
Per Identity
GUARDRAIL
Resource Control Policy (RCP)
Sets maximum access for ALL resources in every account under the OU/Org
Deny s3:* if !PrincipalOrgID
Deny PutBucketPolicy Principal:*
must pass
GUARDRAIL
Service Control Policy (SCP)
Sets maximum permissions for ALL identities in every account under the OU/Org
Deny ec2:* outside VPC
Deny sts:* unknown IPs
Deny iam:CreateUser
must pass
GRANT
Resource Policy
Who can access this specific resource (attached to S3 bucket, KMS key, etc.)
S3 bucket policy: Allow account X
KMS key policy: Allow role Y
must pass
GUARDRAIL
IAM Permissions Boundary
Caps the maximum permissions for a specific IAM user or role
Allow only s3:Get*, ec2:Describe*
Scoped per user / role
must pass
GRANT
Identity Policy (IAM Policy)
What this specific user/role is allowed to do (attached to the principal)
Allow ec2:*, s3:GetObject
Attached to user / role / group
Effective Permission = Allowed by ALL layers
Any single layer deny = request denied
✓
✓
✓
✓
✓
AWS Data Perimeter — Three Dimensions of Trust
Click a scenario on the left to see which trust gate blocks it
1 · IDENTITY · RCP
Misconfigured bucket policy (Principal:*)
External account reads S3 customer data
2 · IDENTITY · VPC EP
Personal AWS creds on corporate network
Dev brings personal access keys into VPC
3 · RESOURCE · SCP
Insider exfils data to personal S3 bucket
s3:CopyObject to account outside org
4 · RESOURCE · VPC EP
Compromised app writes to attacker bucket
Malware uploads via VPC endpoint
5 · NETWORK · SCP
Stolen creds used from attacker's network
Keys leaked on GitHub, called from 185.42.x.x
6 · NETWORK · RCP
Employee accesses S3 from home laptop
Valid SSO creds from home WiFi, no VPN
AWS API Request
WHO?
Identity Trust
PrincipalOrgID
PrincipalAccount
SourceOrgID
Enforced by: RCP + VPC EP
WHAT?
Resource Trust
ResourceOrgID
ResourceAccount
CalledVia
Enforced by: SCP + VPC EP
WHERE?
Network Trust
SourceVpc / SourceIp
VpceOrgID
ViaAWSService
Enforced by: SCP + RCP
ALL three must pass — any failure = DENY
Your Data & Resources
S3, RDS, KMS, Secrets, EC2, Lambda, EKS
Accessible only when all 3 trust checks pass
Identity Trust check (RCP):
aws:PrincipalOrgID = 999888777 (not in org)
DENY — untrusted identity
RCP: Deny s3:* where PrincipalOrgID != o-myorg
Identity Trust check (VPC EP):
aws:PrincipalOrgID = (dev's personal account)
DENY — non-org identity on org network
VPC EP: Allow only PrincipalOrgID = o-myorg
Resource Trust check (SCP):
aws:ResourceOrgID = (personal acct, not in org)
DENY — untrusted destination
SCP: Deny s3:* where ResourceOrgID != o-myorg
Resource Trust check (VPC EP):
aws:ResourceOrgID = (attacker's account)
DENY — untrusted resource via endpoint
VPC EP: Allow only ResourceOrgID = o-myorg
Network Trust check (SCP):
SourceVpc=(none) · SourceIp=185.42.x.x
DENY — not from expected network
SCP: Deny * where SourceVpc != vpc-prod
Network Trust check (RCP):
SourceIp = home IP (not corp/VPC range)
DENY — resource blocks non-corp net
RCP: Deny s3:* where SourceVpc not in org