Charting our Identity journey in AWS — Part 1

Louay Shaat
My Local Farmer Engineering
10 min readSep 28, 2021

TL;DR This blog details our journey on how we ended up choosing AWS SSO as our authentication gateway to AWS. Read Next Steps to understand our top 4 reasons for selecting AWS SSO

For those of you who saw our Launch post, you know that 2020/2021 has been a tough challenge for us due to the COVID-19 crisis. While our teams are busy progressing their Cloud migration to get back flexibility and improve our Time-To-Market, one aspect that we have been grappling with, is building the right guardrails to secure our applications and access to our infrastructure. We immediately discovered, security in the cloud is quite different from the model we operated in our data-centers. We also saw this as an opportunity to improve how we view security and embed it in how we build our new services. As we don’t have a dedicated security team, I saw this as an opportunity to explore new grounds and develop new skills.

As we started using AWS for testing, our team created identities in aws to give themselves access to services and resources. Now that we are running production services in AWS, we wanted to make sure that our team are empowered with the right access at the right time.

In this blog I will highlight the learning journey we went through to build identities to enable our teams to do just that. Get access to the right resources at the right time.

Disclaimer
I Love My Local Farmer is a fictional company inspired by customer interactions with AWS Solutions Architects. Any stories told in this blog are not related to a specific customer. Similarities with any real companies, people, or situations are purely coincidental. Stories in this blog represent the views of the authors and are not endorsed by AWS.

AWS Identities

Understanding how roles, policies, cross account access, service linked roles, permission boundaries and organizational SCPs are important concepts to grasp to understand how you can utilize AWS IAM effectively to secure your user access. We won’t be covering these aspects in this blog but we will assume basic knowledge and how they apply to your identity access.

Before diving into authorization options, we have already decided that we will be going with a multi aws account setup leveraging AWS Control Tower, read more here to understanding the reasoning and benefits that brings to us as an organization.

AWS Identity and Access Management (AWS IAM) is the glue that holds it all together in AWS, if you want access to a service, a bucket or a Lambda function, you have likely touched IAM to get this working.

So what is IAM?

IAM gives you the ability to create users/groups to provide access to resources

As you can see above, I can create a role that contains a policy (Detailing allowed actions). This role can be assumed by a user or a group to get access to those actions.

Well that sounds straight forward, but it really isn’t.

While researching IAM, I cam across this policy evaluation logic, this was our starting point on understanding how granular we can get in providing access to our resources in AWS and the guardrails we can use to prevent mis configurations.

Source: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_evaluation-logic.html

AWS Identity has many layers that are taken into account when evaluating whether to grant or deny an access request.
In summary, requests are all denied by default, whatever access policy you are leveraging needs to have an implicit allow and any deny in that flow will result in a denied request.

As an example, if I have a Lambda (Lambda is the AWS Function as a service) administrator role with a policy assigned to a user (giving them the ability to create/delete and modify ec2 instances) within a specific account. i.e. an Identity Based Policy.
I also have an Organizational Service Control Policy associated with that account, that denies all actions within the Sydney region(ap-southeast-2).
If that administrator tries to create a Lambda function in the ap-southeast-2 region, that request will be denied.

Existing Architecture

As with any organization that has a footprint outside of Cloud platforms, we are not starting a greenfield journey, we have been utilizing Microsoft Active Directory on-premise as our central identity since we defined our on-premise access strategy. As most of Office users, we’ve moved to Office 365 and then Microsoft 365 which come with an Azure AD built-in. To avoid managing identities twice, we have extended our Active Directory setup by synchronizing our AD users and groups to AzureAD.

Users today requiring access to Azure or other web accessible resources need to enter a secondary authentication factor either using a Mobile App, or SMS. We decided to implement a 2 factor authentication model to ensure we are protecting our assets and data

Now the question is, what identity solution is the right fit for us?

Types of Authentication

Now that we have a fundamental understanding of AWS Identity concepts and how AWS evaluates authorization access to resources, what AWS IAM options do we have for authenticating our users in AWS?

After some research, we see there are 3 options that we can leverage

  • Option 1: Create and Manage users and groups in IAM natively. We can assign those users/groups roles with policies to grant them access to specific resources. AWS also allows cross account access meaning we can centralize our IAM users in a single account and create the required roles in the destination accounts.
  • Option 2: Leverage IAM Identity Providers utilizing with SAML 2.0 or OIDC. Establishing a trust relationship between my IdP (AzureAD) and a Trust Role in my account. This setup will have to be repeated in every account in my AWS Organization.
  • Option 3: AWS has another service AWS SSO that gives you the ability to synchronize your users and groups from our idp (AzureAD) or Active Directory users to grant access to resources. AWS SSO provides cli, api and console access and direct integration with AWS Organizations. AWS SSO uses Permission Sets (a template similar to IAM Roles with policies embedded to provide the authorization to resources) to provision access to child accounts

