How to use AWS IAM Authentication with MongoDB 4.4 in Atlas to Build Modern Secure Applications
Imagine a scenario where you use AWS IAM Authentication across cloud cloud services in your cutting edge secure application and had wanted that your application could validate with MongoDB Atlas clusters along these lines. With MongoDB 4.4, Atlas adds native support for AWS IAM Authentication.This post will talk about how it functions, and how it very well may be utilized to make and convey present day secure application architectures.
Introducing a new authentication mechanism for MongoDB Atlas clusters named MongoDB-AWS, a unique new way to work with your MongoDB Atlas clusters that offer seamless integration with AWS.
The new MongoDB-AWS authentication mechanism is available to MongoDB 4.4 Atlas clusters at the M10 level and above.It’s exclusive to MongoDB 4.4 clusters and MongoDB Atlas. It supports cross-cloud, it does not matter which cloud providers your application or your Atlas cluster are hosted in, you can freely mix and match cloud providers. The new mechanism is supported by all official MongoDB Drivers and the shell. Furthermore, it has deep integration with various AWS services which I will go into.
The new authentication mechanism builds on the existing AWS IAM and security token services. It support the STS AssumeRole API, it also integrate with AWS’s multifactor support because of our support for AssumeRole. The new authentication mechanism has been tested and integrates with Lambda, EC2, and ECS. Finally, it support authentication for both IAM users and roles.
As mentioned on the previous slide, MongoDB-AWS supports two different types of AWS IAM types. The first, IAM roles are typically used for applications for service to service authentication, but can also be used in functionality like AssumeRole. This is a very powerful feature of AWS IAM, it works very well when paired with MongoDB Atlas clusters.
The second IAM type that it support is IAM Users. These are typically used by human operators. You typically use them with a program like the shell.
Now moving on, let’s talk about Role Authentication. Role Authentication is the most powerful feature and where the new authentication mechanism shines. There are two uses of Role Authentication, applications and users who assume a role. In the first case, your application will be running on an EC2 machine, an ECS container, or in Lambda. The second case, you can use STS AssumeRole functionality to assign permissions to roles and then control which users can assume that role. For instance, you might have MongoDB App Role Operator that grants all the actions needed to manage all the pieces of the example in a Canonical application. Then instead of granting users that role, you grant them the ability to assume that role. It’s going to be better audited and managed. This added layer of indirection makes permissions easier to manage since you can organize roles around tasks, and it also supports multi-factor authentication.
in the Atlas UI to actually add a role. First, select AWS IAM as the authentication method. Next, select IAM role for the AWS IAM type. Finally, enter your AWS ARM.
Notice, there is no password store. I’ll explain more about that later.
As we saw on the previous screenshot, adding an Atlas user that authenticates via an AWS IAM role is very easy. To start, you just need the ARN for the role and then choosing to add an AWS role user. On any other side, you just need to assign the same role as the execution role to your container EC2 or a Lambda function that hosts your application. You do not need to grant any special AWS actions to the role to make it work with MongoDB. For your application, it’s even simpler to add support for MongoDB-AWS. Use update to the new URL that points to your cluster and you’re done. You do not need to specify a username or password anymore.
Note, the URL does not contain a password.
If you notice in the previous slide, there was no password, but we’re still able to authenticate to our MongoDB Atlas cluster. You may be asking, what’s the catch? Is it really passwordless?
Yes, but while there is still a password, you no longer need to manage the passwords. That is the important part. Any of the services support execution roles. Execution roles allow you to assign a IAM role to either an AWS, EC2 machine, ECS container, or Lambda function. You can then associate permissions to this role and allow to access IAM services. Under the covers, AWS provides the application running on one of these compute services with a set of temporary credentials that can be used by the application to talk to AWS services. When you use an official AWS SDK, the SDKs automatically retrieve these credentials for you. We’ve mirrored the same functionality as the AWS SDK into the official drivers for MongoDB 4.4. When you pass a connection string for MongoDB-AWS, the driver will seamlessly use the temporary credentials for you. It also designed it for the most sensitive security situations, your secret key is never passed to the MongoDB Atlas clusters, it’s never persisted by the driver.
I’m going to go into more detail and explain how that works over the next few slides. These slides will make it clear why the passwords are never sent over the wire to the Atlas clusters.
When you log in with the new authentication mechanism, MongoDB-AWS, there are three pieces involved in the login handshake. The first piece of the puzzle is your application with the driver that supports a MongoDB 4.4. That’s 4.4 Atlas cluster. All the official drivers have support for the new authentication mechanism. The second piece is a MongoDB Atlas cluster running MongoDB 4.4. The new automatic is only supported in M10 clusters or above. Finally, the AWS Security Token Service, which the MongoDB Atlas cluster uses to validate the credentials. This is a standard service available in all AWS regions. There’s nothing to enable or configure on a user’s end.
First, on the far right side of the slide, the AWS Security Token Service, the red box, which is used by the Atlas cluster. The MongoDB Atlas cluster talks to the STS service to validate the identity of the user.
In the next set of slides, we’ll break down the onetime setup in AWS and Atlas, and then I will break down the three main steps in authentication.
The first step in the onetime setup is set up the AWS service with support for temporary credentials. First, you create an IAM role. You don’t need to assign any special AWS actions for MongoDB Atlas. The authorization checks are still done by MongoDB Atlas, in this case, not AWS. That’s why there’s no need to add any particular actions to the IAM role.
Next, we need to assign the IAM role to an ECS container. To do this, you assign a task execution role in the ECS task definition. The act of assigning a IAM role to an ECS task enables the MongoDB driver to get temporary credentials at runtime. Please note that if you have an existing task definition, you may not need to make any change. If the container already accesses an AWS service like S3 or needs to retrieve images from a private elastic container service, it will already have a task execution role assigned to it. You’ll just need to note the assigned roles that it can be added in Atlas.
Instead of step two, you need to add the task execution role as a user of the MongoDB Atlas cluster. Note that in this step, you do not provide any credentials to MongoDB Atlas, you only provide the ARN that should be permitted to log on to Atlas, just the string. Also, at this time, you must decide what set of permissions this ARN should have in Atlas. That is all you need to do for the one-time setup.
Now, we discuss the three steps in the authentication process. The first step is to get the temporary credentials. These credentials have an expiration time and are periodically refreshed automatically by AWS. The MongoDB driver seamlessly retrieves them from the local machine, container, or lambda function as appropriate. On the EC2 and ECS, the driver uses the AWS instance metadata service version to retrieve the credentials.
IMDSv2 protects against server-side request forgery and was just released in November. This upgraded version of IMDS was really steering the development of the off-mechanism. It quickly pivoted our design to take advantage of it since it offered the most robust security. When running Lambda, the credentials that exposes environment variables still function, so retrieving them is a lot simpler than making the HTTP calls required to the AWS instance metadata service.
it consists of three important pieces that are highlighted in yellow and red. Going from top to bottom, they are access to key ID which is in yellow, secret access key, which is in red, and token, which is in yellow. These three pieces together allow the application to login to a MongoDB Atlas cluster. As I mentioned before, the secret access key, the red text tier is never sent to Atlas. I’ll explain how it works in a moment. The access key and security token, the yellow texts, are sent to Atlas. These are merely identifiers, not secret information, and are safe to transmit over TLS connection to Atlas.
In the second off step, the driver sends the credentials to your MongoDB Atlas cluster. I will show you what is actually sent to the next level, but let me emphasize again that the secret key is not sent. The driver specifically sends three pieces of information. These three pieces are signature, which I’ll explain later, the date and time the message was generated, and the security token. These three pieces allow Atlas and AWS to determine that the driver knows a secret access key without having to actually send the secret access key over the wire.
If you’ll notice, there are two yellow pieces of text. These pieces are the same pieces highlighted in the previous slide, the account key, and see the security token. As I explained before, there is no security key sent, which was highlighted in red text before.
The most important piece of this content is the signature, highlighted in blue. The correct signature for a given access key can only be generated by something that knows the secret key. I’ll explain more in a later slide how it is calculated.
In the final step of authentication, MongoDB Atlas cluster takes the signature and sends it on to the AWS Security Token Service. In this case, the Atlas cluster just makes a regular HTTPS call to AWS STS service. The AWS STS service validates whether the signature is correct, replies with ARN of the application that created the signature. After MongoDB gets an acknowledgment from STS, authorization information is retrieved from MongoDB. This means that all the role information, authentication, restrictions, etc.. for the IAM role are stored in MongoDB, not AWS in this case. Information about database role membership continues to be managed on the MongoDB side, only authentication is managed by AWS. You continue to use Atlas for all your database role management.
If the signature is incorrect or the temporary credentials are expired, for example, STS will return an error, and the MongoDB log on fails. More information about why it fails can be found in the MongoDB error log.
For MongoDB Atlas to verify their credential, it makes a HTTPS call to the STS GetCallerIdentity API. GetCallerIdentity is a free API that tells the caller the ARN of the account that generated the signature. You can call yourself via the AWS command line or any AWS SDK. This could be used to identify which account and account key and secret key belong to for instance.
Finally, you’ll notice that there are two yellow pieces of text highlighted above. These are the same yellow piece of text highlighted in the first message example, the account key in the security token, so explained, there’s no secret key which was highlighted in the red text before. The signature, highlighted in blue, is a compound SHA-256 HMAC calculation of all the headers in the body of the HTTPS requests. The algorithm to compute the signature is rather involved and is called the AWS Signature Version 4.
To create the signature, you need to know the secret key for the account key. Our example diagram for our Canonical application, only two components know the secret key, the ECS container, and the STS service. The driver gets the secret key from the temporary credentials and then tries to prove it knows the secret key by sending the signal to the STS service. The reason why the account key is sent to the STS service, the STS service knows which secret key to use for computing the signature. The STS service verifies to ensure it’s correct by recalculating the signature using its copy of the secret key. If it computes the same answer, then the request is considered valid and proceeds. If the signature does not match, a HTTP status code of 403, i.e., forbidden, is returned instead.
The area on the role highlighted in blue is returned. This is checked against the list of users in your MongoDB Atlas cluster. So if the user with the same name as this ARN, the authentication is successful. If no user was found with that ARN, the logon fails.
As mentioned earlier, It also support user authentication. The process of adding a user is identical to adding a role. First, you select AWS IAM as authentication mechanism method. Second, you select the IAM user for AWS IAM type. Third, you enter the AWS user ARN.
Every user has an AWS ARN associated with them. There’s a globally unique string that identifies an AWS account and user within that account. The ARN for a given user can be retrieved from the AWS console on the web page.
Finally, to login with this ARN, you use the AWS access key and AWS secret key associated with that user. You don’t actually login with the ARN itself. That’s why the ARN does not show up in the connection string. ACS tells your MongoDB cluster your ARN if you know the correct secret key for the account, the key you specify, but please note, as we explained in the Role Authentication part of this presentation, the secret key is never sent to Atlas.
MongoDB-AWS is a new mechanism to authenticate with Atlas clusters. You can use AWS credentials natively across all AWS services and MongoDB Atlas clusters within your application. It works across Atlas clusters, and Azure, and GCP, it is available in MongoDB Atlas June 2020, and it’s supported in all official MongoDB 4.4 drivers; C, C++, C# , Go, Java, Node.js, PHP, Python, and Ruby.