· NERVICO · cloud-architecture  Â· 12 min read

AWS Security: IAM, VPC, and Security Groups for Startups

Practical AWS security guide for startups: IAM least-privilege configuration, secure VPC design, Security Groups, and the most common security mistakes we find in audits.

Practical AWS security guide for startups: IAM least-privilege configuration, secure VPC design, Security Groups, and the most common security mistakes we find in audits.

AWS security is not a product you buy. It is a set of configurations your team must implement correctly from day one. AWS operates under a shared responsibility model: AWS secures the physical infrastructure and base services. Your company secures everything built on top: IAM configurations, virtual networks, data, user access, and code.

The problem is that most startups prioritize speed over security. And it is understandable: when you have 6 months of runway, security does not feel urgent. Until it is. A public S3 bucket with customer data, a compromised access key, or a database reachable from the internet can destroy your users’ trust and, with it, your company.

This article covers the three fundamental pillars of AWS security (IAM, VPC, and Security Groups) with enough depth to implement them correctly, without the unnecessary complexity that causes many teams to misconfigure or ignore them.

IAM: The Cornerstone of AWS Security

What IAM Is and Why It Is the Most Important Service

IAM (Identity and Access Management) controls who can do what in your AWS account. Every action in AWS, from launching an EC2 instance to reading an S3 object, passes through IAM. If IAM is misconfigured, nothing else matters. It is like having a high-security deadbolt on the front door while leaving the windows open.

IAM has four main components:

  • Users: Permanent identities for people who access AWS. Every team member should have their own IAM user.
  • Groups: Collections of users that share the same permissions. “Developers,” “DevOps,” “Billing” are typical examples.
  • Roles: Temporary identities that services or people assume to perform specific actions. A role does not have permanent credentials.
  • Policies: JSON documents that define permissions. They specify which actions are allowed or denied on which resources.

The Principle of Least Privilege

The fundamental IAM principle is: every identity should have only the permissions it needs to do its job. Nothing more.

In practice, this means:

Do not use the root user: The root account has unlimited access to everything. Create an IAM user with administrator permissions for daily work and store root credentials in a secure location. Enable MFA on the root account. Better yet, use AWS Organizations and do not create resources in the root account.

Do not use AdministratorAccess for developers: It is tempting to give everyone admin access “so nobody is blocked.” But a developer with AdministratorAccess can, through error or credential compromise, delete production databases, modify network configurations, or create resources in regions you do not monitor.

Create specific policies: Instead of "Action": "*", define exactly which actions each role needs:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["s3:GetObject", "s3:PutObject", "s3:ListBucket"],
      "Resource": ["arn:aws:s3:::my-production-bucket", "arn:aws:s3:::my-production-bucket/*"]
    }
  ]
}

This policy allows reading and writing objects in a specific bucket. Nothing else. It does not allow deleting the bucket, accessing other buckets, or modifying bucket configuration.

IAM Roles for Services

AWS services (Lambda, EC2, ECS) need permissions to interact with other services. Never use static access keys for this. Use IAM Roles.

Example: Lambda reading from DynamoDB:

  1. Create an IAM Role with a policy that allows dynamodb:GetItem and dynamodb:Query on the specific table.
  2. Assign the role to the Lambda function.
  3. Lambda assumes the role automatically and receives temporary credentials.

Temporary role credentials rotate automatically. Static access keys do not. If an access key leaks (in a Git commit, in a log, in an exposed environment variable), the attacker has access until you revoke it. With roles, credentials expire in minutes or hours.

IAM Access Analyzer

IAM Access Analyzer is a free service that identifies resources shared with entities outside your account. It detects:

  • S3 buckets with policies that allow public access.
  • IAM roles that can be assumed by external accounts.
  • KMS keys accessible from outside the account.
  • SQS queues and SNS topics with open permissions.

Enable it from day one. It is free and alerts you to configurations you probably did not intend to make public.

MFA: Not Optional

Multi-Factor Authentication should be active on all IAM user accounts with console access. Without MFA, a compromised password is sufficient to access the entire account.

Recommended configuration:

  • Mandatory MFA for the root user (hardware key if possible).
  • Mandatory MFA for all users with console access.
  • IAM policy that denies all actions if MFA is not active (except the action of configuring MFA).

VPC: The Private Cloud Network

What a VPC Is

A VPC (Virtual Private Cloud) is an isolated virtual network within AWS. It is your own network space where you launch resources. By default, nothing inside a VPC is accessible from the internet unless you explicitly configure it.

Subnet Design

A well-designed VPC has at least three types of subnets:

Public subnets: Resources with direct internet access through an Internet Gateway. Only these should be here:

  • Load balancers (ALB, NLB).
  • Bastion hosts (if you use them, though Session Manager is preferable).
  • NAT Gateways.

Private subnets: Resources without direct internet access. They can reach the internet through a NAT Gateway. These go here:

  • Application EC2 instances.
  • Containers (ECS, EKS).
  • Lambda functions that need VPC access.

