SQS Security: IAM Policies and Network Security
Amazon Simple Queue Service (SQS) is a fully managed message queuing service that enables decoupling and scaling of microservices, distributed systems, and serverless applications. Because SQS often carries sensitive data flowing between application components, securing access to your queues is critical. This tutorial covers the two primary pillars of SQS security: IAM (Identity and Access Management) policies that control who can interact with your queues, and network security controls that restrict where requests can originate from.
Why SQS Security Matters
By default, a newly created SQS queue is accessible only by the AWS account owner. However, in practice, queues are shared across services, roles, and sometimes even AWS accounts. Misconfigured permissions can lead to unauthorized message consumption, data leakage, message tampering, or denial-of-service through queue flooding. A defense-in-depth strategy combining IAM policies, resource-based policies, and network-level restrictions dramatically reduces your attack surface.
Understanding SQS Access Control Layers
SQS security operates at two policy layers that work together:
- Identity-based policies — Attached to IAM users, roles, or groups. They define what actions those identities can perform on which SQS resources.
- Resource-based policies — Attached directly to the SQS queue. They define which principals (including cross-account) can perform actions on that specific queue.
For an action to succeed, both the identity-based policy of the caller and the resource-based policy of the queue must allow the action (unless the caller and queue are in the same account, in which case a single explicit allow is sufficient).
Securing SQS with IAM Policies
Granting Least-Privilege Access to a Producer
A producer service only needs to send messages. Avoid granting sqs:* or broad sqs:SendMessage across all resources. Scope the action to a specific queue ARN:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowSendMessageToOrdersQueue",
"Effect": "Allow",
"Action": "sqs:SendMessage",
"Resource": "arn:aws:sqs:us-east-1:123456789012:orders-queue"
}
]
}
Granting Least-Privilege Access to a Consumer
A consumer needs to receive, delete, and optionally change message visibility. It should not be able to purge the queue or alter its attributes:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowConsumeFromOrdersQueue",
"Effect": "Allow",
"Action": [
"sqs:ReceiveMessage",
"sqs:DeleteMessage",
"sqs:ChangeMessageVisibility"
],
"Resource": "arn:aws:sqs:us-east-1:123456789012:orders-queue"
}
]
}
Using Condition Keys for Tighter Control
IAM condition keys let you constrain access further. For example, you can require that messages sent to a queue include specific attributes, or that requests originate from a specific VPC endpoint:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowSendOnlyFromVpce",
"Effect": "Allow",
"Action": "sqs:SendMessage",
"Resource": "arn:aws:sqs:us-east-1:123456789012:orders-queue",
"Condition": {
"StringEquals": {
"aws:sourceVpce": "vpce-1a2b3c4d5e6f7g8h9"
}
}
}
]
}
Other useful SQS-specific condition keys include sqs:MessageAttributeName, sqs:MessageGroupId, and aws:SourceArn (useful when an SNS topic or EventBridge rule is the only allowed publisher).
Restricting Publishers to a Known SNS Topic
If your queue subscribes to an SNS topic, you can ensure only that topic can publish to it using a resource-based policy with the aws:SourceArn condition:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowSNSTopicToPublish",
"Effect": "Allow",
"Principal": {
"Service": "sns.amazonaws.com"
},
"Action": "sqs:SendMessage",
"Resource": "arn:aws:sqs:us-east-1:123456789012:orders-queue",
"Condition": {
"ArnEquals": {
"aws:SourceArn": "arn:aws:sns:us-east-1:123456789012:orders-topic"
}
}
}
]
}
Cross-Account Access
To allow an IAM role in account B (e.g., 999999999999) to read from a queue in account A (123456789012), attach a resource-based policy to the queue:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowCrossAccountConsumer",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::999999999999:role/ConsumerRole"
},
"Action": [
"sqs:ReceiveMessage",
"sqs:DeleteMessage",
"sqs:GetQueueAttributes"
],
"Resource": "arn:aws:sqs:us-east-1:123456789012:orders-queue"
}
]
}
The role in account B must also have an identity-based policy granting the same actions on the queue ARN. Both sides must explicitly allow the access.
Network Security for SQS
IAM policies answer "who can do what," but they do not restrict the network path. By default, SQS endpoints are reachable over the public internet. To prevent traffic from traversing the public internet and to restrict access to specific networks, use VPC endpoints and endpoint policies.
Creating a VPC Endpoint for SQS
A VPC endpoint (PrivateLink) for SQS keeps traffic between your VPC and SQS entirely within the AWS network. The following AWS CLI command creates an interface endpoint for SQS:
aws ec2 create-vpc-endpoint \
--vpc-id vpc-0abc123def456 \
--service-name com.amazonaws.us-east-1.sqs \
--subnet-ids subnet-0aaa subnet-0bbb \
--security-group-ids sg-0123456789abcdef \
--vpc-endpoint-type Interface
Once created, you receive a set of regional DNS names (e.g., vpce-1a2b3c4d5e6f7g8h9-abc123.sqs.us-east-1.vpce.amazonaws.com) that resolve to private IP addresses within your VPC.
VPC Endpoint Policies
Every VPC endpoint can have an attached endpoint policy that controls which principals can use the endpoint and which queues they can access. This is a powerful network-level control. The following policy restricts the endpoint to a single queue and a single role:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "RestrictToOrdersQueue",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123456789012:role/ConsumerRole"
},
"Action": [
"sqs:ReceiveMessage",
"sqs:DeleteMessage",
"sqs:SendMessage"
],
"Resource": "arn:aws:sqs:us-east-1:123456789012:orders-queue"
}
]
}
Enforcing VPC-Only Access with IAM
To guarantee that no caller can reach your queue over the public internet, combine a VPC endpoint with an IAM policy that denies requests not coming through the endpoint. Use the aws:sourceVpce condition in a deny statement:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyIfNotFromVpce",
"Effect": "Deny",
"Principal": "*",
"Action": "sqs:*",
"Resource": "arn:aws:sqs:us-east-1:123456789012:orders-queue",
"Condition": {
"StringNotEquals": {
"aws:sourceVpce": "vpce-1a2b3c4d5e6f7g8h9"
}
}
}
]
}
Be careful: this deny applies to all principals, including AWS services that may need to publish to your queue (such as SNS or EventBridge). If you use such integrations, add explicit allow statements for those service principals before the deny, or scope the deny to specific IAM roles instead of "Principal": "*".
Restricting by VPC or IP Address
You can also restrict access based on the source VPC ID or source IP range. The following resource-based policy denies access unless the request originates from a specific VPC:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyOutsideTrustedVpc",
"Effect": "Deny",
"Principal": "*",
"Action": "sqs:*",
"Resource": "arn:aws:sqs:us-east-1:123456789012:orders-queue",
"Condition": {
"StringNotEquals": {
"aws:SourceVpc": "vpc-0abc123def456"
}
}
}
]
}
For IP-based restrictions, use aws:SourceIp with CIDR blocks. Note that aws:SourceIp is not effective when requests come through a VPC endpoint, because the source IP will be a private VPC address; in that case prefer aws:sourceVpce or aws:SourceVpc.
Server-Side Encryption (SSE) with KMS
While not strictly a network control, SSE-KMS complements network security by ensuring that messages at rest are encrypted and that only principals with kms:Decrypt and kms:GenerateDataKey permissions on the associated KMS key can read messages. Enable SSE on a queue with the CLI:
aws sqs set-queue-attributes \
--queue-url https://sqs.us-east-1.amazonaws.com/123456789012/orders-queue \
--attributes KmsMasterKeyId=alias/sqs/orders-key
Then scope the KMS key policy to only the producer and consumer roles. This adds another layer: even if an IAM principal somehow gains sqs:ReceiveMessage permission, they cannot decrypt the payload without KMS access.
Best Practices
- Apply least privilege. Grant only the specific SQS actions each role needs (e.g.,
SendMessagefor producers,ReceiveMessageandDeleteMessagefor consumers) and scope them to specific queue ARNs. - Use resource-based policies for cross-account and service integrations. They make the queue's access surface explicit and auditable.
- Prefer VPC endpoints over public internet access. This keeps traffic on the AWS network and enables endpoint policies as an additional control plane.
- Combine deny statements with
aws:sourceVpceoraws:SourceVpcto enforce that traffic must come from trusted networks. - Enable SSE-KMS on queues carrying sensitive data, and tightly scope the KMS key policy.
- Avoid wildcard principals. Never use
"Principal": "*"with"Action": "sqs:*"in an allow statement. If you must allow a service like SNS, scope it to a specific source ARN. - Separate queues by sensitivity. Instead of one queue for everything, use distinct queues with tailored policies so a compromise of one consumer cannot read unrelated messages.
- Monitor with CloudTrail and GuardDuty. SQS API calls are logged to CloudTrail. Watch for unexpected
PurgeQueue,DeleteMessagespikes, or access from unfamiliar IPs. - Tag your queues and use
aws:ResourceTagconditions in IAM policies to scale access management as your queue count grows. - Test policies with the IAM Policy Simulator before deploying, and validate cross-account access end-to-end in a non-production environment.
Conclusion
Securing SQS requires a layered approach: IAM identity-based policies define what each role can do, resource-based policies define who can touch a specific queue (including cross-account and service publishers), and network controls such as VPC endpoints and endpoint policies define where requests can come from. By combining least-privilege IAM grants, explicit deny rules tied to aws:sourceVpce or aws:SourceVpc, SSE-KMS encryption, and continuous monitoring through CloudTrail, you can ensure that your queues only accept traffic from trusted producers and only deliver messages to authorized consumers. Applying these controls consistently across every queue in your organization turns SQS from a convenient messaging primitive into a hardened, production-grade backbone for your distributed systems.