IAM stands for "Identity and Access Management." IAM provides answers to the fundamental question in DevOps: "Who can access what?"
The roots of IAM go back to the early days of computing, where users of UNIX systems needed a username and password to access their accounts and files. As systems got more complex, grew in number, and larger pools of users needed access, identity management solutions like Lightweight Directory Access Protocol, LDAP, became increasingly popular, where a central team could manage access for multiple departments and roles.
The revolution of DevOps added a new layer of complexity to access management; non-human entities also needed access to data and systems. These non-humans included both applications on the same platform as well as third-party systems, making things even more complex.
While it is commonly associated with AWS, and their AWS IAM service, IAM is not limited to their platform. All cloud providers, such as Google Cloud and Azure DevOps, offer IAM solutions that allow users to access resources and systems. If you are looking for specific AWS IAM best practices, look no further than our AWS IAM Security Best Practices article.
For the rest of this article, we will look at the generic best practices that have evolved over the last decade around each part of the basic question we started with, "who can access what?":
- Who: Humans and non-human entities (applications and machine workers)
- Can access: permissions sets
- What: resources and systems
Who - Users in IAM
There are two broad groups that we are concerned with in IAM: humans and non-humans.
Humans are typically developers, engineers, analysts, or anyone else that needs access to the data and resources in your DevOps environments. IAM services allow you to create specific users for specific roles and assign them any needed permissions. These are not separate accounts but just users under a single account.
Non-human entities, also commonly called machine identities, are any system, API, platform, or service that needs to be able to connect and interact with your CI/CD pipeline. IAM systems can grant these entities the access they need and tightly scope it only to allow specific access under the right conditions. We will dive into this kind of access further in the resources and services section.
Zero-Trust or Least Privilege Access
No matter what kind of user, the principle of least privilege should always be applied. Any new user created or approved should start with no access whatsoever and then only be granted permissions that will let them accomplish their work, but nothing further. This is what we mean by zero trust.
By default, most cloud providers use this model so that any new user will start with zero permissions. Only once assigned a role or specific permissions will they be able to access any resources.
A Staged Approach to Permissions
While we feel everyone should lean into Zero-Trust, it is also important to balance access restriction with real-world business needs. One good way to think about this is to scope access based on the maturity or progress of a project.
For example, for early-stage research into a new product or application, giving a user unrestricted access might be necessary to get to a minimum viable product, MVP, effectively. It would be a good idea in that case to create a whole new account dedicated to the project and isolated from your production infrastructure. As the project progresses toward production, additional access restrictions can be applied and fine-tuned, allowing only the needed access to finalize the application. Finally, when launched, permissions can be brought in line with existing company policies and best practices.
Identity Providers and Temporary Credentials
For human users, the best credentials are short-lived, and ones that no human ever sees or knows. This is entirely achievable thanks to identity providers such as AWS IAM Identity Center or Google Cloud Identity. You can also sync a trusted external ID source like Okta Universal Directory, Microsoft Active Domain, or any open-source SAML-based system to get the same result.
When leveraging an identity provider, any user authenticates with their identity service and is then issued a short-term token or certificate that is never exposed to the users and, therefore, nearly impossible to leak. There are some additional advantages to this approach, such as:
- Centralized user stores that are easy to manage
- Reduced password fatigue from constant password rotation
- A decreased number of systems to secure overall
- A centralized ID manager that is simpler to secure and audit
There is a special kind of human user in IAM who control an organization's account on a cloud provider: Root, also known as Super Administrator. These users are ultimately responsible for provisioning access, resources, and billing. These are extremely powerful accounts and should be used with caution.
It is a very good idea to avoid using root credentials at all. Instead, create unique users to perform specific jobs. Some providers, like AWS, allow you to block root users from managing or working with some processes, ensuring that these special and powerful accounts stay protected.
Since root accounts necessarily require long-lived passwords, it is vital to create complex, high-entropy passwords and protect them. We highly recommend using a password manager like LastPass or 1Password. Combined with multi-factor authentication, MFA. MFA means having something you know, such as a password, combined with something you have, like a Google Authenticator one-time password, OTP, or, better yet, a hardware token.
Another approach is to create very long and complex passwords but never store them anywhere after logging in, instead relying on password resets each time access is needed.
It is vital for your business to ensure the long-lived credentials for a root user never appear in your code or configuration anywhere. In fact, the best practice is to never use your root user access key, and, even better, delete it. While this can sound radical, it has two interesting benefits: it limits vectors by which the account can be compromised (remember, this account has full-administrative privileges!), and it forces the creation of role based accounts with restricted privileges.
Trust is good but verifying is better, so using GitGuardian to scan for secrets across all of your repos to check that no root credentials are anywhere in your perimeter. Developers can also leverage ggshield to make sure any such credentials accidentally pasted into a file never make it into a commit or get pushed to your shared repositories.
Protect The Credential Recovery Path
Make sure you also secure the root credential recovery flow. Unfortunately, there has been a steady increase of phishing attempts recently targeting administrator-level password resets. Attackers know this is a good way to try to steal login credentials.
One important element of any password reset strategy is enforcing MFA for any email accounts used for recovery. Another strategy is creating dedicated email accounts for these highly prized and powerful credentials. If malicious actors do not know or can't guess associated email addresses for your root users, then it will make it that much harder for them to launch an attack.
Make Sure Your User List is Accurate and Current
The easiest user to administer is the one that does not exist. As soon as a user is no longer needed, remove them from the system. Make sure you are auditing users regularly to see if they are still active and behaving as expected. If you ever discover a user you do not recognize accessing your resources, it likely is time to have a conversation with your security team.
Can Access - Permissions in IAM
The second part of the IAM equation, "who can access what?' is setting permissions. Permissions can be managed per user or per role.
Setting permissions for long-lived user accounts might sometimes be necessary, but it means you will need to monitor and manage each of those users' permissions over time. It also means you will need to track what individuals have which permissions to avoid overlap or misconfigurations.
The other path you can use for permissions is creating roles. Roles can be assigned any number of permissions, and then you can assign users those roles. This approach makes it much easier to manage permission sets at a larger scale and quickly see who has access to each role. If a new resource is added to your setup, you can quickly add the needed permissions to anyone with a role rather than setting individual user permissions. It makes broadly revoking access to a service that much quicker as well.
The AWS EPARC Model
While IAM is offered by various vendors, it might be helpful to take a closer look at the model AWS uses for its permission structure, EPARC:
- Effect - what should happen if permission is allowed
- Principle - the user or machine worker that is allowed or denied access
- Action - what will be carried out if access is allowed or denied
- Resource - the service or data to be accessed
- Condition - the conditions under which the access can be granted
If you can provide and understand all the needed information to satisfy the EPARC model, then you are in a good position to set policy.
Use Conditions to Further Restrict Unexpected Access
When defining policy, you can use conditions to narrow access rights even further. Conditions are fine-grained controls to define specific circumstances to allow permissions. You can think of these as "but, only if" statements. For example:
- Grant access to resources, BUT ONLY IF the access request comes from a specific subnet and within a specific IP range
- Grant access to resources, BUT ONLY IF the access request starts with a specific prefix
- Allow an AWS Lambda function to be created, BUT ONLY IF using AWS CloudFormation
- Allow a Google Cloud Function, BUT ONLY IF it will live in a specific VPC
While all cloud platforms differ slightly in the implementation specifics, all support implementing conditions.
What - Resources and Services in IAM
Finally, the last piece of the IAM "who can access what?" puzzle is the resources and services a user can access. In the case that the 'user' is a non-human entity, you can think of it as a 'resource that can access a resource.' Fortunately, if you have handled user authentication and permissions correctly, there is not much you will need to think about for this part.
There are basically two types of services; systems on the same platform and third-party services that exist outside the platform. In some rare cases where a team has built its own private cloud, there might not be any 'on-platform' applications at all.
Your Data Perimeter
One good way to view resources and services is to think about them existing either inside or outside of your 'data perimeter,' which we can define as the boundary between your applications and the rest of the internet. In short, you only ever want trusted identities to be able to access trusted resources from expected locations. If a resource is outside of your data perimeter, then access should be denied. Similarly, if anyone from outside this perimeter tries to gain access to any trusted service, then access should also be denied, and likely alarm bells should be going off.
For systems on the same platform, you can generally rely on their provided identity provider service to ensure it is a trusted resource. Even though it is inside your account, it is still a good idea to set conditions to ensure only the expected users can gain access to any service.
For third-party applications, there is always the temptation to just quickly embed the access credentials in your configuration… Don't ever do this! This is one of the main paths attackers use to laterally expand during a breach, and sometimes, this is the origin of a breach. Instead, to make them trusted resources, rely on tools like Hashicorp Vault to store any long-lived credentials. Or, even better, integrate with Certificate Authority Services to authenticate automatically via automatically generated and managed certificates.
Leverage Tools to Optimize Your IAM Configurations
Cloud providers want you to succeed and achieve the best possible security policies. This is the motivation behind tools like AWS IAM Access Analyzer and Google Cloud Policy Analyzer. These are free tools that can help you understand your current settings and fine-tune them.
IAM analyzers can show you who has which permissions and, just as importantly, which permissions have not been used. Any unused permissions should be revoked to prevent abuse. They should not be missed since they were not needed for the work to be done. AWS refers to this fine-tuning exercise as 'right-sizing your permissions'.
Aside from just analyzing the existing permissions, these tools can also suggest optimal permission sets for a given situation. They can also validate your settings. For example, AWS IAM Access Analyzer claims to offer over 100 validation checks that will show security issues, errors, and general warnings, while providing optimization suggestions. No matter what provider you choose, make sure you look through their documentation for best practices and tools that can help you stay safe.
IAM Best Practices is a Journey
For many organizations, the last time IAM was discussed or even thought about was when it was first implemented. If that sounds like you, then you are not alone, but it is likely time to rethink your permissions and answer the question: "who can access what?". While there is no single right answer to that question, all cloud providers agree you should be able to answer that question.
As we wrap up this article, we want to sum up our tips on managing IAM:
- Use Identity Managers to authenticate users
- Create users for specific tasks with zero permissions by default
- Never use root accounts for everyday jobs, and delete unused access keys
- When long-term credentials are in use, ensure they are protected along with their recovery path
- Enforce MFA everywhere
- Use roles to manage sets of permissions, assigning users roles instead of permissions
- Think through the EPARC model when assigning permissions
- Use "but only if' conditions to fine-tune permissions
- Use IAM analyzer tools to verify and refine permissions on a regular basis
- Think in terms of data perimeter; only trusted identities accessing trusted resources from expected locations
- Never embed credentials into your configuration files
- Integrate with certificate authority services whenever possible
On your journey to more secure IAM practices in your organization, remember GitGuardian is here to help you discover where those long-lived credentials have snuck into your code and files. Make sure you tackle secret sprawl as you are adopting better security practices.