Isolated subnets (data tier): Subnets with no internet access, not even through NAT Gateway. For:

  • Databases (RDS, ElastiCache, OpenSearch).
  • Any resource that stores sensitive data.
VPC: 10.0.0.0/16

Availability Zone A:
  - Public subnet:   10.0.1.0/24   (ALB, NAT GW)
  - Private subnet:  10.0.10.0/24  (App servers)
  - Isolated subnet: 10.0.100.0/24 (Databases)

Availability Zone B:
  - Public subnet:   10.0.2.0/24   (ALB, NAT GW)
  - Private subnet:  10.0.20.0/24  (App servers)
  - Isolated subnet: 10.0.200.0/24 (Databases)

Fundamental rule: Use at least 2 availability zones for high availability. ALBs require subnets in at least 2 AZs.

NAT Gateway vs NAT Instance

Resources in private subnets need internet access (to download patches, call external APIs, etc.) but must not be accessible from the internet. The NAT Gateway solves this.

NAT Gateway (recommended):

  • Managed service by AWS.
  • High availability within one AZ.
  • Bandwidth up to 100 Gbps.
  • Cost: $0.045/hour + $0.045/GB processed.
  • For high availability: one NAT Gateway per AZ.

NAT Instance (budget alternative):

  • An EC2 instance acting as NAT.
  • Your team manages it (patches, scaling, availability).
  • Cheaper for low traffic.
  • Not recommended for production unless budget is extremely tight.

VPC Endpoints: Private Traffic with AWS Services

By default, when your EC2 instance in a private subnet calls S3, traffic goes through the NAT Gateway to the internet and back to AWS. You are paying for NAT Gateway and exposing traffic unnecessarily.

VPC Endpoints allow your resources to access AWS services without leaving the private network:

Gateway Endpoints (free): For S3 and DynamoDB. Added as an entry in the route table. All S3/DynamoDB traffic is routed through the AWS private network.

Interface Endpoints (with cost): For other AWS services (SQS, SNS, Secrets Manager, CloudWatch, etc.). They create an ENI in your subnet with a private IP. Cost: $0.01/hour per AZ + $0.01/GB processed.

Recommendation: At minimum, create Gateway Endpoints for S3 and DynamoDB. They are free and reduce NAT Gateway traffic. For services handling sensitive data (Secrets Manager, KMS), Interface Endpoints add a security layer by keeping traffic within the private network.

Security Groups: The Per-Instance Firewall

How They Work

Security Groups are stateful firewalls that control inbound and outbound traffic at the instance or ENI level. “Stateful” means that if you allow inbound traffic on a port, the response traffic is automatically allowed without needing an explicit outbound rule.

Fundamental Rules

By default, all inbound traffic is blocked: A Security Group with no inbound rules allows no connections.

By default, all outbound traffic is allowed: A new Security Group allows all outbound traffic. In most cases, this is acceptable. For environments with strict compliance requirements, restrict outbound traffic as well.

Security Groups reference other Security Groups: This is the most powerful feature. Instead of opening a port to an IP or CIDR range, you can open a port “to the ALB Security Group.” This means only instances belonging to the ALB Security Group can communicate with your service.

Layered Security Group Design

ALB Security Group:

Inbound:
  - Port 443 (HTTPS) from 0.0.0.0/0 (internet)
  - Port 80 (HTTP) from 0.0.0.0/0 (for HTTPS redirect)
Outbound:
  - All traffic (default)

Application Security Group:

Inbound:
  - Port 8080 from sg-alb (only the ALB can talk to the app)
Outbound:
  - All traffic (default)

Database Security Group:

Inbound:
  - Port 5432 (PostgreSQL) from sg-app (only the app can talk to the DB)
Outbound:
  - No rules (the DB does not need to initiate connections)

This configuration creates a chain of trust: the internet only talks to the ALB, the ALB only talks to the application, and the application only talks to the database. An attacker who compromises the ALB cannot access the database directly.

Network ACLs vs Security Groups

Network ACLs (NACLs) operate at the subnet level, not the instance level. They are stateless (you need explicit inbound and outbound rules) and are evaluated in numerical order.

FeatureSecurity GroupsNetwork ACLs
LevelInstance/ENISubnet
TypeStatefulStateless
RulesAllow onlyAllow and Deny
EvaluationAll rulesNumerical order

Recommendation: Use Security Groups as the first line of defense. Use NACLs as a second layer to block known malicious IP ranges or to meet compliance requirements that demand defense in depth.

Common Security Mistakes in Startups

1. Access Keys in Code Repositories

This is the most frequent and most dangerous mistake. An AWS access key published on GitHub is detected by automated bots within minutes. Those bots launch instances for cryptocurrency mining that can generate bills of thousands of dollars within hours.

Solution: Never use access keys in code. Use IAM Roles for services, encrypted environment variables for local applications, and AWS Secrets Manager for centralized secret management. Enable AWS notifications about exposed access keys.

2. Public S3 Buckets

S3 blocks public access by default since April 2023. But if you disable that protection “because something is not working,” you are exposing data. Use S3 Block Public Access at the account level and never disable it.

