Skip to main content
Version: v2.1.3

AWS IAM Trust Policies and Permissions for Document Storage

Overview

This document explains how to set up AWS IAM trust policies and permissions for role assumption, specifically for AlphaSense's document storage service using chained assume role scenarios.

Workflow Diagram

Chained Assume Role Workflow

Trust Policies vs Permissions

Trust Policy

  • What: Defines WHO can assume a role
  • Where: Attached to the IAM role being assumed
  • Purpose: Controls access to the role itself

Permission Policy

  • What: Defines WHAT actions the principal can perform
  • Where: Attached to the user, group, or role making the assumption
  • Purpose: Controls what the principal can do (including assuming roles)

Setting Up Trust Policies

1. Basic Trust Policy for AlphaSense Document Storage

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::[AlphaSense-Account-ID]:role/document-storage-role"
},
"Action": "sts:AssumeRole"
}
]
}
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::[AlphaSense-Account-ID]:role/document-storage-role"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"sts:ExternalId": "unique-external-id-12345"
}
}
}
]
}

Setting Up Permission Policies

Chained Assume Role Setup for Document Storage

For the document storage service's chained assume role pattern:

Step 1: AlphaSense Service Role (Managed by AlphaSense)

The AlphaSense service role must have permission to assume client roles:

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::*:role/AlphaSense-DocumentStorage-ClientRole-*"
}
]
}

Step 2: Client Role Permissions (Customer Managed)

The client role in the customer's account needs permissions to access S3 and/or KMS:

For S3 (Bring Your Own Bucket):
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:RestoreObject",
"s3:ListBucket",
"s3:DeleteObject",
"s3:GetObjectVersion",
"s3:DeleteObjectVersion"
],
"Resource": [
"arn:aws:s3:::your-document-bucket",
"arn:aws:s3:::your-document-bucket/*"
]
}
]
}
For KMS Only Access (Bring Your Own Key):
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"kms:Encrypt",
"kms:Decrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:DescribeKey"
],
"Resource": "arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012"
}
]
}

Step 3: Client Role Trust Policy (Customer Managed)

The client role must trust the AlphaSense document-storage-role:

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::[AlphaSense-Account-ID]:role/document-storage-role"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"sts:ExternalId": "customer-specific-external-id-2024"
}
}
}
]
}

Step 4: Resource Policies (Customer Managed) - Optional

Update your S3 bucket and KMS key policies to allow access from your client role. This step is optional if there are no other policies denying access to your customer role:

S3 Bucket Policy (for Bring Your Own Bucket):
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::[Your-Account-ID]:role/[Your-Client-Role-Name]"
},
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:RestoreObject",
"s3:ListBucket",
"s3:DeleteObject"
],
"Resource": [
"arn:aws:s3:::your-document-bucket",
"arn:aws:s3:::your-document-bucket/*"
]
}
]
}
KMS Key Policy (for both scenarios):
{
"Sid": "Allow access through client role",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::[Your-Account-ID]:role/[Your-Client-Role-Name]"
},
"Action": [
"kms:Encrypt",
"kms:Decrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:DescribeKey"
],
"Resource": "*"
}

AWS CLI Commands

Create Role with Trust Policy

# Create the trust policy file
cat > trust-policy.json << EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::[AlphaSense-Account-ID]:role/document-storage-role"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"sts:ExternalId": "your-unique-external-id"
}
}
}
]
}
EOF

# Create the IAM role
aws iam create-role \
--role-name AlphaSense-DocumentStorage-ClientRole \
--assume-role-policy-document file://trust-policy.json

Create and Attach Permission Policy (Customer Step)

# Create permissions policy file for S3 and KMS access
cat > permissions-policy.json << EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:RestoreObject",
"s3:ListBucket",
"s3:DeleteObject",
"s3:GetObjectVersion",
"s3:DeleteObjectVersion"
],
"Resource": [
"arn:aws:s3:::your-document-bucket",
"arn:aws:s3:::your-document-bucket/*"
]
},
{
"Effect": "Allow",
"Action": [
"kms:Encrypt",
"kms:Decrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:DescribeKey"
],
"Resource": "arn:aws:kms:us-east-1:[Your-Account-ID]:key/[Your-KMS-Key-ID]"
}
]
}
EOF

# Create the policy
aws iam create-policy \
--policy-name AlphaSense-DocumentStorage-Policy \
--policy-document file://permissions-policy.json

# Attach the policy to the role
aws iam attach-role-policy \
--role-name AlphaSense-DocumentStorage-ClientRole \
--policy-arn arn:aws:iam::[Your-Account-ID]:policy/AlphaSense-DocumentStorage-Policy

Configure AlphaSense Service Role Permissions (AlphaSense Step)

# This is managed by AlphaSense - shown for reference only
# AlphaSense service role needs permission to assume client roles
cat > alphasense-service-policy.json << EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::*:role/AlphaSense-DocumentStorage-ClientRole-*"
}
]
}
EOF

Testing Role Assumption

Test with External ID

aws sts assume-role \
--role-arn arn:aws:iam::123456789012:role/AlphaSense-DocumentStorage-ClientRole \
--role-session-name test-session \
--external-id your-unique-external-id

Verify Current Identity

aws sts get-caller-identity

Common Issues and Solutions

1. "User is not authorized to perform: sts:AssumeRole"

  • Cause: Missing permission policy on the principal
  • Solution (AlphaSense): Add sts:AssumeRole permission to the AlphaSense service role's policy

2. "Access denied" with External ID

  • Cause: External ID mismatch or missing
  • Solution: Ensure external ID in request matches trust policy exactly

3. "Cross-account pass role is not allowed"

  • Cause: Missing trust relationship
  • Solution: Add the AlphaSense account to the trust policy

Best Practices

Security

  1. Always use External IDs for cross-account roles to prevent confused deputy attacks
  2. Implement least privilege - only grant necessary permissions
  3. Use conditions to restrict when/where roles can be assumed
  4. Monitor role usage with CloudTrail

Management

  1. Use descriptive role names that indicate purpose (e.g., AlphaSense-DocumentStorage-ClientRole)
  2. Tag roles for better organization and cost tracking
  3. Document role purposes and dependencies in role descriptions
  4. Regularly audit role usage and permissions

Example Configuration for AlphaSense Document Storage (AlphaSense Reference)

Based on a typical client configuration:

{
"chainedAssumeRole": "arn:aws:iam::CLIENT-ACCOUNT:role/AlphaSense-DocumentStorage-ClientRole",
"chainedAssumeRoleRegion": "us-east-1",
"chainedAssumeRoleExternalId": "client-unique-external-id-2024",
"s3BucketArn": "arn:aws:s3:::client-document-bucket",
"kmsKeyArn": "arn:aws:kms:us-east-1:CLIENT-ACCOUNT:key/12345678-1234-1234-1234-123456789012"
}

This requires:

  1. AlphaSense service role with permission to assume the client role
  2. Client role with trust policy allowing the AlphaSense service role
  3. External ID matching the configuration value
  4. Proper S3 and KMS permissions on the client role for the target resources

Troubleshooting Checklist

  • Trust policy allows the correct AlphaSense principal
  • Permission policy includes necessary S3 and KMS actions
  • External ID matches exactly (if used)
  • Role ARN is correct and exists
  • Account IDs are correct in all policies
  • Region is correct (if specified)
  • Principal has valid credentials
  • No conditional restrictions are blocking access
  • Role is not in a deleted state
  • S3 bucket policy allows the client role
  • KMS key policy allows the client role
  • CloudTrail logs show assume role attempts and outcomes