Proactive Cloud Security w/ AWS Organizations

Rob Witoff
4 min readDec 5, 2016

If you’re like me and heavily invested in security around AWS, you’ve likely been keeping tabs on last week’s re:Invent conference and the security updates hidden within. Security services didn’t play as big a role as I was hoping in the keynotes but the public announcement of AWS Organizations and their cross-account constraints are the biggest news for proactive security in AWS this year.

Of the 38 talks under the Security Compliance & Service tracks this year, there was a heavy focus on defining standards, auditing & automation. Some of the highlights were:

These talks made heavy references to newer auditing services like CloudWatch Events, Config and CloudTrail to monitor the state of our account and rapidly¹ remediating any deviations. These are indispensable resources to reactively tell us when something bad with is happening and it’s also critical for us to proactively defend our environments.

Independent Monitoring is a core Reactive Security Measure

Proactive defense is paramount in cloud where automation allows an attacker to move faster than ever. In our world where humans are increasingly vulnerable it’s a good assumption that credentials will eventually leak and having privileged credentials for even a few seconds can be all a sophisticated attacker needs.

Over the past few years I’ve had the privilege of working on large cloud incidents and it’s not uncommon for adversaries to execute cloudtrail:StopLogging or ec2:DeleteFlowLogs once keys have been leaked and before an attack has commenced. Further, there are extremely powerful API calls like ec2:DeleteVpc or ec2:DeleteSubnet that you never want to see run in production without some offline planning first. We’d really like to inject some offline friction before any of these command are ever run.

One recommend way of protecting against these failure modes that was discussed at re:Invent is to Reduce Blast Radius by Using Multiple AWS Accounts. The latency and lack of rate-limiting granularity in AWS today makes it difficult to otherwise protect against these powerful API calls within a single account before damage is done:

¹Logging Service Latency & Coverage

Usability & Least Privilege (Escalation)

Today, I make heavy use of IAM Conditions and Resource constraints to proactively defend access on roles and their corresponding sessions to my clouds. These can be pushed surprisingly far, for example:

Constraining roles to a single network block, useful after you’ve assigned a block to your egress NATs:

{
"Effect": "Allow",
"Action": "ec2:RunInstance"
"Resource": "*",
"Condition": {
"IpAddress": { "aws:SourceIp": "1.2.3.4/28" }
}
}

Constraining AMIs that can be launched:

{
"Action": "ec2:*",
"Resource": "arn:aws:ec2:us-east-1::image/*",
"Effect": "Allow",
"Condition" : {
"ForAnyValue:StringEquals": {
"ec2:Owner": ["amazon", "MY_ACCOUNT_ID"]
}
}
},

Or even using IAM variables to balance security & usability by namespacing access within IAM per our Self-Service IAM model:

{
"Effect": "Allow",
"Action": "iam:CreateUser",
"Resource": "arn:aws:iam::ACCOUNT_ID:user/${aws:username}-*"
}

Where these conditions unfortunately break down is in one command: iam:PutPolicy. Until now, the ability to maintain tight least-privilege with custom policies meant that your deployment process needed the ability to PutPolicy which introduced a single point of failure that could unconditionally escalate privileges.

Introducing Organizational Controls

We’ve been waiting for the ability to balance security and productivity with the following three requests, and with Organizations we can finally make that happen:

  1. Allow privileged online users the ability to create custom policies and maintain least privilege.
  2. Proactively defending against unnecessarily dangerous API requests with global Deny commands
  3. Restricting privileged access to offline keys.

AWS Organizations introduces a tier above IAM Admin access for the first time with Organizational Control Policies or OCPs. Until now, privileged users in AWS could unconditionally escalate their permissions. With AWS organizations, here’s how we’ll be protecting our accounts:

Authz is Constrained by |Account ∩ Org| Policies
  • Offline Master Account: Following traditional best practice, our root account will only be accessible with offline physical MFA tokens that are locked in a secure place that no single person has access to. Any usage of these keys will be done through a hardened, single-purpose notebook that best secures the root of our cloud.
Account Hierachy in AWS Organizations via
  • Judicious Organizational Control Policy: Our Production OCP restricts rare actions that we deem sensitive. Noting that OCPs don’t currently support customConditions or Resources, here’s a short securiy OCP that I’d recommend today and you can find more detailed OCPs here:
{
"Effect": "Deny",
"Resource": "*",
"Action": [
"ec2:DeleteFlowLogs",
"ec2:DeleteSubnet",
"ec2:DeleteVpc",
"rds:DeleteDBCluster",
"redshift:DeleteCluster",
"cloudtrail:DeleteTrail",
"cloudtrail:StopLogging",
"cloudtrail:UpdateTrail",
"config:DeleteDeliveryChannel",
"config:StopConfigurationRecorder",
"events:DeleteRule",
"events:DisableRule"
]
}

Closing Thoughts

Though not presented directly as a security product, AWS Organizations provides a novel capability within AWS to balance security and productive. I’m a strong believer that security done right helps all of us move faster, not slower and this is a good example of just that!

--

--