Policy Evaluation Logic in AWS
A challenge you'll face as a Cloud Architect is that your clients will rate the quality of your work by how quickly you can secure scale resources in the cloud.In a properly engineered AWS environment, provisioning and consumption of your organization's resources must be managed and controlled by AWS Identity and Access Management (IAM).
For those of you who have followed my course and blog posts on INE, you'll recall that I've consistently focused on Microsoft Azure. In fact, my first post describe a hands-on approach to enforcing speed and control in an Azure environment.
Even though the tools are different or not necessarily replicated by AWS, I will demonstrate in my next series of posts how to achieve the same using AWS IAM. In this series, we'll master the following key AWS IAM concepts:
- AWS IAM Terminology
- Policy Evaluation Logic
- AWS Security Credentials
- Permissions and Policies
- Attribute-Based Access Control
These are the concepts that lay the foundation of what's coming.
AWS IAM Terminology
IAM provides the infrastructure necessary to control authentication and authorization for your account.
Resources - These include the user, role, policy, and identity provider objects that are stored in IAM.
Identities - The IAM resource objects that can be used to identify and group. You can attach a policy to an IAM identity, including:
Entities - These are the IAM resource objects that AWS uses for authentication. These include roles and users. Roles can be assumed by:
- IAM users
- Roles in your account
- Roles in other accounts
- Users federated through a web identity or SAML
Principals - A principal is a person or application that uses an AWS account root user, an IAM user, or an IAM role to sign-in and make requests to AWS. It can also make requests for an action or operation on an AWS resource.
Request - When a principal tries to use the AWS Management Console, AWS API, or the AWS CLI, they send a request to AWS. The request includes the following information:
- Actions or operations -this can be an action in the AWS Management Console, AWS CLI, or AWS API
- Resources - the resource object on which the actions or operations are performed
- Principal - the person or application that used an entity (user or role) to send the request, including the policies associated with the entity that the principal used to sign-in
- Environmental Data - information about the IP address, user agent, SSL enabled status, or the time of day
- Resource Data - data related to the resource that is being requested, including information such as a DynamoDB table name or a tag on an Amazon EC2 instance
AWS gathers the information into a request context which is used to evaluate and authorize the request.
Authentication - A principal must be authenticated (signed-into AWS), using their credentials, to send a request. To authenticate from the console, a root user must sign-in with their email address and password. An IAM user must provide their account ID or alias, and then their username and password. To authenticate from the API or AWS CLI, you must provide your access key and secret key. AWS recommends that you use multi-factor authentication (MFA) to increase the security of your account.
Authorization - You must be authorized (allowed) in order to complete your request. During authorization, AWS uses values from the request context to check for policies that apply. It then uses the policies to determine whether to allow or deny the request.
Policies - Most policies are stored in AWS as JSON documents and specify the permissions for principal entities. Policies can be categorized as:
- Identity-based policies - provides users with permissions to access the AWS resources in their own account
- Resource-based policies - popular for granting cross-account access
- Advanced or other policies - these are advanced features and should be used carefully
Actions or Operations - After your request has been authenticated and authorized, AWS approves the actions or operations in your request. Operations are defined by a service and include things you can do to a resource, such as viewing, creating, editing, and deleting. For example, IAM supports approximately 40 actions for a user resource, including:
To allow a principal to perform an operation, you must include the necessary actions in a policy that applies to the principal or the affected resource.
Resources (Policy-Perspective) - After AWS approves the operations in your request, they can be performed on the related resource within your account. Examples of resources that exist within a service are:
- an Amazon EC2 instance
- an IAM user
- an Amazon S3 bucket
The service defines a set of actions that can be performed on each resource. If you request to perform an unrelated action on a resource, that request is denied.
Role - A role is an IAM identity you can create in your account that has specific permissions. It shares some similarities with an IAM user. Roles and users are both AWS identities with permission policies that determine what the identity can and cannot do in AWS. However, instead of being uniquely associated with one person, a role is intended to be assumable by anyone who needs it. A role does not have standard, long-term credentials such as a password or access keys associated with it. When you assume a role, it provides you with temporary security credentials for your session. Roles can be used as:
- an IAM user in the same AWS account as the role
- an IAM user in a different AWS account than the role
- a web service offered by AWS such as Amazon EC2
- an external user authenticated by an external identity provider (IdP) service that is compatible with SAML 2.0 or OpenID Connect or a custom-built identity broker.
AWS Service Role - An AWS service role is a role a service assumes to perform actions in your account on your behalf. This service role must include all the permissions required for the service to access the AWS resources that it needs. Service roles provide access only within your account and cannot be used to grant access to services in other accounts. You can create, modify, and delete a service role from within IAM.
AWS service role for an EC2 instance
This is a special type of service role that an application running on an Amazon EC2 instance can assume to perform actions in your account. This role is assigned to an EC2 instance when it's launched. Applications running on that instance can retrieve temporary security credentials and perform actions that the role allows.
AWS service-linked role
This is a unique type of service role that is linked directly to an AWS service. These are pre-defined by the service and include all the permissions that the service requires to call other AWS services on your behalf. The linked-service also defines how you create, modify, and delete a service-line role. With service-linked roles, you do not have to manually add the necessary permissions.
Role Chaining - Role chaining occurs when you use a role to assume a second role through the AWS CLI or API. For example, assume that:
- User 1 has permission to assume RoleA and RoleB
- RoleA has permission to assume RoleB
You can assume RoleA by using User1's long-term credentials in the AssumeRole API operation. This operation returns RoleA short-term credentials. To engage in the role chaining, you can use RoleA's short-term credentials to assume RoleB. When you assume a role, you can pass a session tag and set the tag as transitive. Transitive session tags are passed to subsequent sessions in a role chain. Role chaining limits your AWS CLI or AWS API role session to a maximum of one hour.
Delegation is the granting of permissions to someone to allow access to resources that you control. It involves setting up trusts between two accounts:
- the trusting account owns the resources
- the trusted account contains the users that need to access the resources in the trusting account
The trusted and trusting accounts can be any of the following:
- the same account
- separate accounts that are both under your organization's control
- 2 separate accounts owned by different organizations
To delegate permission to access a resource, create an IAM role in the trusting account. The IAM role has two policies attached:
- the permissions policy grants the user of the role the needed permissions to carry out the intended tasks on the resource
- the trust policy specifies which trusted account members are allowed to assume the role
Attach a permissions policy to the user in the trusted account that allows that user to switch to, or assume the role.
Allows user in trusted account to assume a role
A user who assumes a role temporarily gives up his or her own permissions and takes on the permissions of the role. When the user exits, or stops using the role, the original user permissions are restored.
Federation - Federation is the creation of a trust relationship between an external identity provider (IdP) and AWS. Users can sign into:
- a web provider, such as Login with Amazon, Facebook, Google, or any IdP that is compatible with OpenID Connect (OIDC)
- an enterprise identity system that is compatible with Security Assertion Markup Language (SAML) 2.0, such as Microsoft Directory Federation Services
When you use OIDC and SAML2.0 to configure a trust relationship between these external IdPs and AWS, the user is assigned to an IAM role. The user also receives temporary credentials that allow the user to access AWS resources.
Federation User - Instead of creating an IAM user, you can use existing identities from AWS Directory Service, your enterprise user directory, or a web identity provider. These are known as federated users. AWS assigns a role to a federated user when access is requested through an identity provider.
Trust Policy - A trust policy is the JSON document where you define the principals you trust to assume the role. A role trust policy is a required resource-based policy attached to a role in IAM. The principals you can specify in the trust policy include:
Permissions Policy - The permissions policy is the JSON document where you define what actions and resources the role can use.
Permissions Boundary - An advanced feature where you use policies to limit the maximum permissions an identity-based policy can grant to a role. You cannot apply a permissions boundary to a service-linked role. AWS checks each policy that applies to the context of your request. If a single permissions policy includes a denied action, AWS denies the entire request and stops evaluating. This is called an explicit deny. Because requests are denied by default, AWS authorizes your request only if every part is allowed by the applicable permissions policies.
Policy Evaluation Logic
Again, by default, all requests are denied. In general, requests made using the AWS account root user credentials for resources in the account are always allowed. An explicit allow in any permissions policy (identity-based or resource-based) overrides this default.
The existence of an Organizations Service Control Policy (SCP), IAM permissions boundary, or a session policy overrides the allow. If one or more of these policy types exist, they must all allow the request. Otherwise, it is implicitly denied. An explicit deny in any policy overrides any allows.
AWS Security Credentials
AWS IAM lets you manage several types of long-term credentials for IAM users:
- Access keys
- Amazon CloudFront key pairs
- SSH public keys
- X.509 certificates
IAM also allows you to grant users temporary security credentials with a defined expiration for access to your AWS resources. Temporary access is useful when:
- creating a mobile app with third-party sign-in
- creating a mobile app with custom authentication
- using your organization's authentication system to grant access to AWS resources
- using your organization's authentication system and SAML to grant access to AWS resources
- using web-based SSO to access the AWS Management Console
- delegating API access to third-parties to access resources in your account or in another account you own
Temporary Security Credentials
You can use the AWS Security Token Service (STS) to create and provide trusted users with temporary security credentials that can control access to your AWS resources.
Temporary security credentials can be configured to last anywhere between a few minutes to several hours. After the credentials expire, AWS no longer recognizes them or allows any kind of access from API requests made with them.
Temporary security credentials are not stored with the user, but are generated dynamically and provided to the user when requested. When (or even before) the temporary security credentials expire, the user can request new credentials, as long as the user requesting them still has permissions to do so.
You do not have to distribute or embed long-term AWS security credentials with an application. You can also provide access to your AWS resources to users without having to define an AWS identity for them.
Temporary credentials are the basis for roles and identity federation. They have a limited lifetime, so you don't need to rotate them or explicitly revoke them when they're no longer needed. You can also specify how long the credentials are valid, up to a maximum limit.
Permissions and Policies
IAM Policy Types
Identity-based policies control what actions the identity can perform, on which resources, and under what conditions. These policies can be further classified into Managed Policies and Inline Policies.
Managed policies are standalone identity-based policies you can attach to multiple users, groups, and roles in your AWS account. You can use two types of managed policies:
- AWS-Managed Policies - These are managed policies created and managed by AWS
- Customer-Managed Policies - These are managed policies that you create and manage in your AWS account. They offer more control over your policies than AWS-managed policies. You can create and edit an IAM policy in the visual editor or by creating the JSON policy document directly.
Inline policies are policies you create, manage, and embed directly into a single user, group, or role. In most cases, AWS does not recommend using inline policies.
Resource-based policies are permissions policies you attach to a resource, such as Amazon S3. It controls what actions a "specified" principal can perform on that resource and under what conditions.
What do we mean by "specified"? In managed-policies, AWS assumes the principal is a user or role. With resource-based policies where the policy is attached to a resource, you must explicitly specify the principal in your policy statement. To enable cross-account access, you can specify an entire account or IAM entities in another account as the principal in a resource-based policy.
IAM Policy Types
The IAM service supports only one type of resource-based policy called a "trust policy". This is attached to an IAM role.
Because an IAM role is both an identity and a resource that supports resource-based policies, you must attach both a trust policy and an identity-based policy to an IAM role. Trust policies define which principal entities (accounts, users, roles, and federated users) can assume the role.
A trust policy is the JSON document where you define the principals that you trust to assume the role. A role trust policy is a required resource-based policy attached to a role in IAM. The principals you can specify in the trust policy include:
Attribute-Based Access Control (ABAC)
Attribute-based access control (ABAC) is an authorization strategy that defines permissions based attributes. In AWS, these attributes are called tags. Tags can be attached to IAM principals (users or roles) and to AWS recourses.
You can create a single ABC policy or small set of policies for your IAM principals. These ABAC policies can be designed to allow operations when the principal's tag matches the resource tag. ABAC is helpful in environments that are growing rapidly and with situations where policy management becomes cumbersome.
For example, you can create three roles with the access-project tag key.
Set the tag value of the first role to Heart, the second to Sun, and the third to Lightning. You can then use a single policy that allows access when the role and the resource are tagged with the same value for access-project.
Comparing ABAC to the Traditional RBAC
In IAM, you implement RBAC by creating different policies for different job functions. You then attach the policies to identities (IAM users, groups of users, or IAM roles).
You grant the minimum permissions necessary for the job function (granting least privilege). You do this by listing the specific resources that the job function can access.
The disadvantage to using the traditional RBAC model is that when employees add new resources, you must update policies to allow access to those resources.
For example, assume you have three projects your employees work on titled Heart, Sun, and Lightning. You can create an IAM role for each project, and them attach policies to each IAM role to define the resources that anyone allowed to assume the role can access.
If an employee changes jobs within your company, assign them to a different IAM role.
However, the Sun project may require additional resources, such as a new Amazon S3 bucket. In that case, you must update the policy attached to the Sun role to specify the new bucket resource. Otherwise, Sun project members are not allowed to access the new bucket.
ABAC provides the following advantages over the traditional RBAC model:
- ABAC permissions scale with innovation - it is no longer necessary for an administrator to update existing policies to allow access to new resources. For example, assume you designed your ABAC strategy with the access-project tag. A developer uses the role with access-project=Heart tag. When people on the Heart project need additional Amazon EC2 resources, the developer can create new EC2 instances with access-project=Heart tag. Then, anyone on the Heart project can start and stop those instances because their values match.
- ABAC requires fewer policies - because you do not have to create different policies for different job functions, you create fewer policies which are easier to manage.
- Using ABAC, teams can change and grow quickly - this is because permissions for newer resources are automatically granted based on attributes.
- Granular permissions are possible using ABAC
- Use employee attributes from your corporate directory with ABAC - you can configure your SAML-based or web identity provider to pass session tags to AWS. When your employees federate into AWS, their attributes are applied to their resulting principal in AWS. You can then use ABAC to allow or deny permissions based on those attributes.
In this post, we've covered the following:
- AWS IAM Terminology
- Policy Evaluation Logic
- AWS Security Credentials
- Permissions and Policies
- Attribute-Based Access Control
In future posts, we'll take a hands-on approach to applying these concepts. Get ready.