Lesson 1.5: Identity architecture and authorization patterns on AWS
Identity is the primary security boundary in AWS. Every request to an AWS service is evaluated against IAM policies before it reaches the target resource. For developers, identity architecture directly affects runtime behavior, service integrations, and cross-account access patterns. This lesson combines IAM fundamentals with application-level authentication and API authorization, showing how AWS evaluates permissions and integrates authentication flows with services such as API Gateway, Lambda, and Cognito.
IAM architecture: users, roles, and policies
AWS Identity and Access Management (IAM) is a global service whose configuration applies across all regions. IAM manages identities and access through three main components: users, roles, and policies. Users typically represent long-term human identities, though modern architectures often favor federated access and role-based access control. Roles represent temporary identities and provide short-lived credentials. They are used by services such as EC2, Lambda, and ECS to access other AWS resources, and can also be assumed across accounts via STS AssumeRole.
Policies define permissions as JSON documents that allow or deny specific actions on resources. Policies can attach to identities (identity-based policies) or directly to resources (resource-based policies). For example, when a Lambda function accesses DynamoDB, it assumes its execution role, and the policies attached to that role determine what actions are permitted. Incorrectly scoped policies result in AccessDenied errors at runtime.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["dynamodb:GetItem"],
"Resource": ["arn:aws:dynamodb:us-east-1::table/MyTable"]
}
]
}
This JSON policy shows how an IAM role can allow a Lambda function to read from a specific DynamoDB table.
How IAM evaluates permissions
When a request is made to an AWS service, IAM evaluates all applicable policies to determine whether the action is allowed:
- Identity-based policies attached to the user or role
- Resource-based policies attached to the target resource
- Service control policies (if using AWS Organizations)
Evaluation follows strict rules: any explicit deny overrides allow. If no explicit deny exists and at least one policy allows the action, the request is permitted. If no policy allows the action, the request is implicitly denied. Misconfigured policies often result in AccessDenied errors at runtime.
IAM is a global service, and its configuration applies across all regions. It is built on three main components:
- Users: Represent long-term human identities, though modern architectures often favor federated access.
- Roles: Provide temporary credentials. They are used by services such as EC2, Lambda, and ECS to access other AWS resources, and can also enable cross-account access via STS AssumeRole.
- Policies: Define permissions as JSON documents that allow or deny specific actions on resources. Policies can attach to identities (identity-based policies) or directly to resources (resource-based policies).
For example, when a Lambda function accesses DynamoDB, it assumes its execution role, and the policies attached to that role determine what actions are permitted. Incorrectly scoped policies result in AccessDenied errors at runtime.
Cross-account access with STS AssumeRole
Cross-account access is common, for instance when a CI/CD pipeline in one account deploys resources in another. AWS Security Token Service (STS) and AssumeRole enable this. The target account defines a role with a trust policy specifying which principals are allowed to assume it. The trusted principal calls AssumeRole, receiving temporary credentials with the target role’s permissions.
Two layers are required:
- Source principal must have permission to call sts:AssumeRole
- Target role’s trust policy must allow the source principal
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {"AWS": "arn:aws:iam::ACCOUNT_ID:role/DevRole"},
"Action": "sts:AssumeRole"
}
]
}
This trust policy permits a role in another account to assume the target role securely.
Application-level authentication with Amazon Cognito
IAM controls AWS service access, but application users require a separate model. Amazon Cognito provides identity management with user pools and identity pools.
- User pools handle authentication and issue JWT tokens after login.
- Identity pools provide temporary AWS credentials, enabling users to access AWS resources directly via mapped IAM roles.
A common pattern is to authenticate users through a user pool and map them to IAM roles via an identity pool. Developers must implement token validation and role mapping carefully to avoid granting excessive permissions.
API Gateway authorization models
API Gateway supports multiple authorization mechanisms:
- IAM authorization: requests signed with AWS credentials, suitable for internal service-to-service calls
- Cognito authorizers: validate JWT tokens for user-facing applications
- Lambda authorizers: implement custom authorization logic beyond token validation
Authorization occurs before backend integration. If authorization fails, requests do not reach the Lambda function or other targets.
aws apigateway update-authorizer \
--rest-api-id abc123 \
--authorizer-id xyz456 \
--patch-operations op=replace,path=/authorizerUri,value='arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:ACCOUNT_ID:function:AuthLambda/invocations'
This CLI command updates an API Gateway Lambda authorizer for custom authorization.
Integrating IAM and application authentication
In many architectures, IAM and application-level authentication intersect. For example, an API Gateway endpoint secured with a Cognito authorizer validates user identity. The backend Lambda function runs under an IAM execution role, which determines what AWS resources the function can access.
This separation enforces two layers:
- User authentication and authorization at the API level
- Service authorization at the infrastructure level via IAM roles
If the Lambda role lacks permission to write to DynamoDB, requests fail even if user authentication succeeds. Conversely, misconfigured API authorizers can allow unauthorized users to invoke backend services.
Understanding policy evaluation logic, explicit deny precedence, STS AssumeRole patterns, and token-based authorization is fundamental for designing secure, least-privilege, and scalable AWS applications aligned with DVA-C02 expectations.
My name is Naeem ul Haq. I’ve been working with AWS since its early days and have deep expertise across its evolving ecosystem.