How IAM Roles Become Credentials on EC2
While investigating how to secure S3 buckets using IAM Roles, I was curious how the IAM Role assigned to my EC2 instance became the credentials an AWS based application could use. IAM Roles for EC2 are the recommended practices, but how they worked was “magic” to me.
First, I created an IAM Role with a policy that allowed Get, Put, and Delete access to my S3 bucket.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1471042403000",
"Effect": "Allow",
"Action": [
"s3:DeleteObject",
"s3:GetObject",
"s3:PutObject"
],
"Resource": [
"arn:aws:s3:::kjh-encryption-test1/*"
]
}
]
}
Then, I created an EC2 instance and assigned that IAM role:
I connected to my instance over SSH…
$ ssh -i kjh-tax-sandbox.pem ec2-user@54.200.155.114
…and on that instance, I followed the instruction from IAM Roles for Amazon EC2 - Amazon Elastic Compute Cloud to get the credentials the same way the AWS SDK does:
$ curl http://169.254.169.254/latest/meta-data/iam/security-credentials/kjh-s3-encryption-test1-role
{
"Code" : "Success",
"LastUpdated" : "2016-08-13T16:36:13Z",
"Type" : "AWS-HMAC",
"AccessKeyId" : "ASIAJ27C6XNOZEXAMPLE",
"SecretAccessKey" : "rrGyOOa3TPLJQIIedUfW5hbCzPXb+EXAMPLEKEY",
"Token" : "TOKEN",
"Expiration" : "2016-08-13T23:09:05Z"
}
For a test, I edited my local .aws/credentials
to add a new profile to match that ec2role
[ec2role]
aws_access_key_id = ASIAJ27C6XNOZEXAMPLE
aws_secret_access_key = rrGyOOa3TPLJQIIedUfW5hbCzPXb+EXAMPLEKEY
aws_session_token = TOKEN
Then, from my local machine, I did an upload using the AWS CLI S3 command and specifying that new ec2role
profile.
$ aws --profile ec2role s3 cp quickbrownfox.txt s3://kjh-encryption-test1/cli-s3-sse/ --sse
upload: ./quickbrownfox.txt to s3://kjh-encryption-test1/cli-s3-sse/quickbrownfox.txt
Back on the EC2 instance, I downloaded that same file, but using the default profile
$ aws s3 cp s3://kjh-encryption-test1/cli-s3-sse/quickbrownfox.txt quickbrownfox.txt
download: s3://kjh-encryption-test1/cli-s3-sse/quickbrownfox.txt to ./quickbrownfox.txt
Everything worked as expected. AWS took care of supplying IAM credentials to an EC2 instance in a way the AWS SDK could find them. However, since I had root access via SSH, it was also easy for me to “steal” my own credentials and access that S3 bucket from outside the VPC. For protecting customer data stored in S3, additional controls like VPC Endpoints or Using Server-Side Encryption with Customer-Provided Encryption Keys (SSE-C) should be considered.