This chapter is an outline. The curriculum, learning objectives and
structure are settled; the prose, diagrams and code are still being written.
What is below is the plan for the chapter, not the chapter.
Security
Who can send, who can receive, and who can read the bytes at rest. The central distinction — identity-based policy vs resource-based queue policy — is both the thing interviewers ask about and the thing that blocks every cross-account integration on the first attempt.
1. What you will learn
- Write least-privilege IAM policies for a producer and for a consumer
- Explain the difference between an identity-based policy and a resource-based queue policy, and when you need both
- Choose between SSE-SQS and SSE-KMS, and price the difference
- Configure cross-account access correctly
- Decide whether you need a VPC endpoint for SQS
2. Why this concept exists
- A queue is a data store: messages contain order details, customer identifiers, sometimes PII
- The default
sqs:*grant that makes the tutorial work is the grant that makes the audit fail - Cross-account and cross-service access (S3 → SQS, SNS → SQS) is impossible without understanding resource policies
3. Beginner explanation
- IAM decides who is allowed to call which SQS API on which queue
- The queue itself can also have a policy saying who may use it
- Messages can be encrypted while stored, either with an AWS-managed key or your own
4. How it actually works
- Identity-based policy — attached to a user/role: "this principal may do X". Lives in the caller's account
- Resource-based queue policy — attached to the queue: "these principals may do X to me". Lives in the queue's account
- Same-account: either suffices. Cross-account: both are required — the caller's account must allow it and the queue must allow the caller
- AWS services (S3, SNS, EventBridge) have no IAM role in your account, so they must be granted via a queue policy, usually with
aws:SourceArn/aws:SourceAccountconditions to prevent the confused-deputy problem - Producer permissions:
sqs:SendMessage,sqs:GetQueueUrl,sqs:GetQueueAttributes - Consumer permissions:
sqs:ReceiveMessage,sqs:DeleteMessage,sqs:ChangeMessageVisibility,sqs:GetQueueAttributes - SSE-SQS — AWS-managed keys, free, one checkbox, no key policy to manage, no audit trail per key
- SSE-KMS — your CMK, per-request KMS charges, full key policy control, CloudTrail visibility, and the ability to revoke
- With SSE-KMS, producers and consumers also need
kms:GenerateDataKeyandkms:Decrypt— the single most common cause of 'it worked unencrypted' - In transit: HTTPS always; enforce with an
aws:SecureTransportcondition - VPC endpoints (interface / PrivateLink): keep SQS traffic off the public internet; add endpoint policies for another control layer
5. Diagram
- Identity-based vs resource-based policy evaluation, same-account and cross-account
- Encryption at rest and in transit across the full path
- VPC endpoint traffic flow vs internet gateway flow
6. Step-by-step flow
- Define the roles: producer role, consumer role, operator role
- Attach least-privilege identity policies scoped to the queue ARN
- Add a queue policy only if a different account or an AWS service needs access
- Add
aws:SourceArnconditions on any service principal grant - Enable encryption; if SSE-KMS, update the key policy and the principals' policies
- Enforce
aws:SecureTransport - Add a VPC endpoint if traffic must not leave the VPC
- Audit with IAM Access Analyzer
7. Configuration
Policyqueue attribute (the resource-based policy)KmsMasterKeyId,KmsDataKeyReusePeriodSeconds(higher reuse = fewer KMS calls = lower cost, slightly weaker isolation)SqsManagedSseEnabledfor SSE-SQS- Queue policy size limits →
aws-facts.md§3
8. Production considerations
- Never
sqs:*onResource: "*"— scope every statement to a queue ARN - Separate producer and consumer roles even when one service does both today
- KMS cost is real at high volume: tune
KmsDataKeyReusePeriodSeconds(up to 24 h) to cut KMS API calls - PII in message bodies is the quiet compliance problem — SQS retains up to 14 days and a DLQ may hold it far longer. Prefer a reference to a record over the record itself
- Queue policies are a common blast-radius mistake:
Principal: "*"with no condition makes your queue world-writable - Rotate nothing manually — use roles; if you find an access key, that is the finding
9. Common mistakes
- Granting
sqs:*. Why → a consumer can purge the queue. Instead → enumerate actions - Cross-account with only an identity policy. Why → both sides must allow it. Instead → add the queue policy too
- SSE-KMS without
kms:Decrypton the consumer. Why → receives fail with an opaque KMS error. Instead → grant both KMS actions Principal: "*"in a queue policy without conditions. Why → anyone can send. Instead → condition onaws:SourceArn- PII in the body. Why → 14-day retention plus DLQ retention plus CloudWatch logs. Instead → store a reference
- Allowing
sqs:PurgeQueuebroadly. Why → one call, all messages gone, no undo. Instead → operator role only
10. Real-world example
- A cross-account integration: account A's service sends to account B's queue. Show both policies, the failure mode with only one, and the
aws:SourceArncondition that makes it safe
11. Interview questions
- 🟢 How do you control who can send to an SQS queue?
- 🟡 What is the difference between an identity-based policy and a queue policy?
- 🟡 What is the difference between SSE-SQS and SSE-KMS?
- 🔴 Why does cross-account access require two policies?
- 🔴 Your consumer gets an AccessDenied after encryption was enabled. Diagnose.
- 🔴 What is the confused-deputy problem and how does
aws:SourceArnprevent it? - ⚫ Design the security model for a multi-tenant queue-based platform handling regulated data.
12. Summary
- Identity policy = what the principal may do; queue policy = who may use the queue
- Cross-account and AWS-service access need the queue policy
- SSE-KMS requires KMS permissions on producers and consumers
- Scope to the queue ARN; never
sqs:*on* - Keep PII out of message bodies
Authoring notes
Terms defined in this module (defined once here, linked from everywhere else):
identity-based policyresource-based policyqueue policySSE-SQSSSE-KMSconfused deputyVPC endpointPrivateLink
Code samples:
- Least-privilege producer IAM policy (JSON)
- Least-privilege consumer IAM policy (JSON)
- Cross-account queue policy with
aws:SourceArn - Creating a queue with SSE-KMS and the matching key policy
- Enforcing
aws:SecureTransport
Mandatory "why?" answers:
- Why does cross-account access need two policies when same-account needs one?
- Why does an AWS service need a resource policy rather than an IAM role?
Facts to pull from _reference/aws-facts.md: queue policy 8,192 bytes / 20 statements / 50 principals / 10 conditions
← Previous: 15 — Performance and Throughput · Index: Course home · Next: 17 — Monitoring and Observability →