Cloud Security: IAM, Network Isolation, and Encryption
Implement defense-in-depth security for cloud infrastructure—identity and access management, network isolation, encryption, and security monitoring.
Cloud security depends on layered identity, network, and encryption controls because a trusted perimeter cannot protect every workload. The guide explains least-privilege IAM, short-lived workload credentials, subnet isolation, VPC endpoints, key management, and monitoring with AWS examples, while comparing native tools with cross-cloud platforms. It also walks through common misconfigurations and incident scenarios so readers can choose practical controls and spot gaps before they become breaches.
Cloud Security: IAM, Network Isolation, and Encryption
Introduction
Cloud security cannot rely on a trusted network perimeter. Publicly reachable resources and overly broad access rules can expose systems, so identity, network isolation, and encryption need to reinforce one another.
This guide covers cloud-neutral security practices using AWS examples, including IAM, workload identity, VPC boundaries, encryption, provider tools, and monitoring. It also compares native security services with cross-cloud tooling and examines operational failures.
When to Use
Cloud-Native Security Services vs. Third-Party
Cloud-native security tools like Security Hub, GuardDuty, and CloudTrail on AWS integrate tightly with the provider’s control plane. Findings surface in the same console where you manage everything else. CloudTrail Event history records management events, while trails and event data stores need explicit selectors for data events such as S3 object access. The upside is simplicity: enable a service, get findings, done. The downside is that Security Hub only sees AWS. If you run EKS and Azure SQL in parallel, you are checking two separate consoles and correlating two separate streams of findings.
Third-party tools like Wiz, Prisma Cloud, and SentinelOne take the opposite approach. They ingest findings from every cloud provider and on-premises systems into one dashboard. This unified view matters when your environment is actually multi-cloud or when you need compliance reporting that spans providers. The tradeoff is added complexity: someone has to configure the integration, manage the vendor relationship, and pay for another subscription. Most organizations that go third-party also keep cloud-native tools running in each provider because the native services catch things the aggregator misses.
The detection coverage difference is where the separation gets real. GuardDuty uses machine learning trained on AWS-specific attack patterns. It catches things like unusual S3 access from an unusual location, brute force attempts on SSH, or cryptocurrency mining behavior in EC2. Third-party CSPMs use rules-based detection that works across providers but may miss AWS-specific signals that GuardDuty catches because the aggregation logic does not replicate the provider-native detection engine. Many organizations run both: GuardDuty for AWS-specific threats, the CSPM for cross-provider visibility and compliance reporting.
For single-cloud environments, cloud-native tools are usually sufficient. Security Hub plus GuardDuty plus CloudTrail give you threat detection, compliance monitoring, and audit logging. The CSPM aggregation overhead is not worth it if you only have one provider. For multi-cloud environments, the moment you have EKS on AWS and Azure SQL on Azure, you have two separate security consoles. A CSPM that aggregates findings into one dashboard makes cross-provider incident response faster. The cost is the integration complexity and the license.
The layered approach that works in practice: cloud-native tools handle core detection in each provider (always on, low overhead), a CSPM aggregates for cross-provider visibility, and a SIEM or SOAR tool automates response playbooks. This is not cheap and requires dedicated security engineering to operate. Pricing reality: cloud-native tools charge per consume or per-asset. CSPMs like Wiz and Prisma Cloud charge per-asset pricing that can get expensive at scale. Factor in the total security tooling cost including the CSPM before deciding.
| Factor | Cloud-Native | Third-Party CSPM |
|---|---|---|
| Detection depth | AWS-specific ML models, high accuracy on AWS threats | Rules-based, cross-provider, may miss provider-specific signals |
| Operational overhead | Low (enable per-service, native console) | High (integration setup, vendor management, ongoing config) |
| Multi-cloud support | Single provider only | Unified view across all providers |
| Cost model | Per-consume or per-asset | Per-asset, scales expensively |
| Compliance reporting | Per-provider | Cross-provider, aggregated |
| Best for | Single-cloud, AWS-focused environments | Multi-cloud, complex hybrid environments |
In practice, start with cloud-native detection in each provider. Add a third-party aggregator when the overhead of checking multiple consoles becomes a real burden, and use a SIEM or SOAR tool if your response process needs centralized analysis or automation.
VPC Endpoints vs. NAT Gateway
The difference between VPC endpoints and NAT gateways comes down to what traffic you need and where it goes. Gateway endpoints route traffic from your VPC to S3 or DynamoDB without a NAT gateway; interface endpoints use AWS PrivateLink for supported services. Gateway endpoints have no hourly charge, while interface endpoints and NAT gateways have separate hourly and data-processing charges. NAT gateways provide internet egress from private subnets.
For private subnets that only need S3 or DynamoDB, gateway endpoints avoid NAT data-processing fees. A common production setup uses private subnets for application servers, an outbound route such as a NAT gateway for package downloads or external APIs, and gateway endpoints for S3 and DynamoDB. If S3 traffic uses a NAT gateway, it adds NAT processing charges.
The catch is that VPC endpoints only work for AWS services. If your private instances need to reach anything else on the internet, you need a NAT gateway or some other outbound route. Some teams also run VPC endpoints alongside NAT gateways intentionally, using endpoints for AWS service traffic and the NAT for everything else. This works fine as long as your route tables are explicit about which traffic goes where. Misconfigured route tables that send endpoint traffic through the NAT are a common source of unexpected bills.
For S3, a gateway endpoint adds routes for S3 prefix lists so matching traffic uses the AWS network without a NAT gateway. Without that endpoint, private-subnet traffic typically uses its configured outbound route, such as a NAT gateway. Endpoint type and regional pricing affect the cost, so compare them with your traffic volume and deployment needs.
The security angle matters for production workloads. VPC endpoints can have endpoint policies that restrict access to specific buckets or actions. A misconfigured application that tries to list all S3 buckets gets denied by the endpoint policy even if the IAM role allows s3:* on all resources. This is defense in depth at the network layer: IAM says what the role can do, the endpoint policy says what can actually be reached. Without the endpoint policy, the IAM permission is the only control, and a typo in a bucket policy or an overly broad IAM statement becomes the only thing stopping a data breach.
VPC endpoints cannot replace an outbound route for every destination. Patching from public repositories, downloading packages from public registries, calling third-party APIs, and fetching vendor software all require internet egress or another configured path, such as a proxy. A NAT gateway is one common way to provide that egress from private subnets.
Teams that route S3 traffic through NAT gateways can accumulate data-processing fees. For S3 and DynamoDB, gateway endpoints avoid those NAT processing charges; check regional pricing for any other endpoint types in use.
Route table priority is where teams get confused. VPC endpoint traffic uses the VPC route table local prefix, which takes precedence over 0.0.0.0/0 NAT routes. This means adding a VPC endpoint does not automatically route all S3 traffic through it. Only traffic destined for the specific S3 prefix lists uses the endpoint route. The confusion comes from assuming VPC endpoints work like NAT for all destinations. When you add a VPC endpoint, you are adding a specific route for S3 prefix lists, not a catch-all redirect.
| Factor | VPC Endpoints | NAT Gateway |
|---|---|---|
| Cost | Gateway: no hourly charge; interface: billed by endpoint and data | Hourly and data-processing charges |
| Latency | Private routing to supported AWS services | Outbound route through NAT gateway |
| Security | Endpoint policies restrict access to specific buckets/actions | No endpoint policy, relies on IAM only |
| Use case | AWS services only (S3, DynamoDB, Secrets Manager) | Any outbound internet (patching, public APIs, registries) |
| Route priority | Local prefix takes precedence over 0.0.0.0/0 | 0.0.0.0/0 catches all unmatched traffic |
| Best for | Private subnets accessing AWS services | Private subnets needing internet access |
Customer-Managed KMS Keys vs. Cloud-Managed Keys
Customer-managed KMS keys cost roughly $1 per month per key plus data processing fees per API call. In return, you control the key policy, can restrict which principals can use it, and can allow cross-account access by editing the policy directly. Key rotation happens on a schedule you define, and every Encrypt/Decrypt operation is logged in CloudTrail with the key ID, caller identity, and timestamp. If an auditor asks which identities accessed your encryption keys last quarter, you can answer that question with CloudTrail.
Cloud-managed keys are free and rotate automatically every year. AWS handles the policy and access control. The limitation is that you cannot view or modify the key policy, and you cannot share the key across accounts. This is fine for development environments and non-sensitive workloads. It is a real problem when your compliance framework requires you to demonstrate who had access to encryption keys, or when you need to share encrypted data with a workload in another account.
The risk with customer-managed keys that catches teams off guard is deletion without a grace period. If you schedule a KMS key for immediate deletion and you have data encrypted under that key, that data is gone. AWS enforces a minimum 7-day waiting period by default and you can extend it to 30 days, but the default exists because teams have permanently lost access to production data this way. Always set the deletion window to the maximum and verify nothing is still encrypted under the key before you delete it.
IAM Best Practices
Identity and Access Management (IAM) is the foundation of cloud security. Every request to a cloud API requires authentication and authorization. IAM policies determine what identities can do what operations on which resources.
The cardinal rule is least privilege: grant only the permissions required for a task, and nothing more. This applies to human users, service accounts, and compute workloads.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "S3ReadOnlyForApplication",
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:ListBucket"],
"Resource": ["arn:aws:s3:::my-app-bucket", "arn:aws:s3:::my-app-bucket/*"]
}
]
}
Avoid attaching policies directly to users. Instead, create groups for roles, add users to groups, and attach policies to groups. This makes permission management systematic rather than ad hoc.
# Create a group
aws iam create-group --group-name developers
# Attach a policy to the group
aws iam attach-group-policy \
--group-name developers \
--policy-arn arn:aws:iam::aws:policy/ReadOnlyAccess
# Add a user to the group
aws iam add-user-to-group \
--group-name developers \
--user-name alice
Regularly audit IAM configurations. AWS Access Analyzer, Azure AD external identities, and GCP Policy Analyzer can identify permissions that grant external access or violate least privilege. Remove unused access keys, deactivate old credentials, and rotate secrets on a schedule.
Service Accounts and Workload Identity
Human users are not the only identities in cloud environments. Compute workloads—EC2 instances, containers, Lambda functions—need permissions to access other AWS services. The question is how those workloads authenticate.
Storing long-lived access keys in code or environment variables is risky. EC2 instance profiles provide temporary role credentials; workloads should use those credentials through the SDK instead of storing static keys. Credentials exposed in logs or environment variables can still be stolen and misused.
Workload identity is the solution. Instead of storing credentials, workloads assume a role using short-lived tokens. The role permissions are scoped to what the workload actually needs.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
For Kubernetes workloads, cloud providers offer operators that project Kubernetes service account tokens into cloud IAM roles. This lets you create Kubernetes service accounts with specific IAM permissions without managing cloud credentials.
# Kubernetes service account with IAM role
apiVersion: v1
kind: ServiceAccount
metadata:
name: my-app
namespace: production
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: my-app-role
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: my-app-role-binding
subjects:
- kind: ServiceAccount
name: my-app
namespace: production
kind: Role
name: my-app-role
VPC and Network Isolation
Network isolation in cloud environments uses virtual private clouds (VPCs) with subnet segmentation. The principle is straightforward: nothing should be directly accessible from the internet unless intentionally exposed.
# VPC with public and private subnets
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
enable_dns_hostnames = true
enable_dns_support = true
}
# Public subnets for load balancers
resource "aws_subnet" "public" {
count = 2
vpc_id = aws_vpc.main.id
cidr_block = cidrsubnet(aws_vpc.main.cidr_block, 8, count.index)
availability_zone = data.aws_availability_zones.available.names[count.index]
map_public_ip_on_launch = true
tags = {
Type = "Public"
}
}
# Private subnets for application servers
resource "aws_subnet" "private" {
count = 2
vpc_id = aws_vpc.main.id
cidr_block = cidrsubnet(aws_vpc.main.cidr_block, 8, count.index + 10)
availability_zone = data.aws_availability_zones.available.names[count.index]
tags = {
Type = "Private"
}
}
# NAT gateway for outbound traffic from private subnets
resource "aws_eip" "nat" {
domain = "vpc"
}
resource "aws_nat_gateway" "main" {
allocation_id = aws_eip.nat.id
subnet_id = aws_subnet.public[0].id
}
resource "aws_route_table" "private" {
vpc_id = aws_vpc.main.id
route {
cidr_block = "0.0.0.0/0"
nat_gateway_id = aws_nat_gateway.main.id
}
}
Application servers sit in private subnets and cannot be reached directly from the internet. Load balancers in public subnets route traffic to application servers. Database and cache servers sit in private subnets with no internet access at all.
Security groups act as instance-level firewalls. They are stateful: allowing inbound traffic automatically allows outbound response traffic.
# Security group for web servers
resource "aws_security_group" "web" {
name = "web-servers"
description = "Security group for web servers"
vpc_id = aws_vpc.main.id
# Allow inbound HTTP/HTTPS from load balancer
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["10.0.1.0/24"] # Private subnet CIDR
}
# Allow outbound to internet via NAT
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
Encryption at Rest and in Transit
Encrypt data wherever it lives. Cloud providers offer encryption at rest by default for most services, using KMS keys you control or provider-managed keys.
# S3 bucket with encryption
resource "aws_s3_bucket" "data" {
bucket = "my-sensitive-data"
server_side_encryption_configuration {
rule {
apply_server_side_encryption_by_default {
sse_algorithm = "aws:kms"
kms_key_id = aws_kms_key.data.arn
}
}
}
}
# KMS key with restricted usage
resource "aws_kms_key" "data" {
description = "KMS key for sensitive data"
deletion_window_in_days = 30
enable_key_rotation = true
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Sid = "Enable IAM User Permissions"
Effect = "Allow"
Principal = {
AWS = "arn:aws:iam::123456789:root"
}
Action = "kms:*"
Resource = "*"
},
{
Sid = "Allow use by application"
Effect = "Allow"
Principal = {
Service = "ec2.amazonaws.com"
}
Action = ["kms:Encrypt", "kms:Decrypt"]
Resource = "*"
}
]
})
}
TLS encrypts data in transit. Force HTTPS on all public endpoints. Use TLS for connections between services, especially when they cross network boundaries. Certificate management can be automated with services like AWS Certificate Manager or Let’s Encrypt.
Security Groups and Firewall Rules
Security groups should be as restrictive as possible. Start with deny all inbound, allow specific ports and sources.
# Database security group - minimal access
resource "aws_security_group" "database" {
name = "database"
description = "Security group for RDS instance"
vpc_id = aws_vpc.main.id
# No inbound rules - RDS is only reachable from application tier
# via security group references
egress {
from_port = 5432
to_port = 5432
protocol = "tcp"
security_groups = [aws_security_group.app.id]
}
}
Network ACLs provide subnet-level filtering as a secondary control. Security groups handle instance-level filtering. Use both together: NACLs for subnet-wide rules like blocking a specific IP range, security groups for instance-specific access control.
VPC endpoint policies restrict which actions are allowed through an endpoint. Without an endpoint, traffic follows the VPC’s configured route to the service, often through a NAT gateway for private subnets. An endpoint can keep service traffic on the AWS network and add a policy boundary.
Cloud-Native Security Services
Each major cloud provider offers security services that layer on top of basic IAM and networking.
AWS Security Hub aggregates findings from GuardDuty, Inspector, and Macie. Azure Security Center and GCP Security Command Center play similar roles. These services provide centralized visibility and compliance monitoring across your cloud footprint.
Cloud-native firewalls and WAFs filter traffic at the edge. AWS WAF works with CloudFront and Application Load Balancers, Azure WAF with Application Gateway, and GCP Cloud Armor with Cloud CDN and load balancers. A WAF adds a useful layer for exposed HTTP services, but it does not replace secure application code or restricted network access.
Logging and monitoring make incident response possible. CloudTrail records management events by default in Event history; configure trails and event selectors for the management and data events your audit requirements need. VPC Flow Logs capture selected network flow metadata, and GuardDuty uses threat intelligence and anomaly detection to flag suspicious activity. Route relevant findings and logs to a SIEM or analytics platform.
Defense-in-Depth Architecture
flowchart TD
A[Internet Traffic] --> B[WAF / Cloud Firewall]
B --> C[Load Balancer]
C --> D[Security Groups]
D --> E[Application Tier]
E --> F[Database Tier]
F --> G[KMS Encryption]
A --> H[IAM Authentication]
H --> E
E --> I[VPC Endpoints]
I --> J[S3 / DynamoDB]
Trade-off Analysis
| Security Control | Complexity | Security Benefit | Best For |
|---|---|---|---|
| Customer-managed KMS keys | High | Full audit and rotation control | Regulated workloads, cross-account access |
| Cloud-managed KMS keys | Low | Automatic rotation, no cost | Development, non-sensitive workloads |
| VPC endpoints | Medium | Traffic stays internal, lower cost | Private access to S3, DynamoDB from private subnets |
| NAT gateway for private traffic | Medium | Outbound-only internet for private subnets | Patching, external API calls from private instances |
| Security groups | Low | Instance-level stateful firewall | Primary network isolation for compute |
| NACLs | Medium | Subnet-level stateless filtering | Broad subnet rules, blocking specific CIDRs |
| IAM roles over user credentials | Low | Short-lived tokens, no credential management | All compute workloads |
Production Failure Scenarios
| Failure | Impact | Mitigation |
|---|---|---|
| IAM role trust policy misconfiguration locking out resources | Resources cannot assume roles, deployments fail | Use AWS Access Analyzer before deploying, test trust policies in dev |
| KMS key deletion without waiting for grace period | Encrypted data becomes irrecoverable | Use 7-30 day deletion windows, never delete keys with production data |
| Security group overly restrictive blocking legitimate traffic | Application cannot connect to dependencies, outages | Always test security group changes in staging first, use descriptive names |
| VPC endpoint policy denying required S3 access | Application cannot read from S3, deployments fail | Explicitly list required actions in endpoint policy, test after changes |
| CloudTrail not enabled for all regions | Attack activity in disabled regions goes unlogged | Enable CloudTrail across all regions, aggregate to single bucket |
Cloud Security Observability
What to monitor:
CloudTrail monitors all API calls. Enable it in all regions and route logs to a centralized bucket with object lock to prevent tampering.
GuardDuty monitors for compromised workloads. Review findings daily and route alerts to your security team’s notification channel.
Security Hub aggregates findings from GuardDuty, Inspector, and Macie into a unified view. Enable all integrated services for complete coverage.
VPC Flow Logs record source and destination IPs, ports, and bytes transferred. Use Flow Logs to detect lateral movement and unusual traffic patterns.
Key commands and queries:
# List recent CloudTrail events
aws cloudtrail lookup-events --max-results 10
# Get GuardDuty findings
aws guardduty list-findings \
--detector-id abc123 \
--finding-criteria '{"Severity": [{"Eq": ["HIGH"]}]}'
# Query VPC Flow Logs for port 22 access
aws logs insights query \
--log-group-name /aws/vpc/flow-logs \
--query-string 'fields srcAddr, dstAddr, dstPort, action | filter dstPort = 22 | limit 20'
# Check IAM access analyzer findings
aws accessanalyzer list-findings \
--analyzer-name my-analyzer
Common Pitfalls / Anti-Patterns
Using AWS root account for daily operations. The root account has full permissions and cannot be restricted by IAM policies. Use root account only for initial setup, then switch to IAM users and roles for everything else.
Over-permissive IAM roles. Granting *:* or AdministratorAccess to workloads because it is faster than scoping permissions defeats the purpose of least privilege. Start with minimal permissions and add only what the workload actually needs.
Leaving security groups open to 0.0.0.0/0. Allowing all inbound traffic to a database or cache port from anywhere on the internet is a common breach vector. Security groups should restrict access to known CIDRs or specific security groups.
Not enabling encryption by default. Some services allow creating unencrypted resources by default. Enforce encryption through service control policies or AWS Config rules so new resources cannot be created without encryption.
Forgetting to rotate access keys. Long-lived access keys on service accounts are a common exfiltration target. Rotate keys regularly, use short-lived credentials via IAM roles wherever possible.
Trade-off Analysis (Tools)
| Security Tool | Preventative vs Detective | CI/CD vs Runtime | Cost |
|---|---|---|---|
| Cloud-native (GuardDuty, Security Hub, Defender) | Detective | Runtime | Pay per consume |
| CSPM (Prisma Cloud, Wiz) | Both | Runtime | Per-asset pricing |
| SAST / IaC scanning | Preventative | CI/CD | Tool cost |
| Secret scanning (Gitleaks, TruffleHog) | Preventative | CI/CD | Free / paid tiers |
| Runtime security (Falco, Sysdig) | Detective | Runtime | Infrastructure + license |
| SIEM (Splunk, Elastic) | Detective | Runtime | High (licensing + storage) |
Real-world Failure Scenarios
| Company / Context | Failure | Consequence | Lesson Learned |
|---|---|---|---|
| Target breach (2013) | IAM credentials for HVAC vendor abused to access POS systems | 70 million customer records exposed | Segment networks; vendor access should never reach POS systems regardless of credentials valid |
| Capital One breach (2019) | Overly permissive IAM role allowing S3 access from external | 100 million customer records exposed | Use SCPs to block cross-account access; Audit trust policies regularly |
| Toyota data exposure (2019) | S3 bucket public; CloudTrail not enabled for region | Customer data accessible; attack undetected | Enable CloudTrail everywhere; Block public S3 access by default |
| Meow ransomware attacks | Elasticsearch and MongoDB with no authentication exposed | Petabytes of data encrypted by ransom | Network access controls alone are insufficient; Authentication required on all data stores |
| SolarWinds supply chain attack (2020) | Software build process compromised; malicious update pushed | 18,000+ organizations breached | Verify software supply chain integrity; sign releases; monitor for anomalous build behavior |
Quick Recap Checklist
- Defense in depth means layering IAM, network isolation, and encryption—not relying on any single control.
- Least privilege is the cardinal rule: grant only the permissions needed, nothing more.
- IAM roles with short-lived credentials reduce the need to store long-lived keys in code or environment variables.
- VPC endpoints keep traffic internal and avoid NAT gateway costs for private resource access.
- CloudTrail, GuardDuty, and Security Hub provide the monitoring foundation for any AWS environment.
Interview Questions
Implementation starts with understanding what permissions your identities actually need rather than defaulting to broad policies. Use IAM Access Analyzer to identify external access and policy simulators to test policies before deployment. Create groups for roles, attach policies to groups, and add users to groups rather than attaching policies directly to users. Regularly audit unused access keys and deactivate old credentials.
NAT gateways handle outbound internet access for private instances—for patching, downloading packages, calling external APIs. They don't allow inbound connections from the internet.
Use VPC endpoints for private access to AWS services. Use NAT gateways when private instances need to reach the internet outbound. If you're routing S3 traffic through NAT, you're paying unnecessary egress costs and adding latency.
Static access keys in code or environment variables can be exposed and reused. Instance profiles provide EC2 workloads with temporary credentials for an IAM role, and other platforms offer similar workload identity mechanisms: Azure managed identities, AWS IAM roles, and Google Cloud Workload Identity Federation.
Database servers sit in private subnets with no internet access at all, reachable only from application tier security groups. KMS encrypts data at rest. IAM roles handle authentication for any AWS service access.
For Kubernetes workloads, network policies restrict pod-to-pod communication, and service mesh adds mTLS between services. VPC endpoints keep traffic to S3 and DynamoDB internal.
Configure the database security group to accept inbound PostgreSQL or MySQL traffic only from the application tier security group ID. This means the rule looks like: port 5432, source security group sg-xxxxxxxx. When application servers scale, they automatically get database access. When database servers scale, they inherit the same restrictions.
Outbound rules should be minimal—typically only to the application tier or specific external services the database needs to reach.
Cloud-managed keys are free and automatic—AWS handles rotation and policies. You cannot inspect or modify their policies. They're fine for development and non-sensitive workloads.
Choose customer-managed keys for regulated workloads, production data requiring compliance controls, and scenarios where you need cross-account access to keys. Choose cloud-managed keys for development, test, and non-sensitive data where you want to minimize operational overhead.
Second, use an S3 VPC endpoint with an endpoint policy to add a network-level restriction on requests that use that endpoint. Without an endpoint, private-subnet traffic follows its configured route, often through a NAT gateway. Endpoint policies can deny actions such as PutObject for requests that pass through the endpoint.
Third, enable S3 Block Public Access at the account level. Fourth, use CloudTrail with S3 data events to detect unusual GetObject patterns—large volumes of downloads from an unusual location or at unusual times.
Use SCPs to set organization-wide permission guardrails, such as denying actions in disallowed regions or preventing changes to security controls. They can also use condition keys to deny sensitive actions when a request lacks MFA. SCPs do not grant permissions, and they do not apply to the AWS Organizations management account or service-linked roles.
Attach SCPs to the organization root, an OU, or an account to set the maximum permissions available to affected principals. Test policy changes carefully so they do not block required administrative or recovery actions.
For non-Kubernetes services, use TLS for all network communication. Either terminate TLS at the load balancer and use internal encryption between services, or implement TLS end-to-end. Certificate management can be automated with services like AWS Certificate Manager or Let's Encrypt with cert-manager for Kubernetes.
The key requirement is enforcing TLS everywhere—not just on public endpoints. Internal services should also use TLS, especially when crossing network boundaries like availability zones.
Detection methods: AWS Config rules can detect overly permissive security groups and alert or auto-remediate. GuardDuty can flag unusual inbound traffic patterns. VPC Flow Logs capture all traffic including the permissive rule's effect. Security Hub aggregates these findings.
Prevention: Use AWS Config rules with remediation to automatically close security groups that open ports to 0.0.0.0/0. Set up AWS Security Hub to alert on configuration changes. Never allow 0.0.0.0/0 for database or cache ports—these should only accept traffic from specific security groups or CIDRs you control.
For existing buckets, run a scan and remediate any unencrypted ones. Use S3 Inventory to track encryption status across all buckets. For KMS encryption, ensure the policy restricts key usage to specific roles and services that need access.
Automate with a bucket creation workflow that enforces default encryption via bucket policy. Lambda can intercept bucket creation and apply encryption settings automatically.
The split varies by service type. For IaaS (EC2, VPC), you manage the OS and applications. For PaaS (RDS, Lambda), the provider manages the platform. For SaaS, most controls are provider-managed.
This means you cannot rely on the cloud provider to secure your data or configurations. Even with a "secure" cloud platform, misconfigured IAM, open security groups, or unencrypted data is your fault.
Response steps: immediately revoke the role's credentials using the role's inline session policies or AWS STS temporary credentials. Isolate the affected resources. Identify what data was accessed using CloudTrail logs. Identify the initial compromise vector (was it a GitHub secret, an exposed credential, a phishing attack?).
Prevent exfiltration by using VPC endpoints with endpoint policies to restrict S3 access to specific buckets. Enable S3 Block Public Access. Use service control policies to prevent overly permissive access to S3 from any account.
Enable Security Hub in each account and region. Use Security Hub standards (CIS AWS Foundations, PCI DSS) to check compliance against benchmarks. Route findings to a SIEM or ticketing system for response. Use automated remediation playbooks for common findings.
Without Security Hub, you would need to check each service individually and correlate findings manually. Security Hub automates this correlation and provides a single view of your security posture.
For external users, create an IAM role with trust policy allowing your identity provider to assume it. Scope permissions to exactly what external users need. Set session duration to limit exposure. Enable MFA at the identity provider level, not just in AWS.
For programmatic access, use STS to issue short-lived credentials rather than access keys. Set external ID if a third party needs cross-account access. Regularly audit which federated identities are active and remove unused ones.
Use SCPs to set permission guardrails across member accounts, such as denying actions in specific regions or denying sensitive actions unless the request includes MFA. SCPs do not grant permissions, and they do not apply to the management account or service-linked roles.
SCPs attached to the organization root, an OU, or an account define the maximum permissions available to affected principals. An explicit deny overrides an allow, and an action also needs an identity-based or resource-based policy that grants it.
Within Kubernetes, use RBAC to grant permissions to service accounts, not to users. Network policies restrict pod-to-pod communication — a compromised pod cannot reach other pods unless explicitly allowed. Limit what pods can do via Pod Security Standards.
Avoid giving pods cluster-admin or using default service accounts. Each workload should have its own service account with minimal RBAC permissions. Enable EKS Secrets encryption for sensitive data in etcd.
Security monitoring use cases: detect port scans (many connection attempts to different ports from same IP), identify lateral movement (unusual traffic between subnets), find data exfiltration (large outbound transfers to unfamiliar IPs), catch open security groups (traffic being rejected that should be allowed).
Route Flow Logs to CloudWatch Logs or S3, then analyze with Athena or a SIEM. Set up CloudWatch alarms on unusual traffic patterns. Store logs with Object Lock to prevent tampering.
For manual rotation (if you need rotation more frequently or on a specific schedule): create a new KMS key, update applications to use the new key for encryption, ensure existing data can still be decrypted with old key, then disable the old key. Do not delete old keys until all data encrypted with them is either re-encrypted or no longer needed.
Use envelope encryption: a data key encrypts data, the data key is encrypted by KMS key. Rotating the KMS key only requires re-encrypting data keys, not the data itself.
Containment: immediately isolate affected resources by revoking IAM credentials, security group changes, or Network ACL blocks. Preserve evidence — do not delete logs or stop instances that might contain artifacts.
Investigation: use CloudTrail to identify what actions were taken, from which IP, using which credentials. Check whether data was exfiltrated via S3 or other services. Identify the initial access vector — was it an exposed access key, a compromised service account, or a misconfigured resource?
Recovery: rotate all credentials that might be compromised. Remove any backdoors added by attacker (new IAM users, security group rules, cron jobs). Restore from known-good backups if data was modified.
Post-incident: document timeline, root cause, and remediation. Update detection rules to catch similar attacks faster. Notify affected customers if data was exposed.
Further Reading
- Network Security: Firewalls, Segmentation, and Zero Trust — practical network boundary and traffic-control concepts
- Secrets Management — storing, rotating, and granting access to application credentials
- Incident Response — investigation and recovery practices for security events
- AWS IAM Documentation — Identity and Access Management best practices and policy types
- Amazon VPC Documentation — Virtual private cloud networking, endpoints, and security
- AWS KMS Documentation — Key management, encryption, and key policies
- AWS Security Hub — Centralized security findings and compliance monitoring
- Azure Security Documentation — Microsoft security best practices across Azure services
- Google Cloud Security — GCP security documentation and best practices
Conclusion
Cloud Security Checklist
# 1. Create and start a multi-region CloudTrail trail
aws cloudtrail create-trail --name my-trail --is-multi-region-trail --s3-bucket-name my-cloudtrail-bucket
aws cloudtrail start-logging --name my-trail
# 2. Enable GuardDuty
aws guardduty enable-detector --detector-id $(aws guardduty list-detectors --query 'DetectorIds[0]' --output text)
# 3. Enforce encryption on S3 buckets
aws s3api put-bucket-encryption \
--bucket my-bucket \
--server-side-encryption-configuration '{"Rules": [{"ApplyServerSideEncryptionByDefault": {"SSEAlgorithm": "AES256"}}]}'
# 4. Create IAM group with minimal permissions
aws iam create-group --group-name readonly
aws iam attach-group-policy --group-name readonly --policy-arn arn:aws:iam::aws:policy/ReadOnlyAccess
# 5. Block public access to S3 buckets
aws s3api put-public-access-block \
--bucket my-bucket \
--public-access-block-configuration 'BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true'
For more on managing cloud infrastructure, see our post on Cost Optimization.
Category
Related Posts
Kubernetes Network Policies: Practical Pod Security
Implement microsegmentation in Kubernetes using Network Policies to control traffic flow between pods and enforce zero-trust networking.
Event Security and Sensitive Data in EDA
Secure event-driven systems with least-privilege identities, encrypted transport and payloads, careful data minimization, and a deliberate retention plan.
Forward and Reverse Proxies: Routing, Trust, and Use Cases
Learn how forward and reverse proxies handle HTTP traffic, CONNECT tunnels, TLS termination, caching, routing, trusted headers, and production failures.