AWS Certified Developer - Associate (DVA-C02) #7 Domain 2-1 Security — Authentication and Authorization
In #6 SDK Development Patterns, I said “production credentials are an IAM Role.” The security domain tackles that topic head-on. Security in DVA isn’t huge network design like in SAA — it’s a more code-adjacent question: how does the application obtain credentials, how does it authenticate users, and how does it issue temporary permissions?
First, let’s distinguish authentication from authorization. Authentication is “who are you?”; authorization is “what can you do?” Cognito mainly handles authentication, and IAM handles authorization.
IAM Roles from a developer’s perspective #
As seen in #6, when code accesses AWS services, don’t store long-term access keys — use an IAM Role. The way the Role is supplied differs by execution environment.
| Execution environment | How the Role is supplied |
|---|---|
| EC2 | Instance Profile |
| ECS | Task Role |
| Lambda | Execution Role |
| EKS pod | IRSA (IAM Role for Service Accounts) |
All of these Roles automatically supply temporary credentials issued by STS to the code. The SDK credential provider chain picks them up at the final step. The answer to “how does Lambda write to DynamoDB?” is “give the execution role dynamodb:PutItem permission.”
STS — temporary credentials #
Security Token Service (STS) issues temporary credentials with an expiration (access key ID, secret key, session token). Even if they leak, the damage is limited.
AssumeRole— assume another Role to temporarily gain its permissions. The standard for cross-account access.AssumeRoleWithWebIdentity— gives temporary credentials to users authenticated with an OIDC/web identity such as Google, Facebook, or Cognito.GetSessionToken— issuing MFA-applied temporary credentials, and so on.
Core principle: don’t distribute long-term IAM keys to apps or mobile devices. Instead, issue temporary credentials via federation.
Cognito — two pools #
Cognito is the most frequently appearing service in DVA security, and if you confuse the User Pool with the Identity Pool, you’ll almost certainly get it wrong.
| Aspect | User Pool | Identity Pool (Federated Identities) |
|---|---|---|
| Role | Authentication (login/sign-up) | Authorization (issuing temporary AWS credentials) |
| Output | JWT tokens (ID/Access/Refresh) | STS temporary AWS credentials |
| Question | “Who is this user?” | “How does this user access AWS resources?” |
| Typical use | App user directory, API Gateway authorizer | A logged-in user accesses S3/DynamoDB directly |
User Pool #
A user directory and authentication provider. It offers sign-up, login, MFA, password policies, social login integration (Google, etc.), and a hosted UI, and issues a JWT on successful login. This JWT is validated by the Cognito authorizer in API Gateway to allow API access.
Identity Pool #
Issues STS temporary AWS credentials to authenticated (or guest) users. With these credentials, users can access an S3 bucket or DynamoDB table directly. It accepts a User Pool, a social IdP, SAML, and so on as authentication sources.
The decisive distinction: “login/token” means User Pool; “direct user access to AWS resources (temporary credentials)” means Identity Pool. Using the two together is also a common pattern: log in with a User Pool → pass that token to an Identity Pool to obtain AWS credentials.
Common authentication scenarios #
- Web/mobile app login → User Pool (authentication) + API Gateway Cognito authorizer.
- A logged-in user uploads only to their own folder in S3 → Identity Pool for temporary credentials + IAM policy variables (
${cognito-identity.amazonaws.com:sub}) for per-user isolation. - Login with third-party OAuth → User Pool social integration or a Lambda authorizer.
- Service-to-service (server to AWS) → IAM Role, no Cognito needed.
Exam question patterns #
- “A mobile app user needs temporary AWS credentials to upload directly to S3 after logging in.” → Identity Pool.
- “The app needs login, sign-up, and JWTs.” → User Pool.
- “Allow only logged-in users in API Gateway.” → User Pool + Cognito authorizer.
- “Lambda needs to access DynamoDB.” → Grant permission to the execution role (not storing keys).
- “Control another account’s resources from code.” → STS AssumeRole.
- “Each user accesses only their own S3 prefix.” → Identity Pool + IAM policy variables.
Common traps #
1) Confusing User Pool and Identity Pool #
A User Pool is authentication (tokens); an Identity Pool is authorization (temporary AWS credentials). If it’s “direct access to AWS resources,” it’s an Identity Pool.
2) Distributing IAM user keys to the app #
An answer that puts long-term keys into mobile/web is always wrong. Issue temporary credentials via federation.
3) Putting access keys into Lambda as environment variables #
Lambda’s execution role supplies credentials automatically. There’s no reason to put keys in.
Wrap-up #
What this post locked in:
- Authentication (“who are you?”) vs authorization (“what can you do?”). Cognito is authentication, IAM is authorization
- Code’s AWS access uses an IAM Role (EC2 profile, ECS task, Lambda execution role) — all STS temporary credentials
- STS — AssumeRole (cross-account), AssumeRoleWithWebIdentity (federation)
- The distinction between Cognito User Pool (login/JWT) and Identity Pool (temporary AWS credentials) is the core
- Don’t distribute long-term keys to apps or mobile
Next — Domain 2-2 Encryption and Secrets #
Now that we’ve covered identity and permissions, next is protecting the data and secret values themselves. In #8 Encryption and Secrets, I’ll cover KMS and envelope encryption, S3 and Lambda environment variable encryption, and the difference between Secrets Manager and Parameter Store (including automatic rotation).