Understanding AWS IAM Trust Policies: How They Differ from Permission Policies and Work Together

Maxat AkbanovMaxat Akbanov
4 min read

A trust policy in AWS IAM (Identity and Access Management) is a JSON document associated with an IAM role that defines who or what (the principal) can assume the role.

Image credits: Unubold Tumenbayar

It acts as a security mechanism to specify the trusted entities allowed to use the role.

Image credits: https://aws.amazon.com/iam/getting-started

Key Elements of a Trust Policy

  1. Principal: Identifies the entities (users, roles, services, or accounts) allowed to assume the role.

    • Service Principals: AWS services like ec2.amazonaws.com or lambda.amazonaws.com.

    • Account Principals: AWS account IDs or cross-account roles.

    • Federated Principals: Identity providers (e.g., SAML or OpenID Connect).

  2. Action: Specifies the actions allowed. For trust policies, this is almost always sts:AssumeRole.

  3. Effect: Determines whether to allow or deny the action. Typically set to "Allow" for trust policies.

  4. Condition (Optional): Adds constraints, such as requiring MFA or allowing specific IP addresses.

When you create a trust policy, you cannot specify a wildcard (*) as part of and ARN in the principal element.

Example of a Trust Policy

1. Service Role Trust Policy

This trust policy allows the EC2 service to assume the role.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "ec2.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

2. Cross-Account Trust Policy

This policy allows a role from Account B (123456789012) to assume the role in Account A.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::123456789012:role/CrossAccountRole"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

3. Federated User Trust Policy

This policy allows users authenticated through an identity provider to assume the role.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "arn:aws:iam::123456789012:saml-provider/MyIdentityProvider"
      },
      "Action": "sts:AssumeRoleWithSAML"
    }
  ]
}

How Trust Policies Work

  • When an entity (e.g., a user, service, or another role) tries to assume a role, AWS evaluates the trust policy to confirm whether the entity is trusted to use the role.

  • If the trust policy grants access, AWS allows the entity to assume the role and provides temporary security credentials for performing actions from AWS Security Token Service (AWS STS).


Differences Between Trust Policies and Permission Policies

AspectTrust PolicyPermission Policy
PurposeDefines who can assume a role (trusted entities).Defines what actions the role can perform.
Key Actionsts:AssumeRole.Service-specific actions (e.g., s3:ListBucket).
Key PrincipalSpecifies trusted entities.Not directly related to who assumes the role.

Key Roles of Trust and Permission Policies

  1. Trust Policy:

    • Determines who can assume the role.

    • Defines the trusted entities (e.g., AWS services, accounts, or federated users) that are allowed to assume the role.

    • Does not grant permissions to perform specific actions on AWS resources.

  2. Permission Policy:

    • Specifies what actions the role can perform on AWS resources (e.g., s3:ListBucket or ec2:StartInstances).

    • Defines the permissions for the role after it is assumed.


How the Two Policies Work Together

When a role is assumed:

  1. Trust Policy: AWS checks if the entity trying to assume the role is trusted based on the trust policy.

  2. Permission Policy: Once the role is assumed, AWS uses the role's permission policy to determine what actions the role can perform.


Example of Insufficient Setup

Scenario:

You create a role with the following trust policy to allow EC2 instances to assume it:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "ec2.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

Without a permission policy, the role does not have permissions to perform any actions, even though EC2 can assume the role.


What Happens Without a Permission Policy?

  • The trusted entity (e.g., EC2 instance) can assume the role but will have no permissions to perform any actions on AWS resources.

  • AWS defaults to a deny-all policy for roles without a permission policy.


Complete Role Setup Example

Trust Policy (Who can assume the role):

Allows EC2 instances to assume the role:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "ec2.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

Permission Policy (What the role can do):

Grants access to list and read objects in an S3 bucket:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:ListBucket",
        "s3:GetObject"
      ],
      "Resource": [
        "arn:aws:s3:::example-bucket",
        "arn:aws:s3:::example-bucket/*"
      ]
    }
  ]
}

Image credits: Unubold Tumenbayar


Summary

A trust policy alone is not sufficient to perform actions. You need:

  1. A trust policy to define who can assume the role.

  2. A permission policy to define what actions the role can perform once assumed.

This two-layer system ensures that AWS maintains strict access control, requiring both trust and specific permissions for a role to be effective.

References

0
Subscribe to my newsletter

Read articles from Maxat Akbanov directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Maxat Akbanov
Maxat Akbanov

Hey, I'm a postgraduate in Cyber Security with practical experience in Software Engineering and DevOps Operations. The top player on TryHackMe platform, multilingual speaker (Kazakh, Russian, English, Spanish, and Turkish), curios person, bookworm, geek, sports lover, and just a good guy to speak with!