Oftentimes as part of delivering a service, a vendor will request a role for cross-account access, in order to aggregate data or perform some actions in the customer’s account. However, beyond modifying an IAM policy to restrict access, customers don’t think much about auditing the use of these roles once live.
In this post in our series on querying CloudTrail with Athena, we take a look at how you can keep tabs on access patterns on assumed roles.
While a particular IAM privilege or role may seem innocuous by name (see ReadOnlyAccess
), there could be reason for concern in the nature, pattern or frequency of access to the customer account.
You may utilize a third-party SaaS solution that requires access to your AWS environment. However, if this role permits it, the provider may attempt to inspect or modify other resources in your environment.
For example, you may expect a vendor to inspect your EC2 instances with DescribeInstances
, but you may not expect them to generate an IAM Credential Report (iam:Generate*
is enabled on the AWS ReadOnlyAccess
policy).
We have heard plenty of stories from customers having reached service limits and being denied service in the AWS Console because a third-party role is busy aggregating data on a very high frequency.
Queries on some services have a direct impact on cost, with queries to CloudWatch and Cost Explorer two common sources of sudden spikes in cost when used carelessly.
To put it plainly, you must keep an eye on the usage of third-party roles for cross-account access for security, availability and cost reasons.
The good news is that using Athena with your CloudTrail is the answer, to retrieve all these answers and more.
Say you want to audit GorillaStack’s role for cross-account access:
-- remember, you can add account, region and day filters SELECT eventname, eventsource, eventtime, requestid, eventid, recipientaccountid, requestparameters FROM cloudtrail_logs WHERE year = '<year>' AND month = '<month>' AND useridentity.arn = '<insert your role here>';
SELECT useridentity, eventtime, requestid, eventid, recipientaccountid, requestparameters FROM cloudtrail_logs WHERE year = '<year>' AND month = '<month>' AND eventname = '<eventname (e.g. CreateUser)';
WITH dataset as (SELECT useridentity.arn as userArn, json_extract(requestparameters, '$.roleArn') AS roleArn FROM cloudtrail_logs WHERE year = '<year>' AND month = '<month>' AND eventname = 'AssumeRole' ) SELECT roleArn, userArn, count(userArn) as count FROM dataset GROUP BY roleArn, userArn ORDER BY count desc;
Note, this will show you all AssumeRole
requests, not just those performed by third parties. It should be easy enough to add to the query to filter our unwanted events.
We’re looking back through CloudTrail retrospectively, to catch mistakes or threats that occurred days, months, years in the past. If you are interested in catching these in real time and sending them to Slack, Jira, ServiceNow or a lambda function, check out our Real Time Events product.
Reach out to us on our public Slack channel to let us know what you think.