SQS IAM Queue Access Policy: Restrict Who Can Read

SQS policies are not just for granting permissions; they are the gatekeepers, and you’re likely here because an IAM principal (a user, role, or service) is being denied access to an SQS queue, and you need to figure out why and fix it. This isn’t about what SQS does, but about the IAM rules that are preventing a legitimate action from succeeding.

Here’s a breakdown of common reasons for SQS access denial and how to fix them:

1. Explicit Deny in the Queue Policy: This is the most common culprit. An explicit Deny statement in the queue’s resource-based policy overrides any Allow statements, even from IAM user/role policies.

  • Diagnosis: Examine the Resource policy attached directly to your SQS queue. Look for any Deny statements that apply to the principal attempting to access the queue. You can find this in the AWS console under the SQS queue’s "Access policy" tab, or via the AWS CLI:
    aws sqs get-queue-attributes --queue-url <YOUR_QUEUE_URL> --attribute-names All
    
    Then, parse the Policy attribute in the output.
  • Fix: Remove or modify the Deny statement. For example, if you have:
    {
      "Version": "2012-10-17",
      "Id": "QueuePolicy",
      "Statement": [
        {
          "Sid": "DenyUnencrypted",
          "Effect": "Deny",
          "Principal": "*",
          "Action": "sqs:*",
          "Resource": "arn:aws:sqs:us-east-1:123456789012:my-queue",
          "Condition": {
            "Bool": {
              "aws:SecureTransport": "false"
            }
          }
        }
      ]
    }
    
    And you want to allow access over HTTP (not recommended for production), you’d remove this Deny. If the Deny is too broad, refine its Principal or Condition elements.
  • Why it works: IAM evaluates policies in a specific order. Explicit Deny statements are always evaluated first. If a Deny matches, access is denied immediately, regardless of any Allow statements.

2. Missing Allow in the Queue Policy: If the queue policy doesn’t explicitly Allow the principal to perform the action, and there’s no Allow in the principal’s identity-based policy (user/role policy) that’s being overridden by a Deny in the queue policy, access will be denied. Remember, SQS requires an explicit Allow in the queue policy for cross-account access or when the principal’s identity policy doesn’t cover the SQS action.

  • Diagnosis: Check the queue policy for an Allow statement that grants the specific action (e.g., sqs:ReceiveMessage, sqs:DeleteMessage) to the principal’s ARN.
    aws sqs get-queue-attributes --queue-url <YOUR_QUEUE_URL> --attribute-names All
    
    Look for a statement with "Effect": "Allow", "Principal": {"AWS": "<PRINCIPAL_ARN>"} (or a service principal like {"Service": "lambda.amazonaws.com"}), and the relevant "Action".
  • Fix: Add an Allow statement to the queue policy. For a Lambda function to poll a queue:
    {
      "Version": "2012-10-17",
      "Id": "QueuePolicy",
      "Statement": [
        {
          "Sid": "AllowLambdaRead",
          "Effect": "Allow",
          "Principal": {
            "Service": "lambda.amazonaws.com"
          },
          "Action": [
            "sqs:ReceiveMessage",
            "sqs:DeleteMessage",
            "sqs:GetQueueAttributes"
          ],
          "Resource": "arn:aws:sqs:us-east-1:123456789012:my-queue"
        }
      ]
    }
    
    If it’s a cross-account IAM role, replace "Service": "lambda.amazonaws.com" with "AWS": "arn:aws:iam::ACCOUNT_ID:role/ROLE_NAME".
  • Why it works: Resource-based policies (like SQS queue policies) are evaluated in conjunction with identity-based policies. For an action to be allowed, it must be allowed by both the resource policy and the identity policy (or at least not explicitly denied by either). An explicit Allow in the queue policy satisfies the resource policy requirement.

