Limited permissions for AWS users and groups

At work, we're having additional research groups starting to leverage our AWS account (of which I've been the sole user to date) so was looking for a way to minimize the amount of accidental interference one group could run on another group's instances. At some point we might switch to using dedicated accounts, but in the meantime, it seems limiting which instances groups can access by using dedicated SSH keys and AWS Identity and Access Management policies seems like it might get the job done.

Fired up the AWS Management Console, went to the IAM Dashboard. Created a new group and user, provided read only access using the "Read Only Access" Policy Template (as the name suggests, it "provides read-only access to AWS services and resources"):

{
  "Statement":[{
      "Action":[
        "ec2:Describe*",
        "rds:Describe*",
        "s3:Get*",
        "s3:List*",
        "sdb:GetAttributes",
        "sdb:List*",
        "sdb:Select*",
        "sns:Get*",
        "sns:List*",
        "sqs:ListQueues",
        "sqs:GetQueueAttributes",
        "sqs:ReceiveMessage",
        "autoscaling:Describe*",
        "elasticloadbalancing:Describe*",
        "cloudwatch:Describe*",
        "cloudwatch:List*",
        "cloudwatch:Get*",
        "iam:List*",
        "iam:Get*"
      ],
      "Effect":"Allow",
      "Resource":"*"
    }
  ]
}

In addition to the ability to list their instances, each group needs to be able to start/stop their own. So, then, using the AWS Policy Generator, created a new policy with permissions to start/stop instances and attached that as the second policy:

{
  "Statement":[{
      "Action":[
        "ec2:StartInstances",
        "ec2:StopInstances"
      ],
      "Effect":"Allow",
      "Resource":"*"
    }
  ]
}

I could, of course, have added the start/stop instance directives to the default ReadOnly template, but keeping them separate seems to work just as well and feels cleaner.

Initially, just adding the policies didn't work for me (I'm using the ec2 command line tools), posted a plee for help on the EC2 forum, then found this bit in the AWS Identity and Access Management Doc.

If a User needs a signing certificate (for example, to use the Amazon EC2 command line tools), you need to first get a signing certificate and then upload it to the IAM system.

Ok, gotcha, created a cert for the user:

openssl genrsa -out user-cert.key 2048
openssl req -new -key user-cert.key -out user-cert.csr
openssl x509 -req -days 1825 -in user-cert.csr -signkey user-cert.key -out user-cert.crt

Then uploaded the contents of user-cert.crt via the AWS Management Console in "Users" > "MyUser" > "Security Credentials" > "Signing Certificates". Also set the user's EC2_CERT and EC2_PRIVATE_KEY environmental variables so they're used by default.

Now, user can't create or destroy instances:

ec2-run-instances ami-xxxxxxxx -k custom --region us-east-1 -t t1.micro -n 1 | tee -a $current.ec2-run-instances.output
Client.UnauthorizedOperation: You are not authorized to perform this operation.

ec2-terminate-instances --region us-east-1 i-xxxxxxxx
Client.UnauthorizedOperation: You are not authorized to perform this operation.

But can describe, start and stop them:

ec2-stop-instances --region us-east-1 i-xxxxxxxx
INSTANCE	i-xxxxxxxx	running	stopping

ec2-start-instances --region us-east-1 i-xxxxxxxx
INSTANCE	i-xxxxxxxx	stopped	pending

In closing, AWS is simply quite awesome. It would be even more awesome if I could limit access for specific users/groups to specific instances (by TAG). That'd be a great enhancement.

2 Comments

  • 1. Balu replies at 14th December 2011, 11:37 pm :

    Hi,

    I found this page really useful.However, i’ve a doubt.Is it possible to restrict
    visibility of main tabs in AWS.I mean, i want one user to only see EC2 tab, nothing else.

  • 2. Momma Mia replies at 9th February 2012, 11:04 am :

    save me culo! graci!

    the cert part was missing on another howto, so…done!

Leave a comment

NOTE: Enclose quotes in <blockquote></blockquote>. Enclose code in <pre lang="LANG"></pre> (where LANG is one of these).