SQS QueuePolicy Self-Lockout
sqs-queue-policy-self-lockout
What this rule checks
Detects AWS::SQS::QueuePolicy resources containing a Deny statement on sqs:DeleteQueue, sqs:RemovePermission, sqs:*, or * with a broad Principal and no NotPrincipal or aws:PrincipalArn carveout for the account root or admin role. Such a policy locks the account out of its own queue โ recovery requires breaking glass on the account root credentials to remove the queue policy, or delete-and-recreate the queue if nothing else depends on its ARN. In event-driven systems that is often a multi-stack rebuild.
How to fix it
- 1Add a NotPrincipal exemption for the account root (arn:aws:iam::<account>:root) or admin role(s)
- 2Or use a Condition with StringNotEquals on aws:PrincipalArn to exempt admin role ARNs
- 3If the Deny is intended to scope to AWS services, use aws:PrincipalIsAWSService rather than a blanket Deny on Principal: '*'
import { aws_sqs as sqs, aws_iam as iam } from 'aws-cdk-lib';
const queue = new sqs.Queue(this, 'Queue');
queue.addToResourcePolicy(new iam.PolicyStatement({
sid: 'DenyAdmin',
effect: iam.Effect.DENY,
principals: [new iam.AnyPrincipal()],
actions: ['sqs:DeleteQueue', 'sqs:RemovePermission'],
resources: [queue.queueArn],
}));import { aws_sqs as sqs, aws_iam as iam } from 'aws-cdk-lib';
const queue = new sqs.Queue(this, 'Queue');
queue.addToResourcePolicy(new iam.PolicyStatement({
sid: 'DenyAdmin',
effect: iam.Effect.DENY,
notPrincipals: [new iam.AccountRootPrincipal()],
actions: ['sqs:DeleteQueue', 'sqs:RemovePermission'],
resources: [queue.queueArn],
}));CDK Insights pinpoints the exact file and line in your CDK source for every finding, so you can jump straight to the fix.
Affected resource types
AWS::SQS::QueuePolicyIntentional? Suppress this finding
Sometimes a flag is deliberate โ a genuinely public endpoint, say. You can dismiss sqs-queue-policy-self-lockout and the reason is kept in the report, not silently hidden.
In .cdk-insights.json:
{
"ignoreRules": [
{ "id": "sqs-queue-policy-self-lockout", "reason": "Why this is intentional" }
]
}Or inline in your CDK code:
Validations.of(scope).acknowledge({
id: 'cdk-insights::sqs-queue-policy-self-lockout',
reason: 'Why this is intentional',
});Use the rule ID sqs-queue-policy-self-lockout shown above โ not the CDK-* ID from SARIF / GitHub code scanning. To dismiss every finding on one construct instead, use ignorePaths. Suppression docs โ
Catch this in your stack
$ npx cdk-insights scanCDK Insights runs this and 118+ other rules locally against your synthesised CDK app โ free, no account, your code never leaves your machine.