3. Incorrect Principal ARN in the Queue Policy: Typos or incorrect ARNs in the Principal element of the queue policy are frequent errors.

  • Diagnosis: Double-check the ARN of the user, role, or service principal in the Principal element of the queue policy against the actual ARN of the entity trying to access the queue. Use the AWS console or CLI (aws iam get-role, aws sts get-caller-identity) to verify ARNs.
  • Fix: Correct the ARN in the Principal element of the queue policy. Ensure it precisely matches the target principal. For example, if the role ARN is arn:aws:iam::111122223333:role/MyProcessorRole, ensure the policy has:
    "Principal": {
      "AWS": "arn:aws:iam::111122223333:role/MyProcessorRole"
    }
    
  • Why it works: The Principal element specifies who is allowed or denied. An incorrect ARN means the policy is effectively not targeting the intended principal, leading to implicit denial.

4. Incorrect Action Specified in the Queue Policy: The Action element must precisely match the SQS API operation being attempted.

  • Diagnosis: Review the Action list in the queue policy. Compare it against the specific SQS API calls your application or service is making (e.g., ReceiveMessage, DeleteMessage, SendMessage, PurgeQueue). You can often see the API calls in CloudTrail logs.
  • Fix: Add or correct the required actions in the Action list. If you need to receive and delete messages, ensure both are present:
    "Action": [
      "sqs:ReceiveMessage",
      "sqs:DeleteMessage"
    ]
    
    Using wildcards like sqs:* is convenient but less secure. Be specific.
  • Why it works: IAM policies are granular. The Action element dictates which specific API calls are permitted or denied. Mismatched actions mean the policy doesn’t authorize the operation being requested.

5. IAM Policy Evaluation Logic (Implicit Deny): If no explicit Allow statement in any applicable policy (queue policy or identity policy) covers the action, access is implicitly denied.

  • Diagnosis: Confirm that there is no Deny statement blocking the action. Then, verify that an Allow statement exists in either the queue policy or the principal’s IAM role/user policy that grants the specific SQS action. For cross-account access or when SQS needs to explicitly grant access to another account’s principal, the queue policy must have the Allow.
  • Fix: Add a suitable Allow statement to the relevant policy. If an IAM user/role is attempting to access a queue in the same account, their identity-based policy might be sufficient if the queue policy doesn’t have a conflicting Deny. However, for cross-account or service access (like Lambda), the queue policy is critical for the Allow.
  • Why it works: IAM operates on a principle of least privilege. If an action isn’t explicitly permitted by an Allow statement and isn’t explicitly denied by a Deny statement, it defaults to being denied.

6. Incorrect Resource ARN in the Queue Policy: The Resource element in the queue policy must accurately reflect the ARN of the SQS queue being accessed.

  • Diagnosis: Verify the Resource ARN in the queue policy matches the ARN of the queue your principal is trying to interact with. Check region, account ID, and queue name.
  • Fix: Correct the Resource ARN in the queue policy. For example, ensure it’s arn:aws:sqs:us-east-1:123456789012:my-queue and not arn:aws:sqs:us-west-2:123456789012:my-queue or arn:aws:sqs:us-east-1:987654321098:my-queue.
  • Why it works: The Resource element scopes the policy’s effect. If the Resource ARN doesn’t match the target queue, the policy statement will not apply to that queue.

7. VPC Endpoint Policies: If you are accessing SQS via a VPC endpoint, the VPC endpoint policy can also restrict access.

  • Diagnosis: Check the VPC endpoint policy attached to the SQS VPC endpoint. Look for Deny statements that might be blocking access to your specific queue ARN or actions.
  • Fix: Modify the VPC endpoint policy to allow the necessary actions and resources, or remove any conflicting Deny statements.
  • Why it works: VPC endpoint policies are evaluated alongside IAM policies. A Deny in the endpoint policy will block access before it even reaches the SQS service itself.

After addressing these, the next error you might encounter is related to KMS permissions if your queue is encrypted, or potentially a throttling error if you’ve fixed an access issue but are now hitting service limits.

Want structured learning?

Take the full Sqs course →