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
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"
}
]
}
2. Trust Policy with External ID (Recommended)
{
"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
- Always use External IDs for cross-account roles to prevent confused deputy attacks
- Implement least privilege - only grant necessary permissions
- Use conditions to restrict when/where roles can be assumed
- Monitor role usage with CloudTrail
Management
- Use descriptive role names that indicate purpose (e.g.,
AlphaSense-DocumentStorage-ClientRole
) - Tag roles for better organization and cost tracking
- Document role purposes and dependencies in role descriptions
- 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:
- AlphaSense service role with permission to assume the client role
- Client role with trust policy allowing the AlphaSense service role
- External ID matching the configuration value
- 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