Authentication and Authorization
The model: authentication establishes identity, authorization runs one allow + no-deny evaluation
"Why was this call allowed or denied?" is the security question DVA-C02 asks most, and two rules answer nearly all of it: a request needs an Allow with no explicit Deny anywhere (a single Deny beats every Allow), and proving who the caller is (authentication) is always a separate step from deciding what they may do (authorization). Read an Effect/Action/Resource statement against those two rules and you can trace any deny scenario and pick the right credential for each job. Two distinct questions are always answered in order. Authentication (authN) answers who is the caller? It verifies an identity, whether that is a SigV4-signed AWS request (SigV4 is AWS's request-signing scheme, in which the SDK signs each call with the caller's credentials), a JSON Web Token (JWT) validated by Amazon Cognito, or a federated login. Authorization (authZ) answers what may that caller do? It is a separate policy decision, so a perfectly authenticated caller can still be denied. Conflating the two is the single most common exam distractor: a Cognito ID token[1] proves who you are and must never be used to authorize an API call, while an OAuth 2.0 access token[2] or a set of temporary AWS credentials is what grants access.
Authorization on AWS is one uniform model regardless of where the permission is written: allow + no explicit deny. A request is permitted only when some policy Allows the requested action on the requested resource AND no policy contains an explicit Deny. Two policy families feed this evaluation:
- Identity-based policy, attached to the IAM principal (user, group, or role) making the call. Multiple attached policies are additive (unioned).
- Resource-based policy, attached to the target resource itself (an S3 bucket policy, a Lambda resource policy, an SQS queue policy, a KMS key policy).
The one rule that separates same-account from cross-account access, stated once here, referenced throughout the page:
- Same account: an
Allowin either the identity-based policy or the resource-based policy is sufficient. AWS takes the union of the two. (KMS is the notable exception: its key policy must allow the principal explicitly.) - Cross account: you need both, an
Allowin the caller's identity-based policy in its own account and anAllowin the resource-based policy in the resource's account.
Explicit Deny always wins. No matter how many Allows exist, a single explicit Deny in any applicable policy denies the request. This is why an "admin" principal can still be blocked from an S3 bucket whose bucket policy denies its ARN. The order is summarized in the figure: check for an explicit Deny first, then apply the same-/cross-account grant rule, then default-deny anything not allowed. The official IAM policy evaluation reference[3] is the canonical source for this logic.
The application's own identity: IAM roles, STS temporary credentials, and least privilege
This section covers how the application authenticates itself to AWS, distinct from the end-user authentication of the next section. The rule is absolute: application code carries a role, never a long-lived access key. Embedding an access key ID and secret in code or config is the antipattern the exam punishes; instead you attach an IAM role to the compute and let the AWS SDK obtain rotating temporary credentials transparently. The figure groups the role-per-compute names under the single service that vends their credentials; the names are worth memorizing because the exam tests them as distractors:
- EC2 instance profile, wraps an IAM role; the SDK fetches credentials from the Instance Metadata Service. Always enforce IMDSv2[4] (
HttpTokens=required) to block SSRF-based credential theft. - ECS task role, the role the application inside the container uses for its AWS API calls. Do not confuse it with the task execution role, which the ECS agent uses to pull images from ECR and ship logs to CloudWatch. Putting application permissions on the execution role is a classic wrong-layer mistake.
- Lambda execution role, set at function creation; credentials are exposed via environment variables and the SDK auto-discovers them.
Where temporary credentials come from: AWS STS. All of the above are vended by AWS Security Token Service (STS)[5] behind the scenes. When code must switch identity (cross-account access or privilege elevation) it calls sts:AssumeRole[6] explicitly. Commit these numbers; they are directly testable:
- Default session length: 3600 seconds (1 hour) when
DurationSecondsis omitted. DurationSecondsrange: 900 seconds (15 minutes) up to the role's configured maximum session duration, which can be set from 1 to 12 hours.- Role chaining (using one assumed role to assume another) caps the session at 1 hour regardless of the role's maximum, a frequently-tested gotcha.
Who is allowed to assume a role is governed by the role's trust policy, its resource-based policy. A subtle, predictably-misread detail: a trust policy Principal of arn:aws:iam::<account-id>:root denotes account-level trust. The whole account is a trusted entity (account-level delegation), NOT the AWS account root user. It means every IAM principal in that account whose own identity policy also permits sts:AssumeRole may assume the role. To trust a single principal, name it explicitly (e.g. arn:aws:iam::<account-id>:role/Build). For third-party SaaS that assume a role in your account, require sts:ExternalId in the trust policy to defend against the confused-deputy problem.
Least privilege bounds, it does not just grant. Each policy should grant only the actions and resources an identity needs, narrowed with Condition keys where possible, per the IAM best-practices guidance[7]. Note the asymmetry the exam probes: where a ceiling is present (a permissions boundary on the principal, or a session policy[8] passed to AssumeRole) effective permissions become the intersection of the grants and the ceiling, so a session can never exceed what the role's identity policy already allows. Grants union; ceilings intersect.
End-user authentication: Cognito user pools (authN) vs identity pools (federated AWS credentials)
When the application must sign in its own end users, the two Amazon Cognito halves answer the two different questions from the model section, and the exam relentlessly tests which one to reach for. Keep them apart by their job:
- A Cognito user pool[9] is a user directory that performs authentication. Users sign in and the pool issues three tokens. The two you must distinguish:
- ID token, carries identity claims (email, name,
sub). It proves who the user is; consume it in your app to learn about the user. It is not an authorization credential. - Access token, an OAuth 2.0[10] bearer token carrying scopes/groups. This is what you send to a protected API to be authorized. (A refresh token, valid much longer, is used only to mint new ID/access tokens.)
- ID token, carries identity claims (email, name,
- A Cognito identity pool[11] (a.k.a. federated identities) performs authorization to AWS: it exchanges a verified login (from a Cognito user pool, or a third-party IdP like Google, Apple, Facebook, or any SAML/OIDC provider) for temporary AWS credentials from STS, scoped by an IAM role. Use this only when a signed-in user must call an AWS service (S3, DynamoDB) directly from the client.
The decision rule, stated once: need to authenticate a user and protect your own API? → user pool (validate the access token). Need to give that user scoped AWS credentials to hit an AWS service directly? → identity pool (which returns STS credentials). The figure traces the full chain when both are used together: user pool authenticates and issues JWTs, then the identity pool swaps the token for STS credentials. Identity pools support authenticated and unauthenticated (guest) roles, letting you grant limited access to users who have not signed in.
Tokens and standards. Cognito user pools are an OIDC/OAuth 2.0 provider: the ID token is an OIDC construct, the access token is OAuth 2.0, and the Cognito Hosted UI / managed login[12] implements the standard authorization-code and other OAuth 2.0 grant flows so you do not hand-roll sign-in. The ID and access tokens are JWTs you can verify against the pool's public JWKS; the refresh token is opaque and encrypted (readable only by the user pool), so you do not validate it yourself.
Protecting the API and exam patterns: API Gateway authorizers, OAuth 2.0 / OIDC, common traps
This section applies the model to the most-tested DVA-C02 surface, protecting an HTTP/REST API, and collects the distractors. The scope: deciding which authorizer gates a route, and which credential each one validates. The figure branches the three authorizer types by the credential each validates; the trap list after it is a flat checklist, so it stays in prose.
Amazon API Gateway authorizer types (authorizer overview[13]):
- Cognito / JWT authorizer, declarative, no code. You point it at a Cognito user pool (REST API: Cognito authorizer) or any OIDC issuer (HTTP API: JWT authorizer); API Gateway validates the incoming bearer JWT's signature, expiry, and scopes/claims and allows or denies the route. Use the user pool access token here, not the ID token (the authN-vs-authZ rule from the model section). This is the default answer when sign-in is already Cognito.
- Lambda authorizer (formerly custom authorizer), your function returns an allow/deny decision (an IAM policy document, or a simple boolean for HTTP APIs). Two event types:
- TOKEN, receives only the bearer token from a single header; the right choice for validating an opaque or non-Cognito JWT.
- REQUEST, receives the full request context (headers, query string, path, stage variables); needed when the decision depends on more than one input. Lambda authorizer results can be cached by TTL to avoid invoking the function on every request.
- IAM authorization (
AWS_IAM), the caller signs the request with SigV4 using IAM credentials, and API Gateway evaluates it through the same identity/resource-policy model as any AWS API call. Best for service-to-service or internal callers that already hold IAM credentials, not for browser/mobile end users.
OAuth 2.0 / OIDC, in one frame. OIDC[10] is the identity (authN) layer on top of OAuth 2.0 (the authorization framework). Mapped to AWS: the ID token is the OIDC artifact (who the user is); the access token is the OAuth 2.0 artifact carrying scopes (what the bearer may do). A JWT/Cognito authorizer enforces the access token's scopes at the edge. For per-request, fine-grained decisions beyond what scopes express ("can this user edit this document?"), validate claims in code or use Amazon Verified Permissions[14]. IAM and edge authorizers gate the route, not row-level business rules.
Exam traps, distilled:
- ID token used to authorize an API call. Wrong, the ID token proves identity; send the access token to the authorizer. The single most common Cognito distractor.
- Long-lived IAM access keys embedded in code on EC2/ECS/Lambda. Wrong, attach a role (the application's own identity section); the SDK gets rotating STS credentials.
- User pool vs identity pool swapped. "Let the signed-in user write to S3 directly" needs an identity pool (STS credentials), not just a user pool. "Sign users in and protect my API" needs the user pool access token.
- Workforce vs application end users. Employees reaching AWS accounts → IAM Identity Center; application customers → Cognito user pool. Reaching for one where the other belongs is a deliberate distractor.
DurationSecondsand role chaining. Default 1 hour, range 15 minutes to the role max (1–12 hours), but chaining caps at 1 hour, restate of the STS facts from the application's own identity section.Principal: "*"on a resource or trust policy = anyone, any account. Almost always wrong; scope to a principal ARN, an account, oraws:PrincipalOrgID.
| Mechanism | Primary job | What it issues / returns | Typical use in app code |
|---|---|---|---|
| Cognito user pool | Authentication (user directory) | OIDC ID token + OAuth 2.0 access token + refresh token (JWTs) | Sign users in; send the JWT to a protected API |
| Cognito identity pool | Authorization to AWS (federation) | Temporary AWS credentials from STS, scoped by an IAM role | Let a signed-in user call S3/DynamoDB directly with limited rights |
| IAM role + STS | Authorization for the app's own AWS calls | Auto-rotating temporary credentials (default 1 hour) | Lambda/ECS/EC2 calls AWS APIs without static keys; AssumeRole for cross-account |
| API Gateway JWT/Cognito authorizer | Authorization at the API edge (declarative) | Allow/deny after validating a bearer JWT's claims and scopes | Gate routes by token validity without custom code |
| API Gateway Lambda authorizer | Authorization at the API edge (custom) | An IAM policy or allow/deny your function computes from the request | Validate non-JWT bearer tokens or apply bespoke logic |
Decision tree
Sharp facts the exam loves — give these one last read before exam day.
Cheat sheet
Sharp facts the exam loves — scan these before test day.
- Authentication proves who you are; authorization decides what you may do
Authentication and authorization are two separate steps, and an exam scenario almost always turns on telling them apart. Authentication verifies an identity (a SigV4-signed AWS request, a JWT validated by Cognito, or a federated login) while authorization is a distinct policy decision about what that verified identity may do, so a perfectly authenticated caller can still be denied. The practical consequence: a credential that proves identity (a Cognito ID token) is not the credential that grants access (an OAuth 2.0 access token or temporary AWS credentials).
Trap Treating a successful sign-in as proof a call is allowed: authorization is evaluated separately, so an authenticated principal can still hit an explicit deny.
- An explicit Deny always beats any Allow
AWS authorization is allow + no-explicit-deny: a request is permitted only when some policy allows the action on the resource AND no policy anywhere contains an explicit
Deny. A single explicitDenyoverrides everyAllow, which is why even an admin principal can be blocked from an S3 bucket whose bucket policy denies its ARN. Anything not explicitly allowed is denied by default (implicit deny), but that default is weaker than an explicit deny. Only an explicitAllowcan overcome an implicit deny, and nothing overcomes an explicit one.Trap Assuming an Allow on an admin or broadly-permissive policy can override an explicit Deny elsewhere, when a single explicit Deny wins over every Allow in the evaluation.
6 questions test this
- A developer is troubleshooting an access denied error when an AWS Lambda function attempts to retrieve a secret from AWS Secrets Manager.…
- A company is implementing a permissions boundary to limit what IAM roles developers can create for their Lambda functions. The security…
- A developer is configuring a Lambda function that uses environment variables to store an API key. The company requires that only specific…
- A company's security policy requires that all IAM roles created for Lambda functions can only access specific secrets in AWS Secrets…
- A developer is troubleshooting an IAM policy issue. A user has an identity-based policy that allows ec2:TerminateInstances on all EC2…
- A developer is troubleshooting an access denied error for an AWS Lambda function that needs to read from an S3 bucket. The Lambda…
- Same account: an Allow in either the identity or the resource policy is enough
For a request within one account, AWS takes the union of the identity-based policy (attached to the user/role) and the resource-based policy (attached to the S3 bucket, Lambda function, SQS queue, etc.): an
Allowin either one (or both) grants the action. Identity-based policies attached to a principal are themselves additive, so multiple attached policies combine. The notable exception is KMS, where the key policy must allow the principal explicitly for IAM permissions to take effect.Trap Assuming KMS follows the union rule: a KMS key policy must grant the principal explicitly, so an identity policy alone is not sufficient.
- Cross-account access needs an Allow in BOTH accounts
When the principal and the resource live in different accounts, the union rule no longer applies: you need an
Allowin the caller's identity-based policy in its own account AND anAllowin the resource-based policy (or role trust policy) in the resource's account. Both sides must opt in, either one alone fails. This is the single behavioral difference between same-account and cross-account evaluation.Trap Granting only the resource-based policy in the target account and expecting cross-account access to work: the caller's own account must also allow the action on its identity.
10 questions test this
- A developer is creating an application that runs in AWS account A and needs to access an Amazon S3 bucket in AWS account B. The developer…
- A company maintains database credentials in AWS Secrets Manager in a centralized security account (Account A). Application workloads…
- A developer is configuring cross-account access between a production account and a development account. The development account (Account A)…
- A company stores data in an Amazon S3 bucket with SSE-KMS default encryption using a customer managed key. Users from a partner company in…
- A company has a centralized security account that stores secrets in AWS Secrets Manager. Application teams in separate AWS accounts need to…
- A company has a centralized security account that stores database credentials in AWS Secrets Manager. Application teams in separate…
- A development team in Account A needs to access Amazon S3 resources in Account B. A developer sets up an IAM role in Account B with a trust…
- A company has an Amazon S3 bucket in Account A that stores data encrypted with SSE-KMS using a customer managed KMS key. A development team…
- A company stores database credentials in AWS Secrets Manager in a central security account. An application running on Amazon EC2 instances…
- A company has a development team in Account A that needs to access Amazon S3 buckets in Account B. A developer is implementing…
- Give compute a role, never embed long-lived access keys
Application code should carry an IAM role attached to the compute, not an access key ID and secret baked into code or config. Embedding static keys is the antipattern the exam punishes. With a role, the AWS SDK transparently obtains temporary credentials that auto-rotate and expire, so there is no long-lived secret to leak or rotate manually. Reach for the role mechanism that matches the compute: instance profile (EC2), task role (ECS), or execution role (Lambda).
Trap Storing IAM access keys in environment variables or config files on EC2/ECS/Lambda: attach a role instead and let the SDK fetch rotating STS credentials.
- Match the role type to the compute: instance profile, task role, execution role
Each compute service exposes role credentials differently and the names are tested as distractors. An EC2 instance profile wraps a role and the SDK fetches credentials from the Instance Metadata Service. Enforce IMDSv2 (
HttpTokens=required) to block SSRF-based credential theft. A Lambda execution role is set at function creation and auto-discovered by the SDK. For ECS, the task role is what the application code inside the container uses for its own AWS calls, distinct from the task execution role, which only lets the ECS agent pull images from ECR and ship logs to CloudWatch.Trap Putting the application's AWS permissions on the ECS task execution role: that role is for the agent (ECR pull, CloudWatch logs); app calls use the task role.
- STS sessions default to 1 hour, range 15 min to 12 h
When code switches identity it calls
sts:AssumeRole, which returns temporary credentials valid forDurationSeconds: 3600 seconds (1 hour) when omitted. The value may range from 900 seconds (15 minutes) up to the role's configured maximum session duration, which an admin can set anywhere from 1 to 12 hours. Requesting more than the role's maximum fails, so the role's ceiling caps the session.- Role chaining caps the session at 1 hour regardless of the role max
Role chaining (using one already-assumed role to assume a second role) always caps the new session at 1 hour, even if the target role's maximum session duration is set to 12 hours. This is a frequently tested gotcha: the 12-hour maximum applies to a directly assumed role, not to one reached by chaining from temporary credentials.
Trap Expecting a chained AssumeRole to honor a 12-hour role maximum: chaining silently caps the session at 1 hour.
3 questions test this
- A developer is building an application that uses role chaining to access resources in multiple AWS accounts. The application first assumes…
- A developer is building a data processing application that uses role chaining to access resources across multiple AWS accounts. The…
- A developer is implementing role chaining where an AWS Lambda function assumes Role A in Account X, and then uses those credentials to…
- A trust policy Principal of :root means the whole account, not the root user
Who may assume a role is governed by the role's trust policy (its resource-based policy). A trust policy
Principalofarn:aws:iam::<account-id>:rootdenotes account-level delegation: the entire account is trusted, NOT the AWS account root user. It means any IAM principal in that account whose own identity policy also permitssts:AssumeRolemay assume the role. To trust a single entity, name it explicitly, e.g.arn:aws:iam::<account-id>:role/Build.Trap Reading
:rootin a trust policy as the account's root user: it is account-wide delegation; the assuming principal still needs its own AssumeRole permission.- Require an ExternalId when a third party assumes your role
When a third-party SaaS assumes a role in your account, add a
Conditiononsts:ExternalIdin the role's trust policy and share that agreed value with the vendor. The vendor must pass the matchingExternalIdonAssumeRoleor the call fails. This defends against the confused-deputy problem, where an attacker tricks the trusted third party into using its access on your behalf without knowing your secret value.Trap Treating ExternalId as a secret password that authenticates the vendor, when it is a confused-deputy guard rather than a credential and offers no protection if the vendor is itself compromised.
8 questions test this
- A developer is building a multi-tenant SaaS application where a third-party company needs programmatic access to resources in the…
- A developer is building a multi-tenant SaaS application that needs to access resources in customer AWS accounts. Each customer creates an…
- A company hires a third-party SaaS provider to perform cost analysis on their AWS account. The company creates an IAM role in their account…
- A development team is configuring cross-account access for an application. The application in Account A needs to assume a role in Account B…
- A company requires that IAM roles used by applications in development accounts can only be assumed by specific CI/CD pipeline roles. The…
- A company uses an external third-party auditing service that requires access to read Amazon CloudWatch Logs in the company's AWS account.…
- A third-party monitoring company needs access to resources in a customer's AWS account. The customer creates an IAM role for the third…
- A company needs to grant a third-party vendor access to an S3 bucket in the company's AWS account. The vendor will access the bucket from…
- A permissions boundary or session policy caps permissions: it never grants them
Grants union, but ceilings intersect. Where a ceiling is present (a permissions boundary on the principal, or a session policy passed to
AssumeRole) effective permissions become the intersection of the identity's grants and that ceiling, so a session can never exceed what the role's own policy already allows. A boundary with no matching grant in the identity policy authorizes nothing; you still need an explicitAllowin the identity policy for any action.Trap Treating a permissions boundary or session policy as a way to add permissions: it only narrows; the underlying identity policy must still grant the action.
16 questions test this
- A developer is creating an application that uses AWS STS AssumeRole to provide temporary credentials to external contractors. The…
- A developer is implementing cross-account access where an application in Account A needs to access an Amazon S3 bucket in Account B. The…
- A security team wants to delegate IAM policy creation to developers while ensuring they cannot create policies that grant permissions…
- A company is implementing a permissions boundary to limit what IAM roles developers can create for their Lambda functions. The security…
- A company uses AWS STS AssumeRole to provide developers with temporary credentials to access production resources. The security team wants…
- A developer is implementing cross-account access for an application running on Amazon EC2 in Account A that needs to access Amazon DynamoDB…
- A company's security policy requires that all IAM roles created for Lambda functions can only access specific secrets in AWS Secrets…
- A developer is implementing an identity broker that authenticates users against a corporate Active Directory and provides AWS access. The…
- A developer is building a multi-tenant SaaS application where different tenants should have access to specific S3 buckets based on their…
- A development team at a financial services company needs to create IAM roles for Lambda functions that access customer data stored in AWS…
- A central IT team wants to allow developers to create IAM roles for their Lambda functions while ensuring the developers cannot grant more…
- A development team lead needs to allow developers to create IAM roles for their Lambda functions that access secrets stored in AWS Secrets…
- A development team needs permission to create IAM roles for their Lambda functions, but the security team wants to prevent privilege…
- A development team manager wants to allow developers to create IAM roles for their Lambda functions while ensuring that the developers…
- A developer is troubleshooting an issue where an IAM role has both an identity-based policy that allows s3:PutObject and a permissions…
- A development team lead needs to allow developers to create IAM roles for their Lambda functions while ensuring they cannot grant…
- A Cognito user pool authenticates users and issues three JWTs
A Cognito user pool is a user directory that performs authentication: users sign in and the pool returns an ID token, an access token (both JWTs you can verify against the pool's public JWKS), and a refresh token (opaque and encrypted, used only to mint new ID/access tokens). It answers "who is this user?": reach for a user pool when you need to sign your own application's end users in and protect your own API. The Hosted UI / managed login implements standard OAuth 2.0 grant flows (such as authorization code) so you do not hand-roll sign-in.
Trap Assuming the refresh token is a JWT you can verify against the JWKS like the others, when it is opaque and encrypted, usable only to mint new ID/access tokens.
- Send the access token to authorize an API, not the ID token
Of the user-pool JWTs, the ID token carries identity claims (email, name,
sub) and proves who the user is: consume it in your app to learn about the user, never to authorize a call. The access token is the OAuth 2.0 bearer token carrying scopes and groups, and it is what you present to a protected API to be authorized. The refresh token only mints new ID/access tokens and is never sent to your API.Trap Sending the Cognito ID token to an API authorizer: it proves identity, not authorization; pass the access token, whose scopes the authorizer checks.
- Use a Cognito identity pool to hand a signed-in user temporary AWS credentials
A Cognito identity pool (federated identities) performs authorization to AWS: it exchanges a verified login (from a user pool, or a third-party IdP like Google, Apple, Facebook, or any SAML/OIDC provider) for temporary AWS credentials from STS, scoped by an IAM role. Reach for it only when a signed-in user must call an AWS service such as S3 or DynamoDB directly from the client. Identity pools also support an unauthenticated (guest) role, granting limited access to users who have not signed in.
Trap Reaching for an identity pool just to authenticate users or protect your own API: that is the user pool's job; the identity pool exists to vend AWS credentials.
- User pool authenticates, identity pool federates to AWS: don't swap them
The decision rule the exam relentlessly tests: need to authenticate a user and protect your own API? Use a user pool and validate the access token. Need to give that user scoped AWS credentials to hit an AWS service directly? Use an identity pool, which returns STS credentials. Used together, the user pool authenticates and issues JWTs, then the identity pool swaps a token via STS for AWS credentials.
Trap Picking a user pool for "let the signed-in user write to S3 directly": that needs an identity pool's STS credentials, not just a JWT.
- Cognito is for application users; IAM Identity Center is for your workforce
Match the identity service to the audience. Amazon Cognito signs in an application's external end users (customers of your app). IAM Identity Center signs in your own workforce: employees needing access to AWS accounts and business applications. The two are not interchangeable, and a scenario that names one where the other belongs is a deliberate distractor.
Trap Using Cognito for employee access to AWS accounts (or Identity Center for app customers): Cognito = app end users, Identity Center = workforce.
- A Cognito or JWT authorizer gates a route declaratively, no code
An API Gateway Cognito authorizer (REST API) or JWT authorizer (HTTP API) validates an incoming bearer JWT's signature, expiry, and scopes/claims and allows or denies the route with no custom code. Point it at a Cognito user pool or any OIDC issuer and pass the access token. This is the default answer when sign-in is already Cognito and you only need standard token validation at the edge.
Trap Writing a Lambda authorizer to validate a standard Cognito/OIDC JWT, when the built-in Cognito or JWT authorizer does signature, expiry, and scope checks declaratively with no code.
2 questions test this
- Use a Lambda authorizer for non-JWT tokens or bespoke logic
A Lambda authorizer (formerly custom authorizer) runs your function to return an allow/deny decision (an IAM policy document, or a simple boolean for HTTP APIs) and is the right choice for validating an opaque or non-Cognito token, or applying custom logic a declarative authorizer can't express. A TOKEN authorizer receives only the bearer token from a single header; a REQUEST authorizer receives the full request context (headers, query string, path, stage variables) and is needed when the decision depends on more than one input. Results can be cached by TTL to avoid invoking the function on every request.
Trap Choosing a TOKEN Lambda authorizer when the decision needs query strings or multiple headers: TOKEN sees only one header's token; use REQUEST for full request context.
8 questions test this
- A developer is building a REST API using Amazon API Gateway with a Lambda authorizer. The authorizer validates JWT tokens passed in the…
- A company uses Amazon API Gateway REST API with a Lambda TOKEN authorizer to protect their APIs. The authorizer validates JWT tokens from…
- A development team is implementing API authentication for an HTTP API using Amazon API Gateway. The team wants to use a Lambda authorizer…
- A financial services company is building a REST API using Amazon API Gateway. The company uses an external OAuth 2.0 identity provider to…
- A company is building a REST API using Amazon API Gateway with Lambda authorizer for authentication. The development team notices that when…
- A company is building a microservices architecture using Amazon API Gateway REST APIs. The development team needs to implement custom…
- A developer needs to implement fine-grained access control for an Amazon API Gateway REST API using a Lambda authorizer. The authorizer…
- A company is building an API Gateway REST API with a Lambda REQUEST authorizer. The authorizer must validate requests based on a…
- Use AWS_IAM authorization for SigV4 callers, not browser end users
API Gateway IAM authorization (
AWS_IAM) requires the caller to sign the request with SigV4 using IAM credentials, and the request is evaluated through the same identity/resource-policy model as any AWS API call. It fits service-to-service or internal callers that already hold IAM credentials, not browser or mobile end users, who carry JWTs and should use a Cognito/JWT or Lambda authorizer instead.Trap Choosing AWS_IAM authorization for browser or mobile end users, who hold JWTs rather than signable IAM credentials; SigV4/IAM auth fits service-to-service callers.
- OIDC is the identity layer on top of OAuth 2.0's authorization framework
OAuth 2.0 is the authorization framework (delegating access via tokens); OIDC adds the identity (authentication) layer on top. Mapped to Cognito: the ID token is the OIDC artifact answering who the user is, and the access token is the OAuth 2.0 artifact carrying scopes for what the bearer may do. A JWT/Cognito authorizer enforces the access token's scopes at the API edge.
Trap Treating OAuth 2.0 itself as an authentication protocol, when OAuth 2.0 handles authorization and OIDC is the identity layer added on top to authenticate the user.
- Edge authorizers gate the route; fine-grained rules go in code
API Gateway authorizers and IAM gate whether a caller may reach a route or action: they do not express per-resource business rules like "can THIS user edit THIS document?". For fine-grained, per-request decisions beyond what scopes capture, validate claims in your application code or use Amazon Verified Permissions. Don't expect a scope check at the edge to enforce row-level ownership.
Trap Expecting an edge scope or JWT authorizer to enforce row-level ownership like "can this user edit this document", when per-resource rules belong in code or Verified Permissions.
- Apply least privilege and prefer MultiFactorAuthPresent for fresh-MFA checks
Each policy should grant only the actions and resources an identity needs, narrowed with
Conditionkeys where possible. When gating a sensitive action on MFA, know the two condition keys differ:aws:MultiFactorAuthPresentis true only when the CURRENT credentials were obtained with MFA, whileaws:MultiFactorAuthAgemeasures how long ago that MFA happened. Use the age key when you need recency, not just presence.Trap Relying on
aws:MultiFactorAuthAgeto require MFA at all: the age key is absent (so a deny-on-absence can misfire) when no MFA occurred;aws:MultiFactorAuthPresentchecks that MFA happened, the age key checks how recently.- Principal: "*" on a resource or trust policy means anyone, anywhere
A
Principalof"*"on a resource-based or trust policy grants the action to any principal in any account (effectively public) and is almost always the wrong answer on a security scenario. Scope access instead to a specific principal ARN, a specific account, oraws:PrincipalOrgIDto bound it to your organization. The exam dangles"*"as a tempting "it just works" option.Trap Accepting
Principal: "*"to make access "just work": it exposes the resource to every AWS account; scope to a principal ARN, account, or PrincipalOrgID.- ABAC compares aws:PrincipalTag to aws:ResourceTag in a StringEquals condition
Attribute-based access control grants access only when a tag on the calling principal matches a tag on the target resource. The policy uses a
ConditionwithStringEqualscomparingaws:ResourceTag/<Key>to the policy variable${aws:PrincipalTag/<Key>}(for exampleteamorEnvironment) so one policy scales to every team without per-team rules. When the principal is an IAM user rather than a tagged role,${aws:username}is the matching variable against the resource's owner tag.Trap Hard-coding a tag value as a literal string instead of the
${aws:PrincipalTag/...}policy variable: ABAC's whole point is the dynamic principal-vs-resource tag comparison.5 questions test this
- A company uses Amazon EC2 instances for development workloads. The security team requires that developers can only start and stop EC2…
- A company implements attribute-based access control (ABAC) to manage access to EC2 instances across multiple development teams. Each team…
- A developer is creating an IAM policy to allow EC2 instances to access specific resources based on their tags. The policy should allow…
- A company implements attribute-based access control (ABAC) to manage access to secrets stored in AWS Secrets Manager. Development teams…
- A developer is implementing attribute-based access control (ABAC) for a microservices application. The application uses IAM roles with tags…
- A Lambda authorizer must return principalId plus a policyDocument, with context values stringified
A REST API Lambda authorizer's output must include a
principalIdand apolicyDocument(an IAM policy withexecute-api:Invokestatements); omit either and API Gateway returns 500, not 403. Anycontextmap it returns may hold only stringified primitives: you cannot set a JSON object or array as a context value. The backend reads those values via$context.authorizer.<key>.Trap Returning a JSON object or array in the authorizer's
contextmap: every context value must be a stringified primitive (string, number, boolean) or the request fails.5 questions test this
- A developer is troubleshooting an API Gateway REST API with a Lambda authorizer. When clients send requests with valid authorization…
- A developer is configuring a Lambda authorizer for an Amazon API Gateway REST API. The Lambda authorizer function validates incoming…
- A company has an Amazon API Gateway REST API with a TOKEN-type Lambda authorizer. The authorizer validates OAuth tokens from an external…
- A developer is implementing a Lambda authorizer for an API Gateway REST API that validates JWT tokens. The authorizer needs to pass user…
- A company is building a microservices architecture using Amazon API Gateway REST APIs. The development team needs to implement custom…
Also tested in
- CLF-C02 AWS Certified Cloud Practitioner
- DEA-C01 AWS Certified Data Engineer - Associate
- DEA-C01 AWS Certified Data Engineer - Associate
- SAA-C03 AWS Certified Solutions Architect – Associate
- SAP-C02 AWS Certified Solutions Architect - Professional
- PCA Professional Cloud Architect
- CISSP Certified Information Systems Security Professional
References
- Using the Amazon Cognito user pool ID token
- Using the Amazon Cognito user pool access token
- IAM JSON policy evaluation logic
- Use IMDSv2 (configure the instance metadata service)
- AWS Security Token Service API Reference: Welcome
- AWS STS AssumeRole API
- Security best practices in IAM
- Policies and permissions in IAM (session policies)
- Amazon Cognito user pools
- Amazon Cognito user pools OIDC/OAuth 2.0 server contract reference
- Amazon Cognito identity pools
- Amazon Cognito user pool app integration (Hosted UI / managed login)
- Controlling and managing access to a REST API in API Gateway
- What is Amazon Verified Permissions?