AWS Security Services: How Do IAM, Secrets Manager, KMS, ACM, WAF, Shield, and Cognito Divide the Work?
From "who can do what" to "how you defend against incoming traffic," understand what line of defense each AWS security service—IAM, Cognito, Secrets Manager, KMS, ACM, WAF, and Shield—actually holds.
IAM: who can do what to your AWS resources
IAM (Identity and Access Management) is the foundation nearly every other AWS service sits on. It answers the most basic question of all: can this identity do this thing?
IAM has a few core concepts. A User is a long-lived identity, usually mapped to an actual person. A Role is a set of permissions that can be temporarily assumed—it isn't tied to any one person, and when an AWS resource like EC2 or Lambda needs to call another service, the standard approach is attaching a role rather than hardcoding a set of credentials into your code. A Policy is a permission rule written in JSON that defines who can do what to which resource.
// Allow this role to read objects in the specified S3 bucket
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-app-assets/*"
}
]
}IAM runs on one crucial principle: deny by default, allow explicitly. A newly created IAM user or role can't do anything until you attach a policy that grants it permission—the opposite of the "open by default, lock down later" logic a lot of systems follow. The most common mistake in practice is granting * (every action, every resource) just for convenience, which pretty much violates the principle of least privilege and is one of the top findings in any security audit.
But keep in mind: IAM manages identities that operate on AWS resources—your own team's developers, or the permissions AWS resources use to call each other. If what you actually need to manage is external users of your own application—say, letting a million shoppers sign up and log in to an e-commerce site—IAM was never built for that scale or scenario.
Cognito: identity for your app's end users
Cognito fills exactly that gap. It's an authentication and user-management service for your application, so you don't have to build sign-up, login, password reset, and MFA from scratch.
Cognito has two main pieces. User Pools are the user directory—handling sign-up, login, password policies, and email/phone verification, with support for third-party login through Google, Facebook, and the like. Identity Pools take an already-authenticated user and exchange them for a set of temporary AWS credentials, letting your frontend call services like S3 or DynamoDB directly and securely, without ever putting a long-lived access key into client-side code.
// Use the Amazon Cognito Identity SDK to let users sign in with email and password
import { CognitoUser, AuthenticationDetails } from 'amazon-cognito-identity-js'
const authDetails = new AuthenticationDetails({
Username: 'user@example.com',
Password: 'user-password',
})The simplest way to tell them apart: IAM governs permissions between your own people and AWS resources; Cognito governs how your product's users log in to your product. The two show up together often—once a user logs in through Cognito, the temporary credentials they receive are still bound by the permission boundaries IAM defines.
Secrets Manager: secrets don't belong hardcoded in your code
Once identity is sorted out, the next question is: your app needs to connect to a database and call third-party APIs, which means passwords and API keys. Where should those actually live?
Hardcode them, and they end up in version control, sitting exposed in your commit history forever. Environment variables are a step up, but rotating a password still means manually editing config and redeploying. Secrets Manager exists to solve exactly this: it stores these secret strings centrally, and your application fetches them via an API call at runtime instead of reading them from a config file.
Its standout feature is automatic rotation: you can configure it to periodically generate a new password and sync it to the corresponding RDS database, no human intervention required—so you never end up with a credential that's been unchanged for years just because everyone forgot about it. Access control, as usual, is handled by IAM, which governs who can read which secret.
KMS: the central manager of your encryption keys
Secrets Manager protects a single secret string, but the broader question is: how do you encrypt all the data sitting in S3, RDS, and EBS? And where do the keys themselves live?
KMS (Key Management Service) is AWS's centralized encryption key manager. It lets you create, control, and rotate encryption keys, while the key material itself never leaves KMS's internal hardware security modules—it's never exported. Your application or another AWS service can only request that this key encrypt or decrypt data; it never gets the key itself.
In practice, you almost never call KMS directly to encrypt or decrypt individual records. Instead, you specify which KMS key to use when you turn on encryption for S3, EBS, or RDS, and the service handles the actual encryption and decryption under the hood. Think of KMS as the keyring for the entire AWS ecosystem—S3 server-side encryption (SSE-KMS), EBS volume encryption, and RDS storage encryption are all backed by the same key-management machinery.
ACM: certificate issuance and renewal, no longer manual
Beyond encrypting data at rest, another common security need is encrypting data in transit—HTTPS. The old-school way is buying a TLS certificate from a certificate authority (CA), installing it on your server by hand, and remembering to renew it before it expires. Forget, and your site starts throwing browser warnings.
ACM (AWS Certificate Manager) lets you request TLS certificates for free and attach them directly to services like CloudFront or an Application Load Balancer. More importantly, it renews them automatically—as long as the certificate stays attached to a supported AWS service, expiration is no longer something you have to think about.
The catch: certificates issued through ACM keep their private key inside AWS—you can't export it to install on your own server or another cloud. If you need an exportable certificate, you'll need ACM Private CA or some other issuance path instead. But for the vast majority of setups where your services live on AWS and the certificate only needs to sit on an AWS resource, ACM is close to the default answer—it's outsourcing certificate management to AWS, full stop.
WAF: the filter standing in front of your application
Everything so far has been about protecting legitimate traffic. But the internet is also full of malicious traffic—SQL injection, XSS, or bots simply trying to scrape your site clean.
WAF (Web Application Firewall) sits in front of CloudFront or an Application Load Balancer and inspects every incoming HTTP request against the rules you define, deciding whether to allow it, block it, or just log it for now. Those rules can come from AWS's Managed Rule Groups, which give you off-the-shelf protection against common attack patterns, or from custom rules you write yourself—like a rate-based rule capping how many requests a single IP can make per minute, to stop brute-force attempts or basic bots.
Think of WAF as a security guard standing at your application's door, checking every visitor's bags one by one. It understands the content of HTTP requests (Layer 7) and can tell "this one looks like an attack." But it's built for application-layer malicious requests, not for absorbing the sheer volume of traffic meant to saturate your bandwidth—that's the next service's job.
Shield: standing up to large-scale DDoS attacks
Shield defends specifically against DDoS (Distributed Denial of Service) attacks—a flood of requests from many sources hitting you at once, trying to knock your service offline.
Shield comes in two tiers:
- Shield Standard is baseline protection enabled by default and for free on every AWS account, covering the most common network- and transport-layer (Layer 3/4) attacks like SYN floods. It kicks in automatically—no extra setup needed.
- Shield Advanced is the paid upgrade, adding more sophisticated detection, real-time notifications, access to the dedicated DDoS Response Team (DRT), and cost protection if an attack drives up your traffic bill.
WAF and Shield frequently work in tandem: Shield blocks the massive, brute-force traffic at the network layer so your service doesn't get overwhelmed outright, and WAF keeps filtering at the application layer for requests that look normal on the surface but carry malicious intent underneath.
Putting it together: which layer each service defends
Line these seven services up, and you'll notice they each guard a different checkpoint along the same path that data and traffic travel:
| Service | What It Guards | Best Fit |
|---|---|---|
| IAM | Who can operate on AWS resources | Developer permissions, role- and access-control between services |
| Cognito | How end users log in to your product | App sign-up, login, third-party login integration |
| Secrets Manager | Where secret strings live | Database passwords, API keys, secrets that need automatic rotation |
| KMS | How data at rest gets encrypted | Encryption key management behind S3, EBS, RDS, and similar services |
| ACM | How data in transit gets encrypted | TLS certificates attached to CloudFront/ALB, auto-renewed |
| WAF | Whether to block malicious requests at the application layer | SQL injection, XSS, IP-based rate limiting, and other HTTP-layer defenses |
| Shield | Large-scale DDoS traffic attacks | Massive-volume defense at the network and transport layers |
Wrapping up
IAM decides who can touch your AWS resources, Cognito takes over login for your application's end users, Secrets Manager keeps secret strings out of your code, KMS centrally manages the encryption keys behind data at rest, ACM automates TLS certificate issuance and renewal, WAF filters malicious requests at the application layer, and Shield stands up to large-scale DDoS attacks at the network layer.