Skip to content

Authorization: a refused role session is named with an arn:aws:iam:: ARN, and a session policy refusal is reported as an identity-based policy refusal #817

Open

Description

@LeeroyHannigan

When a request from a role session is refused, the service names the caller with its AWS Security Token Service (STS) ARN, arn:aws:sts::<account>:assumed-role/<role>/<session>, and names the kind of policy that refused it: because no session policy allows the <action> action when the session policy has no Allow, and with an explicit deny in a session policy when it denies the action. ExtendDB names the caller arn:aws:iam::<account>:assumed-role/<role>/<session> and always reports an identity-based policy, so a session policy refusal reads as because no identity-based policy allows or with an explicit deny in an identity-based policy. Condition evaluation already uses the STS ARN as aws:PrincipalArn; the message builds a second ARN of its own.

Measured against Amazon DynamoDB in us-east-1 on 3 November 2026, one request per row, in sessions of a role whose identity policy allows the action on the table, except where a row says otherwise; the session policy rows narrow the session with an inline session policy. The service rows were measured with the PartiQL actions, and their texts have the same form for all four of them. ExtendDB answers are from main eaf16e89e (SQLite, debug build) with GetItem, since main has no PartiQL, in sessions created through the management API's assume-role endpoint. Account ids, role and session names are shown as placeholders.

Request DynamoDB ExtendDB main eaf16e89e (SQLite)
the identity policy has no Allow for the action (a table outside it) User: arn:aws:sts::<account>:assumed-role/<role>/<session> is not authorized to perform: dynamodb:PartiQLSelect on resource: arn:aws:dynamodb:us-east-1:<account>:table/<table> because no identity-based policy allows the dynamodb:PartiQLSelect action User: arn:aws:iam::<account>:assumed-role/<role>/<session> is not authorized to perform: dynamodb:GetItem on resource: arn:aws:dynamodb:us-east-1:<account>:table/<table> because no identity-based policy allows the dynamodb:GetItem action
the identity policy denies the action User: arn:aws:sts::... with an explicit deny in an identity-based policy User: arn:aws:iam::... with an explicit deny in an identity-based policy
the session policy has no Allow for the action User: arn:aws:sts::... because no session policy allows the dynamodb:PartiQLInsert action User: arn:aws:iam::... because no identity-based policy allows the dynamodb:GetItem action
the session policy denies the action User: arn:aws:sts::... with an explicit deny in a session policy User: arn:aws:iam::... with an explicit deny in an identity-based policy

Every answer is an AccessDeniedException. A refusal of an AWS Identity and Access Management (IAM) user names arn:aws:iam::<account>:user/<name> and is not part of this issue.

Where the answer comes from

crates/server/src/authorization.rs on main 74c03690e, check_role_authorization. Line 205 sets the STS ARN as principal_arn for condition evaluation. When the decision is a Deny, lines 248 and 254 build the principal for the message as arn:aws:iam::{account_id}:assumed-role/{role_name}/{session_name}, and deny_message (line 283) has two texts, both naming an identity-based policy (lines 293 and 295). The explicit flag it receives comes from explicit_deny_matches_arc (crates/auth/src/policy/evaluator.rs, line 86), which says whether any Deny statement matched in the identity policies, the permissions boundary or the session policy, and not which of them. evaluate_policies_arc in the same file reaches its Deny in a known phase (explicit Deny, permissions boundary, session policy, no Allow), and choosing the service's text needs that phase.

Not measured

The same refusals for a classic action such as dynamodb:GetItem on the service; a refusal by a permissions boundary on either side; a Deny that matches in both an identity policy and the session policy.

Related

#509 (merged on 4 November) added a helper that writes the STS ARN for a role session, for the refusals of cross-account requests in crates/server/src/authz_resource/cross_account.rs, and kept check_role_authorization's message as it is. #531 adds table name and ARN checks ahead of authorization in authorize_request and does not change this text. #411's PartiQL statements report their refusals through deny_message, so they give the ExtendDB text above.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions