AWS security is built upon a powerful identity and access management service (IAM) with a rich set of features befitting of an enterprise platform. Yet the IAM management console, nestled within an overflowing AWS service dashboard, is deceptively simple, belying the complexity of the myriad account, credential and security policy options within AWS. IAM shares many features, like users, groups, passwords and permissions, from server operating systems, however it adds others like conditions, roles, access keys and credential rotation that are less common. Further complicating the picture, AWS uses identities and groups for several purposes: access to AWS management features via the Web console or command line interface (CLI), programmatic access to AWS services via APIs and network access and traffic policy when using a private networks on a virtual private cloud (VPC).
AWS hews to established identity management practice where security policy starts at the most atomic layer, individual user identities with unique credentials, that are mapped to a set of usage permissions. However, as the number of users and associated sets of permissions grows, minimizing management complexity requires making molecules out of those atoms. Central to efficient and consistent identity and access management is the ability to define a common set of permissions for particular tasks and job requirements by placing users with common needs into a single pool with a consistent set of policies for everyone in the group. Indeed, the foundation of an effective and secure AWS access policy framework are users and groups.
User Management Basics
AWS access control starts with user identity where the prime directive is that every individual should have a unique user ID and credentials. These map to a set of permissions that by default should have no permissions. In other words, creating a new AWS user doesn’t allow them to do anything. In AWS, user IDs have up to four types of security credentials:
- password: used for Web access to AWS the management console
- access keys (public and private): used for CLI or API access to AWS services
- multi-factor authentication (MFA): associate with a physical (USB token) or software (Google Authenticator) generating one-time passwords for extra security.
- SSH key pairs: used to secure code management software for traffic between private repositories hosted on AWS CodeCommit and local Git clients.
AWS is designed around the security strategy of granting least privilege since by default users can do nothing, even if they have their own access keys. Administrators should build user permissions built from the bottom up: only those required do the job should be added. In practice, this means users that never need to access the management console, like developers, shouldn’t have passwords and those that never programmatically access AWS services, like service admins, shouldn’t know their keys. The principle here is that it’s always easier and more secure to add permissions when necessary than take them away when misused.
Permissions, Policies and Groups
IAM permissions proscribe access to AWS resources and can apply to individual users or overall resources. For example, a user might have read permission to an S3 bucket that allows access to the buckets content, but no ability to add, delete or change its contents. Another S3 bucket used for test and development might have resource permissions that allow any users coming from a specific range of IP addresses or from EC2 instances in a certain zone to have full access. Individual IAM permissions can be aggregated into a policy.
IAM policies are a set of logical statements using JSON syntax that describe an arbitrarily complex set of permissions. For example, a policy could allow users from a business partner (teaser: defined using groups) to drop files only in a specific portion of a larger corporate file sharing bucket, or a user might need full access to just EC2 reports, but just read-only to AWS account usage.
AWS policies can be arbitrarily complex, however most situations are covered by the policy templates built into IAM. Before discussing groups that apply policies to many users at once, a big word of warning: permissions don’t apply to the root user, i.e. the identity used to establish an AWS account. Like the superuser in Linux, AWS root has unfettered access to everything, which is the reason the IAM setup wizard nags administrators to delete (or not create in the first place) root access keys and to secure the root password with MFA.
Groups: A Proxy for User Tasks
Groups are merely a set of users with the same AWS access requirements, i.e. permissions and are a handy shortcut for assigning and changing permissions for large subsets of one’s AWS user population. Groups also make it simple to reassign a user’s set of permissions when they change job responsibilities.
Groups should be based on business function and job requirements, indeed, it’s best to define permissions and groups as a unit and assign users as necessary. Start by defining the needs of each constituency using AWS and then map to a set of AWS permissions. Use the default set of AWS access policies as templates and double check your IAM configuration using the AWS Trusted Advisor.
Group permissions can also have a set of conditions that allow granular control over certain actions and logically take the form of “if-then-else” statements. The goal of conditional permissions is to allow legitimate work while minimizing accidents, particularly with restricted, administrative activities. For example, a conditional permission could require access to a certain resource or the admin console from a certain IP address range and only when using MFA. Conditional policy logic can get complicated and easily lead to unintended consequences, thus it’s wise to use the AWS Policy Simulator, documented here, to test the effects of policy changes before deployment.
Security groups can be very granular, controlling access to specific EC2 instances, however this is overkill that adds administrative overhead. A better option is to create groups for user access to specific applications, or better yet, application tiers, such as access to front ends and ELB (load balancers), app logic and database layers. However when defining permissions for service requests, say an EC2 instance calling other AWS services, it’s best to use roles, not groups, as this IAM FAQ explains:
Q: What is the difference between an IAM role and an IAM user?
An IAM user has permanent long-term credentials and is used to directly interact with AWS services. An IAM role does not have any credentials and cannot make direct requests to AWS services. IAM roles are meant to be assumed by authorized entities, such as IAM users, applications, or an AWS service like EC2.
Group policies can also apply to AWS virtual private cloud (VPC) network security to control access to specific subnets, server ports and API access. We don’t have room for the details, but here groups serve the same function as they do in network firewall policies and ACLs.
Core to group policies is the integrity of individual user credentials. Thus, it’s wise to enforce a strong password policy that includes strength, expiration and re-use, and to regularly rotate access credentials. AWS admins should use credential reports to identify the use of access keys, flag those that are dormant and remove unused keys. Key rotation requires a few steps, detailed here, to avoid accidentally disabling application access.
- Create a second access key in addition to the one in use.
- Update all your applications to use the new access key and validate that the applications are working.
- Change the state of the previous access key to inactive.
- Validate that your applications are still working as expected.
- Delete the inactive access key.