AWS SSO was really appealing to us. In one place, we could create, modify and delete permissions set and apply them to all our AWS accounts. With our mutli-account strategy, I was elated about keeping homogenous permissions in all our accounts. Discovering AWS SSO was a relief.

Option 2, give us the flexibility integrate with multiple identity providers using SAML and OIDC, meaning that we can also leverage a separate idp to perform Privilege access management or mix and match our identity provider on an account level.

Options 3, AWS SSO gives us the ability to leverage a single identity store as an identity source while centralizing authorization in AWS with lifecycle management.

Note: we can leverage both, AWS SSO and IAM Identity providers to perform different functions.

One of the main tenets of our identity strategy is a Single Identity across all services, regardless of where the service resides. That gives us the ability to leverage a single Starters and Leavers process to ensure that only authorized users have the right to access our services.

Based on this, Option 1 with Users and Groups created outside our identity source doesn’t fit with our current strategy. This leaves us with option 2 and 3.

Auditing

Another strong requirement for our identity is auditing and monitoring to be able to capture misconfigurations, identity any security risks and mitigate against them. Understanding what roles and identities our users are using is important for us to be able to understand user behaviour and detect any anomalies.
Both AWS IAM and AWS SSO have detailed Events available in AWS CloudTrail (CloudTrail provides Event History of actions in AWS via CLI, Console and API) for us to consume, analyze and track actions accordingly

AWS SSO produces 2 main events, Authenticate and Federate (Following the Authentication and Authorization model)

Some examples below

AWS SSO Authenticate Event

{
“eventVersion”: “1.08”,
“userIdentity”: {
“type”: “Unknown”,
“accountId”: “123456789011”,
“userName”: “louay.shaat@gmail.com
},
“eventTime”: “2021–08–23T06:18:02Z”,
“eventSource”: “sso.amazonaws.com”,
“eventName”: “Authenticate”,
“awsRegion”: “eu-west-1”,
“sourceIPAddress”: “54.240.197.233”,
“userAgent”: “Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36”,
“requestParameters”: null,
“responseElements”: null,
“requestID”: “b9d00158–3274–48ad-9ee1–572035dbd0ce”,
“eventID”: “6be15a19-c7d1–4b5f-b943–23d472293cd0”,
“readOnly”: false,
“eventType”: “AwsServiceEvent”,
“managementEvent”: true,
“recipientAccountId”: “2345678901111”,
“eventCategory”: “Management”
}

In this event, you can see the userName used to authenticate “UserName”, “SourceIPAddress”, receipientAccountId (account logged into). This gives us enough information to be able to model user activity.

AWS SSO Federate Event

{
“eventVersion”: “1.08”,
“userIdentity”: {
“type”: “Unknown”,
“accountId”: “123456789011”,
“userName”: “louay.shaat@gmail.com
},
“eventTime”: “2021–08–23T06:18:10Z”,
“eventSource”: “sso.amazonaws.com”,
“eventName”: “Federate”,
“awsRegion”: “eu-west-1”,
“sourceIPAddress”: “54.240.197.233”,
“readOnly”: false,
“eventType”: “AwsServiceEvent”,
“managementEvent”: true,
“recipientAccountId”: “1234567890”,
“serviceEventDetails”: {
“role_name”: “AdministratorAccess”,
“account_id”: “2345678901111”
},
“eventCategory”: “Management”
}

The Federate Event focus on the Role assumed and the account you federated into. “role_name” and
“account_id” fields give us more information on the activity of the user.

The main thing to consider in these events is understanding users, sourceIPs, Target Accounts. These give us rich information on typical user activity

AWS IAM has AssumeRole and ConsoleLogin events that give you similar level of insights.

Example of ConsoleLogin

