AWS 1x1 - Identity and Access Management
From the basics to advanced concepts of AWS’ core service for managing users, groups, permissions for resources, and much more.
For seriously working with AWS, there’s no way around its Identity and Access Management (IAM) service. Skipping to understand its core principles will bite you again and again in the future️.
Take the time to do a deep dive, so you won’t be frustrated later.
Overview of the topics to cover:
Identity- & Resource-based Policies
Securing your AWS Account
Basics: Credentials & AWS CLI
Dealing with “Access Denied”
Personally speaking, IAM is the most outstanding AWS core service, with an endless list of features that are well-integrated into the whole service landscape.
A small, non-exhaustive list of those features:
managing users for your AWS account, with individual rights and/or temporary access
enforcing password policies or Multi-Factor Authentication
setting rights boundaries for AWS services & your apps
Take your time to get to know the basics is crucial.
Starting with IAM can cause you to feel overwhelmed, alone due to its huge vocabulary. Let's cover the fundamental concepts you will work with on a daily basis.
User — an end-user, accessing the console, AWS API, or both.
Group — a group of users, sharing the same privileges and permissions.
Policy — a defined list of permissions, specified as JSON.
Role — a set of policies, that can be assumed by a user or AWS Service to gain those permissions.
At AWS IAM, everything evolves around Policies.
By default, all actions for all services are denied, so you have to explicitly grant rights by adding a policy with your targeted actions and resources to your service role, user, or group.
You can attach one or multiple policies to a role and each policy can contain one or multiple Statements.
Statements contain the permissions you want to grant and are structured in a specific way, defined as a JSON.
An important detail about policies: they come in two different types.
• Identity-based — attached to a user, group, or role.
• Resource-based — attached to a resource, e.g. S3 bucket, SQS queue, or KMS key.
Let’s have a look at what a Statement must contain
• Effect — the indication if it’s Deny or Allow.
• Action — a list of actions.
• Resource — a list of resources for which the actions are granted.
For resource-based policies, Resouce is optional. Resource-based Policies also need to define a Principal. It indicates for which account, (federated) user, or role user you’d like to allow or deny access.
There are more specifics for this type of policy like they aren’t being affected by permission boundaries
If you got to this point, your IAM knowledge foundation is laid.
Securing your own AWS account
It’s not recommended to work with your root credentials. Those should only be used to enable MFA, create your first IAM user, and should then be locked away securely.
Go to your security page & select Manage MFA Device. You can use an authentication app of your choice.
💡 If there’s already an Access Key, you can delete it as you shouldn’t work with your root credentials in any way.
Afterward, you can create your first user by clicking on Users > Add User. You can make use of AWS’ predefined policies in the first place.
If you’re working on a serious project, make sure to use groups to manage rights across different roles easily.
After creating your user with enabled console access, you can now log out with your root user and log back in with your IAM user.
💡 Note down your AWS’ account identifier on the top right before logging out, because it’s needed for the IAM user login.
For accessing AWS’ API to maintain your infrastructure via code, we’ll need credentials.
Go back to your security credentials page and click Create Access Key to get your Access Key ID & Secret Access Key.
💡 There’s no way to display the Secret Access Key again, but you can create a new one at any time.
AWS’ Command Line Interface
Now that we’ve got our credentials, we can install the AWS CLI. After installation, you can run aws configure for doing our initial setup.
You’ll be prompted for credentials (which we received in the previous step) and some default settings.
💡 When working with different accounts and/or roles and enabled MFA, it’s recommendable to get some tooling support. I love working with AWSume in this case. It’s easy to set up and really intuitive to work with.
Handling “Access Denied”
Working with AWS, especially in the beginning, you’ll face this message regularly. Mostly, AWS’ API will point you to missing permissions so you can easily extend your policy.
Sometimes it’s not that easy and you’ll need to get back to the docs.
What you should not do: just extending your policy with all permissions for your target service by adding e.g. ACTION: ["dynamodb:"] and RESOURCE: [""]
You won’t learn anything by that and you’re not respecting the rule of Least Privilege.
Least Privilege states that you should always just assign the permissions that are actually needed for the service to fulfill its goals.
Example: An app that runs on Lambda and now needs access to a recently created DynamoDB table.
The easiest way would be to just create a policy that grants full permissions to DynamoDB and attach the role to your Lambdas role.
But that’s not a good solution, because our app just needs to have read & write permissions for a single table.
How can we improve?
We don’t manage tables, so we shouldn’t grant DeleteTable.
What we need:
You’ll always find all permissions in the docs!
As we’re only working with a specific table, we can really fix the permissions to be only valid for this single table by listing the ARN.
For enforcing least privilege, you’ll need to fiddle around with ARNs a lot.
Maybe this sounds tedious, but if you start working with Infrastructure as Code (IaC) tools like Terraform, CloudFormation, or AWS CDK, this is really easy & comfortable!
Regardless of what you’re using, all tools will create output variables for your created resources that include all the references you need, like for example the ARN.
You can create other resources that depend on those.
That’s not the end of IAMs capabilities.
AWS’ Permission Boundaries help you to restricted effective permissions for a user or role. They also contain policies that describe actions and resources, but they are acting as an outer boundary.
What it means: the actually attached permissions can never exceed the boundary. So if your boundaries only list dynamodb:query for all resources, a role with dynamodb:* can’t update or delete items, but only query!
What is it good for?
Boundaries can be defined in one place but re-used across all of your account’s roles and users.
By that, you could for example strictly separate an app’s permissions to only access resources with a given name prefix, but having multiple apps within your account. You can also use your boundary policy not only as a boundary but as actual permissions, for example for your CI/CD service/tool like CodeBuild.
By that, you’ll automatically grant all necessary rights, but still with respect to the boundary.
Important details about boundaries policies:
• if used as a boundary, they are not actually granting permissions, but only restricting them.
• there’s no effect on resource-based policies, e.g. for your S3 bucket.
There are a lot more features that IAM offers and this was just an introduction with some general recommendations, but it will be enough to get you started.
For following security best practices, there’s also a lot of tooling you can fall back to.
It reviews your permissions for unnecessary rights or best practice violations and checks that you’ve enabled AWS security features for your services and resources.
It greatly helps to build, validate and troubleshoot your policies. It supports identity-based, resource-based, and even Organizations service control policies.
There are a lot more third-party services guiding you with security recommendations & well-architected tips like dashbird.io for serverless architectures, build around Lambda, DynamoDB, SQS, and other well-known managed services.
You can try it out for free, as 1m Lambda requests per month are included in the default tier.
Completely mastering IAM is more of a holy grail, as it’s a complex topic and there will always be days where you’re stuck on some permissions issue, regardless of your experience.
But it gets a lot easier with time.