IAM Users and Policies are the most basic concepts. Understanding them well creates 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 before 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.
Read the above one again and remember it.Policies tell AWS if "user/application" is allowed or denied to perform certain "actions" on specific "resources"
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, To understand what is 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 (you can just read through the code to understand it too without actually executing it):
- We create an user [use
iam.createUser
] and credentials for that user [useiam.createAccessKey
] - Create a policy [use
iam.createPolicy
] - Attach policy to that user [use
iam.attachUserPolicy
] - Get list of users as the newly created user [use
iam.listUsers
]
Create an User
Execute this step with credentials of administratorconst 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, we 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 similar content to following:
{
"accessKeyId": "AKIACCCCCTRL34HMMBZE56GY",
"secretAccessKey": "ccccUqSavfDUAZtDjY6R8AQ6y6jUi7NM3it4C/jf7Y",
"region": "ap-south-1"
}
Create a Policy
Execute this step with credentials of administratorUse 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 administratorconst AWS = require("aws-sdk");
var credentials = new AWS.SharedIniFileCredentials({ profile: "admin-profile-name" });
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.