Skip to main content

An IAM Permissions Boundary Fails to Block Decrypt Access Granted by a KMS Key Policy

High severityAmazon Web Services About 20 minutes to fixGenerated 11 Aug 2026

Overview

For cross-account KMS decrypt, AWS requires both the key policy and the role's identity-based policies, as limited by its permissions boundary, to allow the call. A boundary fails to block decrypt only when it is not actually account-scoped.

At a glance

Symptom
A workload assumes an IAM role carrying an explicit permissions boundary intended to cap the role to a single AWS account's resources.
Likely cause
An IAM permissions boundary is a managed or inline policy that limits the maximum permissions an identity-based policy can grant to the IAM entity…
Impact
The immediate impact is that a role believed to be contained to one account can read encrypted data protected by a key in another account, undermining the isolation…
Verification signal
Validation must confirm the specific unwanted grant is gone without breaking legitimate same-account decrypt operations that depend on the key.
Safe correction
The fix is not to modify the permissions boundary, which is already working exactly as designed; it targets the key policy that grants the unintended access.
Rollback or recovery
If removing the cross-account principal breaks a dependency that was not fully mapped, restore the exact prior key policy captured during diagnosis rather than improvising a new one.

Symptom

A workload assumes an IAM role carrying an explicit permissions boundary intended to cap the role to a single AWS account’s resources. Despite the boundary, the role successfully calls kms:Decrypt against a customer-managed KMS key that lives in a second, unrelated AWS account. CloudTrail records the call as successful, with no errorCode, and no access-denied event appears for the role. Nothing about the role’s own identity-based policies was changed before the access appeared.

False Assumption

The team that attached the permissions boundary assumed it would cap every permission the role could ever exercise, from any source, because that is how boundaries are commonly described in informal terms: as a hard ceiling on the role. On that assumption, the boundary was treated as limiting the role to one account’s resources, and nobody audited what its KMS statement actually allowed or which resource-based policies in other accounts named the role.

Root Cause

An IAM permissions boundary is a managed policy that sets the maximum permissions an identity-based policy can grant to the IAM entity it is attached to. For a cross-account request such as this one, AWS runs two evaluations and allows the request only if both allow it: the role’s own account evaluates its identity-based policies together with any permissions boundary and SCPs, and the key’s account evaluates the KMS key policy. A boundary that genuinely restricts kms:Decrypt to the home account’s key ARNs therefore does block a grant in another account’s key policy. In this trap it did not: the boundary’s KMS statement, copied from a template, allowed kms:Decrypt on "Resource": "*", the role’s identity-based policy did the same, and the key policy in the other account named the role’s ARN as a principal, so both evaluations returned Allow. The boundary was working as written; it was never account-scoped for KMS. The case where a resource-based policy really does bypass a boundary is narrower: within a single account, a policy that names an IAM role session ARN (rather than the role ARN) grants permissions directly to that session, and an implicit deny in the boundary does not limit them.

Impact

The immediate impact is that a role believed to be contained to one account can read encrypted data protected by a key in another account, undermining the isolation the boundary was meant to enforce. Because the access is technically authorised by two independent, correctly evaluated policies, no policy-evaluation error or explicit deny is generated, so the exposure is unlikely to surface through routine access-denied alerting. The blast radius depends on what the key protects; where the key wraps sensitive data such as customer records or credentials, this qualifies as a high-severity identity boundary failure even though every individual policy statement is syntactically valid.

Diagnosis

Confirm the mechanism before changing anything. First, retrieve the role’s attached policies and boundary to confirm what the boundary actually restricts.

Correction

Fix both sides: scope the boundary’s KMS statements to the key ARNs in the role’s own account, so it really caps cross-account use, and remove the role from the other account’s key policy if that access was never intended.

Validation

Validation must confirm the specific unwanted grant is gone without breaking legitimate same-account decrypt operations that depend on the key.

Rollback

If removing the cross-account principal breaks a dependency that was not fully mapped, restore the exact prior key policy, or the prior boundary policy version, captured during diagnosis rather than improvising a new one.

Prevention

Treat permissions boundaries and resource-based policies as two independent control planes that must both be reviewed, not one substituting for the other. Maintain an inventory of resource-based policies (KMS key policies, S3 bucket policies, SNS/SQS policies, Secrets Manager resource policies) that name cross-account or wildcard principals, and review it whenever a boundary is introduced or a role’s scope changes. Where an organisation-wide backstop is needed regardless of individual resource policies, use an AWS Organizations service control policy, which does apply across accounts, rather than relying solely on a per-role permissions boundary to achieve that effect.

3

Apply the safer control

Before you change production

Confirm the affected scope, export the current configuration, and test the replacement control in a non-production environment first.

Fix commands and configuration

kms:Decrypt
errorCode
"Resource": "*"
4

Verify, roll back or escalate

Verify

Validation must confirm the specific unwanted grant is gone without breaking legitimate same-account decrypt operations that depend on the key.

Rollback

If removing the cross-account principal breaks a dependency that was not fully mapped, restore the exact prior key policy captured during diagnosis rather than improvising a new one.

Escalate

Escalate when the blast radius is uncertain, the control cannot be tested safely, or remediation requires an outage or security exception.

The KBY Brief

Fixed? Get the next one before it hits you: The KBY Brief

Practical fixes for the systems you run, by email about twice a week. Unsubscribe at any time.

About this page

Dates

Published

Last updated

Corrections

No corrections are listed for this page. Some review sweeps corrected pages without naming each one; those are in the corrections log.

Was this useful?

Reports go to the site owner and are used to correct pages. Corrections are listed at /corrections.

After remediation

Further reading stays below the corrective workflow and is selected by platform, category and shared technical keywords.

Discover more

Connected KBY resources