Skip to content

AWS IAM aws:PrincipalAccount vs. aws:SourceAccount

  • by

The 2 major confused conditions when writing a service control policy is whether to use aws:PrincipalAccount or aws:SourceAccount., Though they look similar, they are widely different from one another and using the wrong one can block access or make your existing resources in AWS vulnerable. Let us do a deep dive and understand in detail what is the difference between aws:PrincipalAccount and aws:SourceAccount

The Big Picture: What’s the Difference?

At its simplest, the distinction comes down to who is making the request.

  • aws:PrincipalAccount identifies the human or machine identity making the call. Think of this as the “who.” It refers to the AWS account of the IAM user or role that’s directly initiating the request.
  • aws:SourceAccount identifies the AWS service that is making the request on behalf of another account. Think of this as the “origin.” This is a security feature designed specifically to prevent a common security vulnerability known as the “confused deputy problem.”

Let’s dive a little deeper with a clear comparison.

aws:PrincipalAccount vs. aws:SourceAccount

Featureaws:PrincipalAccountaws:SourceAccount
FocusThe identity (user, role) making the request.The service making the request on behalf of a specific account.
Use CaseGranting a principal from a specific account access to resources in a different account.Securing resources that are accessed by other AWS services to prevent a “confused deputy” from exploiting them.
Common ScenariosCross-account access to S3 buckets, SNS topics, or assuming an IAM role in a different account.Protecting Lambda functions, SQS queues, or SNS topics from being invoked or written to by a malicious service call.

Export to Sheets


Real-World Use Cases Explained

Scenario 1: Cross-Account Access with aws:PrincipalAccount

Imagine your organization has two AWS accounts: a Dev Account (111122223333) and a Prod Account (444455556666). A developer in the Dev Account needs to read data from an S3 bucket in the Prod Account.

To make this happen securely, you would attach a resource-based policy to the S3 bucket in the Prod Account that looks like this:

JSON

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowDevAccountAccess",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::111122223333:root"
      },
      "Action": [
        "s3:GetObject"
      ],
      "Resource": "arn:aws:s3:::prod-app-data/*"
    }
  ]
}

In this policy, the Principal element and the aws:PrincipalAccount context key (implicitly included in the Principal ARN) ensures that only an identity originating from the Dev Account is allowed to perform s3:GetObject on the bucket. This is all about controlling the “who.”

Scenario 2: Preventing the Confused Deputy with aws:SourceAccount

Now, let’s consider a classic security challenge. You have an SQS queue in your Prod Account (444455556666) that is used to trigger a workflow whenever a new file is uploaded to an S3 bucket in the same account.

An attacker could try to exploit this by sending a message directly to your SQS queue, tricking it into thinking it’s a legitimate file upload event.

To prevent this, you use aws:SourceAccount in your SQS queue policy to ensure that the request comes from the S3 service acting on behalf of your trusted account.

JSON

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowS3ToSendMessage",
      "Effect": "Allow",
      "Principal": {
        "Service": "s3.amazonaws.com"
      },
      "Action": "sqs:SendMessage",
      "Resource": "arn:aws:sqs:us-east-1:444455556666:MyQueue",
      "Condition": {
        "StringEquals": {
          "aws:SourceAccount": "444455556666"
        },
        "ArnLike": {
          "aws:SourceArn": "arn:aws:s3:::MyTrustedBucket"
        }
      }
    }
  ]
}

In this case, the aws:SourceAccount condition explicitly allows the S3 service ("Principal": {"Service": "s3.amazonaws.com"}) to send messages, but only if the request originated from the trusted account 444455556666. The request is denied if it came from any other account, even if it’s sent via the S3 service.

Summary:

The distinction is clear:

  • aws:PrincipalAccount is for managing access based on the identity’s home account.
  • aws:SourceAccount is for securing service-to-service communication by validating the origin account.

In Most SCPs, we may need to use aws:PrincipalAccount rather than aws:SourceAccount (The condition key aws:SourceAccount will be used rarely)

Tags:

Leave a Reply

Your email address will not be published. Required fields are marked *