Learning/AWS SQS/16 — Security
Advanced 40 min read outline
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:SourceAccount conditions 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:GenerateDataKey and kms:Decrypt — the single most common cause of 'it worked unencrypted'
  • In transit: HTTPS always; enforce with an aws:SecureTransport condition
  • 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:SourceArn conditions 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

  • Policy queue attribute (the resource-based policy)
  • KmsMasterKeyId, KmsDataKeyReusePeriodSeconds (higher reuse = fewer KMS calls = lower cost, slightly weaker isolation)
  • SqsManagedSseEnabled for SSE-SQS
  • Queue policy size limits → aws-facts.md §3

8. Production considerations

  • Never sqs:* on Resource: "*" — 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:Decrypt on 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 on aws:SourceArn
  • PII in the body. Why → 14-day retention plus DLQ retention plus CloudWatch logs. Instead → store a reference
  • Allowing sqs:PurgeQueue broadly. 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:SourceArn condition 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:SourceArn prevent 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 policy
  • resource-based policy
  • queue policy
  • SSE-SQS
  • SSE-KMS
  • confused deputy
  • VPC endpoint
  • PrivateLink

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