The SecOps Cheat Guide

AquaSec: Why doth thou torment me so??

I recently noticed that I needed to update the CloudFormation Stacks in our accounts that are responsible for the IAM AssumeRoles linked to our Aqua CSPM account. OK, so it was actually the 400+ "UNKNOWN" errors in each account that prompted me, but still.

This wouldn't be so bad, but Aqua CSPM (nee CloudSploit) predates the MultiAccount design fad, and really doesn't support it. The problem is the "External ID" that is required in the Role that is used to tell the system what account they are interacting with (why not use the AWS account number, since it never changes, and you give it to them to tell them which darned role to use in the first place? Who knows.) Best you can do is bulk upload INTO Aqua, with no real support for the AWS side. And if you do this, every time there is an update you still have to manually touch EVERY account to update that darned External ID. Or, I guess you can delete every account from Aqua, every IAM role your old stackset created, and re-do the whole bulk upload process (because, hey, who needs to keep historical results for compliance audits?)

So, once I got done cussing them out through my monitor, I got stuck in. Aqua provides a CFT in a public S3 bucket, so it's really a copy/paste operation (except they removed the ability to copy the NEW EXTERNAL ID, so you are forced type out the 32 character hexadecimal value.)FUUUUUUUuuuuuuUUUuuUuUUUUuuUUUUUUUUuuuuu...

OK, calm down dude. Don't be mad on the internet. WHooooooSahhhhhhhhhhhhh

A few days later, the work is done. I could have done this in probably a full day, but who has the bandwidth (and brain power) to do that?? New reports come in, and I am still seeing 300+ UNKNOWNs. Double you Tea Eff? Further inspection shows Aqua had not updated their template (and as of today, still has not) to include several new AWS services. Thankfully AWS has made it easy to see what perms are now needed, and I was able to update their CFT for them (where do I send the bill?). To save you the time and headache, here it is.

HOPEFULLY this will be deprecated soon as Aqua gets their act together and updates their template. I would assume that if this post is >6 months old, you are better off using whatever version they are now providing (but, we will see...)

{
	"AWSTemplateFormatVersion" : "2010-09-09",

	"Description" : "CloudSploit security scans cross-account role",

	"Parameters" : {
		"ExternalId" : {
			"Type"					: "String",
			"Description"			: "The external ID auto-generated from the CloudSploit dashboard. Copy this from the Add Account section.",
			"AllowedPattern"		: "[-a-z0-9]*",
			"ConstraintDescription"	: "Must be lowercase or numbers, no spaces, dashes ok."
		}
	},

	"Resources" : {
		"CloudSploitRole" : {
			"Type": "AWS::IAM::Role",
			"Properties" : {
				"AssumeRolePolicyDocument": {
					"Statement": [
						{
							"Effect": "Allow",
							"Principal": {
								"AWS": "arn:aws:iam::057012691312:root"
							},
							"Action": "sts:AssumeRole",
							"Condition": {
								"StringEquals": {
									"sts:ExternalId": { "Ref" : "ExternalId" }
								}
							}
						}
					]
				},
				"Policies": [
					{
						"PolicyName": "cloudsploit-supplemental-policy",
						"PolicyDocument": {
							"Version" : "2012-10-17",
							"Statement": [
								{
									"Effect": "Allow",
									"Action": [
										"athena:GetWorkGroup",
										"cloudwatchlogs:DescribeLogGroups",
										"cloudwatchlogs:DescribeMetricFilters",
										"efs:DescribeFileSystems",
										"elastictranscoder:ListPipelines",
										"ses:DescribeActiveReceiptRuleSet",
										"es:GetMetricStatistics",
										"ssm:GetServiceSetting",
										"codeartifact:ListDomains",
										"kms:DescribeKey",
										"auditmanager:GetSettings",
										"backup:ListBackupVaults"
									],
									"Resource": "*"
								}
							]
						}
					}
				],
				"ManagedPolicyArns": [
					"arn:aws:iam::aws:policy/SecurityAudit"
				]
			}
		}
	},

	"Outputs" : {
		"CloudSploitRoleArn" : {
			"Description" 	: "The role ARN of the cross-account user. Copy this into CloudSploit.",
			"Value"			: {"Fn::GetAtt" : ["CloudSploitRole", "Arn"] }
		}
	}
}