AWS Basics - IAM Users, Policies cover image

Rajiv Seelam • December 13, 2019

AWS Basics - IAM Users, Policies

aws iam-users iam-policies

IAM Users and Policies are the most basic concepts. Understanding them well created a perfect background to overwhelming concepts of Roles which is essential to effectively implement Authorization.

Who is a user?

To get started, let's just say, users are people or applications who can access AWS resources. As a person you might be accessing AWS Console via browser, and for programmtic access (ex: nodejs) you would act as an application.

So, according to AWS an user can be a real person or just an application, so instead of constanstly referring to them as a person or as a application, there is different word we can use: Principal

A principal is a person or application that can make a request for an action or operation on an AWS resource

What is a policy?

Let's take a little detour we get into policy. Why do we even need a policy? Generally, we might have lot of servers, data in databases, files in storage. Who can access it? Who is authorized to perform actions? Who can control what resources? That's exactly what policies do.

Policies tell AWS if "user/application" is allowed or denied to perform certain "actions" on specific "resources"

Read the above one again and remember it.

Resource

Everything in AWS is a resource. IAM User, IAM Policy, EC2 Instance, DynamoDB Table, S3 Bucket, An Object in a S3 bucket etc., Each resource is identifier by an ARN (Amazon Resource Name). If you want to learn more, visit here

Action

Everything you do on a resource is an action. AWS lists all possible actions on a resource in their documentation. If you want to know list of possible actions on S3 resources, you can refer to documentation.

Policy

Now, let's get back to understanding a policy. Let's look at a policy, it's specified in a JSON format.

{
    "Version": "2012-10-17",
    "Statement": {
        "Effect": "Allow",
        "Action": "iam:ListUsers",
        "Resource": "*"
    }
}

There's no much use of a policy unless you attach this to a Principal. When attached to a Principal, it tells: "Allow that principal to list users in IAM service".

To run below examples, you need to setup nodejs aws-sdk. If you need help you can refer to setup article.

In the following exercise:

Create an User

Execute this step with credentials of administrator

const AWS = require("aws-sdk");

var iam = new AWS.IAM();

function createUser(username) {
  var params = {
    UserName: username
  };

  iam.getUser(params, (err, data) => {
    if (err && err.code === "NoSuchEntity") {
      iam.createUser(params, function(err, data) {
        if (err) {
          console.log("Error", err);
        } else {
          console.log("Success", data);
        }
      });
    } else {
      console.log("Already exists");
    }
  });
}

createUser("Bobby");

In above step we create a user with name "Bobby".

Next step, create credentials for Bobby

function createAccessKey(username) {
  iam.createAccessKey({ UserName: username }, (err, data) => {
    if (err) {
      console.log("Error", err);
    } else {
      console.log("Success", data.AccessKey);
    }
  });
}

createAccessKey("Bobby");

You will see a response similar to following:

Success {
  UserName: 'Bobby',
  AccessKeyId: 'AKIACCCCCTRL34HMMBZE56GY',
  SecretAccessKey: 'ccccUqSavfDUAZtDjY6R8AQ6y6jUi7NM3it4C/jf7Y',
}

Create a file with name access-bobby.json in the same folder and put following content and replace with your AccessKeyId and SecretAccessKey:

{
  "accessKeyId": "AKIACCCCCTRL34HMMBZE56GY",
  "secretAccessKey": "ccccUqSavfDUAZtDjY6R8AQ6y6jUi7NM3it4C/jf7Y",
  "region": "ap-south-1"
}
Create a Policy

Execute this step with credentials of administrator

Use the following code to create a policy

const AWS = require("aws-sdk");

function createListUsersPolicy() {
  var myManagedPolicy = {
    Version: "2012-10-17",
    Statement: [
      {
        Effect: "Allow",
        Action: "iam:ListUsers",
        Resource: "*"
      }
    ]
  };

  var params = {
    PolicyDocument: JSON.stringify(myManagedPolicy),
    PolicyName: "getListOfUsers"
  };

  var iam = new AWS.IAM();

  iam.createPolicy(params, (err, data) => {
    if (err) {
      console.log("Error", err);
    } else {
      console.log("Success", data);
    }
  });
}

createListUsersPolicy();

You would get a similar response as following, please note down the Arn

Success {
  ResponseMetadata: { RequestId: 'cccd8168-f5fd-410b-b3e0-4f04fe56f444' },
  Policy: {
    ...
    PolicyName: 'getListOfUsers',
    Arn: 'arn:aws:iam::523004999112:policy/getListOfUsers',
    ...
  }
}
Attach Policy to User

Execute this step with credentials of administrator

const AWS = require("aws-sdk");
var credentials = new AWS.SharedIniFileCredentials({ profile: "finkitdemo" });
AWS.config.credentials = credentials;

function attachPolicy(user, arn) {
  var params = {
    PolicyArn: arn,
    UserName: user
  };

  var iam = new AWS.IAM();

  iam.attachUserPolicy(params, (err, data) => {
    if (err) console.log(err, err.stack);
    else console.log(data);
  });
}

attachPolicy("Bobby", "arn:aws:iam::523004999112:policy/getListOfUsers");
Get list of users as Bobby
const AWS = require("aws-sdk");
AWS.config.loadFromPath("./access-bobby.json");

var iam = new AWS.IAM();

var params = {};

iam.listUsers(params, (err, data) => {
  if (err) {
    console.log(err.message);
  } else {
    console.log(data);
  }
});

Now you will list of users a part of response, success!

Basically, you must have understood that there are users and policies. Policy defines what it allows and denies. In our policy we allowed getting list of users from IAM. That's what action iam:ListUsers does.