3. Publicly Accessible Databases

RDS offers the “Publicly Accessible” option during creation. If you enable it, your database gets a public IP. Even if Security Groups limit access, the exposure is unnecessary and increases the attack surface.

Solution: Databases always in private subnets. Access via bastion host, Session Manager, or VPN.

4. A Single AWS Account for Everything

Development, staging, and production in the same account. A mistake in development can affect production. A junior developer with access to development potentially has access to production data.

Solution: AWS Organizations with separate accounts per environment. SCPs to limit what each account can do. AWS Control Tower to automate the setup.

5. Disabled Logs

CloudTrail disabled or configured in only one region. Without CloudTrail, there is no record of who did what. Investigating a security incident without logs is like investigating a crime without evidence.

Solution: CloudTrail enabled in all regions, with logs sent to an S3 bucket in a separate logging account with deletion protection.

Detection and Response Tools

AWS GuardDuty

GuardDuty is a threat detection service that analyzes CloudTrail logs, VPC Flow Logs, and DNS Logs to identify suspicious activity. It detects:

  • EC2 instances communicating with known malicious IPs.
  • Unusual IAM credential access from new geographic locations.
  • Data exfiltration attempts from S3 buckets.
  • Cryptocurrency mining on your instances.
  • Reconnaissance patterns (port scanning, API enumeration).

Cost: Based on the volume of data analyzed. For an account with moderate activity, expect $5 to $30 per month. Enabling it is one of the highest cost-to-benefit security actions available.

AWS Security Hub

Security Hub aggregates findings from GuardDuty, IAM Access Analyzer, Inspector, Firewall Manager, and Config into a single dashboard. It also evaluates your account against compliance standards:

  • AWS Foundational Security Best Practices: 200+ security checks.
  • CIS AWS Foundations Benchmark: Industry standard for secure AWS configuration.
  • PCI DSS: For companies processing credit card data.

Security Hub is not free (charged per finding and per check), but for companies with compliance requirements, it centralizes security management significantly.

AWS Config

Config monitors and records the configuration of all your AWS resources. It lets you create rules that evaluate whether resources comply with your policies:

  • “All S3 buckets must have encryption enabled.”
  • “No Security Group should allow inbound traffic from 0.0.0.0/0 on port 22.”
  • “All RDS instances must have Multi-AZ enabled.”

When a resource is non-compliant, Config generates a finding and can execute an automatic remediation action (through Systems Manager Automation).

Encryption: In Transit and At Rest

Encryption in Transit

All traffic between services should use TLS. On AWS:

  • ALBs terminate TLS with ACM (AWS Certificate Manager) certificates, which are free and auto-renew.
  • Traffic between ALB and application instances should also use TLS (end-to-end encryption), although many teams omit this for simplicity.
  • Connections to RDS, ElastiCache, and OpenSearch support TLS. Always enable it.

Encryption at Rest

AWS KMS (Key Management Service) manages encryption keys:

  • AWS-managed keys (aws/s3, aws/ebs): Free, AWS manages rotation.
  • Customer-managed keys (CMK): $1 per month per key + $0.03 per 10,000 operations. Needed if you want control over the key policy (who can use it, when it rotates, etc.).

Services that must have encryption at rest enabled:

  • S3: SSE-S3 (default since January 2023) or SSE-KMS.
  • EBS: Default encryption enabled at the account level.
  • RDS: Encryption enabled at instance creation (cannot be enabled afterward).
  • DynamoDB: Encryption enabled by default.

Security Plan for Startups: The First 30 Days

Week 1: Identity and Access

  • Enable MFA on the root account.
  • Create individual IAM users for each team member.
  • Create IAM groups with least-privilege policies.
  • Disable root user access keys.
  • Enable IAM Access Analyzer.

Week 2: Network and Isolation

  • Design the VPC with public, private, and isolated subnets.
  • Create Security Groups per layer (ALB, app, data).
  • Create Gateway Endpoints for S3 and DynamoDB.
  • Verify that no database has public access.

Week 3: Detection and Monitoring

  • Enable CloudTrail in all regions.
  • Enable GuardDuty for threat detection.
  • Configure AWS Config with basic compliance rules.
  • Create CloudWatch alerts for suspicious activity.

Week 4: Secret Management and Encryption

  • Migrate all secrets to AWS Secrets Manager.
  • Enable KMS encryption for S3, EBS, and RDS.
  • Configure automatic secret rotation.
  • Verify all traffic uses TLS.

Conclusion

AWS security is not a project with an end date. It is a continuous practice that evolves with your infrastructure. But the fundamentals are straightforward: IAM with least privilege, a well-designed VPC, and proper Security Groups cover 80% of the risks a startup faces.

The cost of implementing these practices from the beginning is minimal. The cost of not doing so can be existential.

If you are unsure about the security posture of your AWS infrastructure, NERVICO conducts security audits covering IAM, networking, encryption, and compliance. Request a free audit and we will show you exactly where the risks are.

Back to Blog

Related Posts

View All Posts »