{
“eventVersion”: “1.08”,
“userIdentity”: {
“type”: “IAMUser”,
“principalId”: “AIDA1234567898”,
“arn”: “arn:aws:iam::123456789012:user/louay”,
“accountId”: “123456789012”,
“userName”: “louay”
},
“eventTime”: “2021–08–23T06:39:10Z”,
“eventSource”: “signin.amazonaws.com”,
“eventName”: “ConsoleLogin”,
“awsRegion”: “us-east-1”,
“sourceIPAddress”: “72.21.198.65”,
“userAgent”: “Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Safari/605.1.15”,
“requestParameters”: null,
“responseElements”: {
“ConsoleLogin”: “Success”
},
“additionalEventData”: {
“LoginTo”: “https://console.aws.amazon.com/console/home?fromtb=true&hashArgs=%23&isauthcode=true&state=hashArgsFromTB_us-east-1_62d001060064b8d8",
“MobileVersion”: “No”,
“MFAUsed”: “No”
},
“eventID”: “61578602–9627–4b96-ae76–54cc69858e07”,
“readOnly”: false,
“eventType”: “AwsConsoleSignIn”,
“managementEvent”: true,
“eventCategory”: “Management”,
“recipientAccountId”: “123456789012”
}

The reason I’m highlighting the difference here is consolidation. AWS SSO consolidates all these Events in the management account, while AWS IAM logs in every account. From an auditing perspective, having a single location detailing user activity and what role are assumed to which accounts makes my life simpler to be able to build automation to respond to any anomalies we see.

AWS IAM or AWS SSO?

Having a look at both services and how we can satisfy our multi account structure, both architectures are quite different and both have advantages and disadvantages.

Multi Account Federation leveraging AWS IAM

AWS has quite a few resources on how to integrate AWS IAM with AzureAD, the integration is based on creating a SAML trust with the IAM identity provider of the management account of your AWS Organization with Azure AD application gallery.

Once a user is authenticated and assumes a role in the management account, they can now assume a role in the destination account.
STS assume role becomes the main mechanism to assume the correct role in the required account.

Assume role operations

The diagram above explains how

Below is a solution released by AWS to help you automate the build of the necessary IAM users and roles in all accounts in your AWS Organization.

Source: https://docs.aws.amazon.com/prescriptive-guidance/latest/patterns/automate-saml-2-0-federation-for-aws-multi-account-environments-that-use-azure-ad.html

The main things to consider with this architecture are:

  • All Users have to authenticate to the management account (single entry point to the whole AWS Organization)
  • Users need to know the Account ID and Role to be able to assume that role in the destination account
  • AzureAD integration relies on using IAM Users with Access Keys to be able to synchronize the roles for federation
  • We need to build automation to ensure all new child accounts have a similar setup

AWS SSO

AWS SSO works differently from AWS IAM, Firstly SSO is a regional service deployed in the Management Account while AWS IAM synchronizes to all regions you have opted in for.

AWS SSO is Fully integrated with AWS Organizations and has direct visibility to all accounts you have provisioned, giving you the ability to deploy permission sets automatically across multiple accounts.

AWS SSO gives you 3 options for building your Identity Source

In our case, leveraging the external Identity gives us the ability to integrate with AzureAD.
AWS SSO also supports SCIM (System for Cross-domain Identity Management), SCIM keeps your AWS SSO identities in sync with identities from your IdP. This includes any creation, updates or deletion of users between your IdP and AWS SSO.

AWS SSO also separates Authentication and Authorization mechanisms.
Authentication is done with your connected IdP and authorization is done within AWS SSO itself.

Example above is AWS with Microsoft AD

Main things to consider with this architecture

  • No IAM Users, fully managed SAML integration
  • AWS Organizations integration
  • AWS CLI integration with multiple profiles including session timeouts (This is a killer feature, building this with Native IAM is complex)
  • SCIM implementation with AzureAD has a 40 min delay

Note: AWS has a custom solution using PowerShell script to initiate an on-demand synchronization between Azure Active Directory and AWS Single Sign-On (AWS SSO) and avoid the default 40-minute synchronization schedule between both identity providers. here

Next steps

After careful evaluation of the options we have, we decided that leveraging AWS SSO is the best move forward. AWS SSO provides us with these 4 advantages that make our identity adoption in AWS seamless and more automated

  • Lifecycle management of Permission Sets, we have the ability to create a Permission Set once and deploy it to our child accounts. Any modifications or deletions are replicated to these accounts
  • Delegation Models, AWS SSO provides multiple delegation models, enabling us to give limited access to Account/Team Owners to manage permissions for their teams

More info here: AWS SSO Delegation Blog

  • AWS SSO Applications gives us access to your cloud applications. Users get one-click access to these applications after they use their directory credentials to sign in to their user portal.
  • Management and deployment of IAM Identity provider in all child accounts

In our next blog, we will dive deeper into our AWS SSO deployment and how we built a hybrid ABAC and RBAC model to support dynamic identities in AWS. We will also cover how we leverage AWS SSO to authenticate to services including AWS Client VPN and Workspaces.

--

--