I am confused about the use cases and advantages of STS. As per the documentation, it is to temporarily acquire a role to perform tasks within AWS which are not available for the IAM user or service. Please note that I am talking about programmatic access (NOT console access)
For example, an IAM user may not have S3 permissions. As per my understanding:
He can get temporary access key/token by contacting AWS STS and get access key and secret for S3.
With those temporary credentials, he can access S3.
My questions are:
To get temporary credentials from AWS STS, he still need his existing access token (permanent) and secret, right?
If his existing access token and secret are leaked, an attacker can still use it to first get temporary credentials from STS and then access S3, right? I understand that the attacker won't be able to directly access S3 using his permanent access token and secret.
I am trying to wrap my head around its correct use cases. I know that I'm confused, but maybe I'm thinking in loops.
Thanks in advance.
They don't so much "contact AWS STS and get access key and secret for S3". Rather, they call AssumeRole() on an IAM Role that has permission to access Amazon S3. Then, using the temporary credentials that are returned, they can access S3.
Your confusion seems to be mostly around the use-case for IAM Roles. I like to explain it by way of a story...
I am a Fire Warden in my office at work. If the Fire Alarm activates, I go to a cupboard, put on a red helmet, then walk around the office and direct people to the stairwell. Since the alarm is sounding and I'm wearing a red hat, people (mostly) do what I tell them. However, if it was a normal day with no alarm sounding and I wasn't wearing the red hat, and I asked them to exit the office via the stairwell, they would likely look at me strangely and ignore my request. The difference is that I assumed the role of a Fire Warden, which gave me extra permissions.
So, as a normal person, I can't order people out of the office. However, once I assume the role, I have extra permissions.
This is a good practice for IT systems, too. The Systems Administrator in your company probably has permissions in your AWS Account to do anything. However, it would be a bad practice for them to use an account with such powers on a day-to-day basis. Instead, their IAM User account should just have normal permissions but, if they want to do Admin-type stuff, they have the ability to Assume an Admin Role and then do powerful stuff. When they're finished, they should exit the role and keep being a normal user. This is much 'safer', since they can't accidentally do something powerful when they are a 'normal user'.
Amazon Security Token Service (STS) is also used to provide permissions to software running on Amazon EC2 instances. In this case, an IAM Role is assigned to the EC2 instance and the EC2 service 'assumes' the role on behalf of the instance. It then provides the temporary credentials via the EC2 Instance Metadata service. In this example, there was no IAM User that assumed the role. Instead, the EC2 service assumed it on behalf of the instance.
STS can also provide cross-account permissions. For example, an IAM User in Account A could call AssumeRole() on an IAM Role in Account B. If they have permission to do this, then they will be given temporary credentials that are associated with Account B. This is required because credentials from one Account can never be used to manage resources in another Account.
There are other reasons for using temporary credentials too, such as using MFA tokens, federated logins where there are no IAM Users, and reducing your own set of permissions.
I will try to extend and generalise the first answer. The example with the Fire Warden is good to understand, but I feel it needs some extension.
Generally the AWS STS is able to return role credentials based on other identity or role credentials (aws or other identity provider).
The original credentials can be either AWS credentials from the same account, another account, federated token (e. g. supported social networks) or even a custom identity broker.
see https://docs.aws.amazon.com/cli/latest/reference/sts/index.html
Common use cases:
privilege elevation - this is already mentioned, AssumeRole allows to become another role within the same or different aws account
authorization to aws resources for identities authenticated a other way (AD, SAML, OIDC,..), see services AssumeRoleWithSAML or AssumeRoleWithWebIdentity.
authorization to aws resources with custom authorization, see GetFederationToken.
To get temporary credentials from AWS STS, he still need his existing access token (permanent) and secret, right?
By default AssumeRole, the user needs to be authenticated and having permission to assume the role.
If his existing access token and secret are leaked, an attacker can still use it to first get temporary credentials from STS and then access S3, right?
yes
I understand that the attacker won't be able to directly access S3 using his permanent access token and secret
if you configure the S3 or IAM permissions that way
Related
We have an external application resides outside of Amazon network and it needs to access our SQS and send message there, in order for our AWS resource to recognize the request from that application it needs to sign its request with the credentials of the IAM role we created, I'm wondering what is the best way for that external application to retrieve temp credentials from us? I have tried to implement it using Amazon Cognito but it looks like Cognito fits more in scenarios like user sign-up and sign-in with an User Interface, anyone has any suggestions? Thanks in advance.
To be able to obtain temporary credentials, you need a form of permanent credentials that can access (or generate) the temporary credentials.
Given your situation, you might consider creating an IAM User in your account and giving those credentials to the third-party. Grant the appropriate permissions to those credentials and they can use them directly with Amazon SQS.
Or, if you'd rather not give IAM credentials to third-parties, you could ask them to create an AWS account and an IAM User. You could then grant their IAM user access to the Amazon SQS queue.
Another option is that the third-party could access an application or API that you provide. Once they authenticate, you can provide temporary credentials created with the Security Token Service. Cognito would be an option for performing this authentication and it can also provide credentials for an associated IAM Role, thus giving them access to the Amazon SQS queue.
lets say I have a on-premise application that needs to access various AWS services such as S3, Cloudwatch etc. What is the correct way to handle this authentication? I have read recommendations to create a new iam role and then distribute the AWS keys on the server that the application runs. But wouldn't this be very bad practice in case the keys gets stolen or exposed in some way? It would also be more work to rotate credentials for example. Is it possible to assign roles in some other ways or this is the correct way to do it? Isn't it better to assign roles or that isn't possible when not running the app in AWS?
Creat an IAM user with “Programmatic Access” only, which will provide you with a key and secret pair.
As a general rule, your application can use one set of credentials to get another, more privileged set of credentials. The app must be able to authenticate somehow so it needs some basic form of service account credentials to start with.
One way you can do this is to create an IAM user with minimal privileges. This IAM user is able to assume a specific IAM service role, but nothing else. That service role actually confers permissions to interact with S3, CloudWatch etc. Your application is configured with, or somehow securely retrieves, the credentials associated with the IAM user. Your application then uses these to call STS and assume the IAM service role, getting back short-lived STS credentials (access key, secret key, and session token). You should leverage the additional 'external ID' with the IAM role, as one more security factor.
Your application is also responsible for getting a new set of credentials before the existing set expires. You can do that in a number of ways, for example by using new STS credentials for every single request you make (so they never expire) or simply paying attention to the credentials expiration time and refreshing prior.
Also, read Temporary Credentials for Users in Untrusted Environments.
If your application is running on an Amazon EC2 instance and it is the only application on that instance, then:
Create an IAM Role
Assign the appropriate permissions to the Role
Assign the IAM Role to the EC2 instance
Any software running on the instance will automatically have access to credentials to access AWS. These credentials automatically rotate every 6 hours.
If you are not running on an EC2 instance:
Create an IAM User
Assign the appropriate permissions to the User
Generate credentials for the User (Access Key, Secret Key) and store them in a credentials file on the computer being used by the application
Any software running on the instance will automatically have access to these credentials to access AWS.
I'm told sharing IAM roles with third parties is more secure than sharing IAM keys. Currently we limit IAM keys with IP filters, many conditions on access control.
Why would sharing IAM roles be better. My understanding is they can use their role to assume privilege for a time limited period from something like the boto3 api. But if they can assume the role without limit, how is there a security benefit over a key?
First, as you mentioned, the short-lived session credentials used by a role limits the time that compromised credentials can be used.
Second, with an IAM user, any time the third party needs to access resources in your account, they must posses the access key and secret key of your IAM user. If they want to access resources from your account from an EC2 instance, they need to have a way to securely push the keys to the EC2 instance. If they want to access resources from a Lambda, they need to make the keys available to the Lambda. If they want to access resources from a mobile device, they need to push the credentials to the mobile device (where they are more difficult to secure, let alone rotate).
Managing these credentials is not only additional work for the third party, but also additional risk for you. The long-lived credentials for your IAM user are now being passed around by a third party.
Using an IAM role instead, you can allow the third party to access resources without passing your credentials around. An EC2 instance can avoid handling your credentials using EC2 instance roles. Lambda, similarly, can avoid handling your credentials by using execution roles. On a mobile device, there is Cognito.
To grant an external party access to the AWS resources owned by you, you have following options:
[WORST APPROACH] You create an IAM user (say, Foo) and grant it the required permissions and then share the same with the external parties. This is obviously the worst approach as now you have no segregation between who is making calls to your resources because in effect, it is always Foo who is calling you.
You let your clients create IAM users in their own accounts and then whitelist them in your resource's policy. This works, given that your resource supports resource-level policies (S3 and API Gatewaydo). Now, even if they do support resource-level policies, now it is an overhead for you to whitelist all such users created by all your clients, which can access the resource.
You create an IAM role, grant it capabilities (in terms of IAM policies) to access your resource and then whitelist your clients' IAM users to assume that role. This will be your way of saying that "this role is capable of accessing my resource and if you can assume this role, so do you". Moreover, this also prevents you from sharing the credentials as AWS STS does all that work in generating the temporary credentials for you.
This page shows how to send an email using SES. The example works by reading the credentials from ~/.aws/credentials, which are the root (yet "shared"??) credentials.
The documentation advises in various places against using the root credentials.
Acquiring temporary credentials
using roles is mentioned as an option, yet assume_role() is not defined for SES client objects.
How do I send an email through SES with temporary SES-specific credentials?
Update
The context for my question is an application running on an EC2 instance.
There are a few pieces to this.
First you need an IAM policy. You can use one of the built-in policies, such as AmazonSESFullAccess or you can create your own. The holder of a particular policy will be able to access the resources and actions defined in the policy. You can create this policy manually, or work through the AWS console and it will walk you through it. IAM --> Policies --> Create Policy
Secondly, you will need a role. Also, easily done in the console. IAM --> Roles --> Create role. Trusted entity is AWS service. Highlight EC2. In the next screen, select the policy you want to associate with this role. This is the policy you created above. If your EC2 already has a role, then you can add the IAM policy to this role. Assigning an IAM policy to a role, is what they refer to as a trust policy.
Now any code that runs on your EC2 instance will be able to send messages to your SES service. The EC2 assumes the role assigned to it. And the SES policy is defined for that role. This will allow EC2 to get temporary credentials (behind the scenes).
The back story is as follows. Any API call to an AWS service needs to have a key and secret. When you make API calls from your local computer, you may use your personal key and secret (or even root ones). When you need to make API calls from another service, you do not have that key and secret. It would not be secure or practical to store the credentials on an EC2. Or even worse, in an S3 bucket. That is why AWS came up with the Role concept. Roles can request temporary credentials from an internal service called Simple Token Service (STS). A role is attached to an EC2 instance for example. And if the right policy is attached to that role, the EC2 instance can request to get temporary credentials to make an API call to another service. All of this happens behind the scenes.
Two options...
You could create IAM User credentials with the appropriate permissions and put them in the ~./aws/credentials file. Then your application will find them and use them to connect with Amazon SES.
Or, your application could use a set of IAM User credentials to call assume_role() (which is an IAM command). This will return a set of temporary credentials that could be used with Amazon SES. However, if you are going to provide a set of credentials that will be used to call assume_role(), then you may as well just use those credentials directly with Amazon SES.
An IAM User can be used for people OR applications.
What is the difference between an IAM role and an IAM user? The IAM FAQ has an entry explaining it, but it was vague and not very clear:
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 such as EC2.
I think an IAM role is used for federated logins (using an IdP with SAML tokens for example), and they don't have permanent access keys that you can download like regular IAM users have (the "an IAM role doesn't have any credentials" part).
What do they mean when they say an IAM role can't make direct requests to AWS services? I can login to AWS Console (the web console) and create stacks etc, so it can't be that.
To understand the difference, let us go through IAM basic knowledge
IAM controls: Who (authentication) can do What (authorization) in your AWS account.
Authentication(who) with IAM is done with users/groups and roles whereas authorization(what) is done by policies.
Here the term
User - End user think about people
Groups- a set of users under one set of permission(policies)
Roles - are used to grant specific permission to specific actors for a set of duration of time. These actors can be authenticated by AWS or some trusted external system.
User and roles use policies for authorization. Keep in mind that user and role can't do anything until you allow certain actions with a policy.
Answer the following questions and you will differentiate between a user and a role:
Can have a password? Yes-> user, No-> role
Can have an access key? Yes-> user, No-> role
Can belong to a group? Yes-> user, No -> role
Can be associated with AWS resources (for example EC2 instances)? No-> user, Yes->role
AWS supports 3 Role Types for different scenarios
AWS service roles (for example: EC2, Lambda, Redshift,...)
Cross-Account Access: granting permissions to users from other AWS account, whether you control those account or not.
Identity Provider Access: granting permissions to users authenticated by a trusted external system. AWS supports two kinds of identity federation:
- Web-based identity such as Facebook, Goolge- IAM support ingeration via OpenID Connect
- SAML 2.0 identity such as Active Directory, LDAP.
To understand what role is, you need to read its use case, I don't want to reinvent the wheel so please read the following AWS documents:
https://aws.amazon.com/blogs/security/how-to-use-a-single-iam-user-to-easily-access-all-your-accounts-by-using-the-aws-cli/
https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_saml.html
Hope it helps.
Main actors in IAM are users, groups, roles and policies. And what you need to understand about AWS and never forget is that
Everything in AWS is an API
And to execute any API or any of its methods, first we have to authenticate and then authorize that particular user/group/role.
Ex: An operator wants to put an object to a S3 bucket. This process happens through a set of API calls within AWS. Basically we call the S3 API and a method of it to put the object into the particular bucket (say method put_object_in_s3). For that we may want to provide the name of the bucket, the object, and most importantly we need to provide set of credentials (username with password or secret key or etc) in order to tell the AWS API Engine who this user/group/role is.
The first thing API Engine does is, look at those credentials sent with the API. Then it validate those (whether they are correct, active) credentials indicating that this request is coming from a actual valid user, group or role. Then what the API Engine does is (as it now knows who sent this API request) it takes the policy documents associated with the particular operator (user or role) and evaluate them as a single view. That is we check whether the action called in the API is authorized for that operator.
IAM user - In the context of IAM, a user is a “permanent” named operator (human or machine). What’s important to note is that it’s credentials (credentials maybe username password or access key or a secret key) are permanent and stays with that named user. So by that AWS knows that what are the authentication methods (username password authentication method or secret key method or etc) for this user (as its permanent and stays with the user).
IAM group - As in the above image, a group is a collection of users. And note that a user can be in many groups as well.
IAM roles - Roles are not Permissions !!!. A role is also an authentication method just as IAM users and groups. As a user, a role is also a operator (could be a human, could be a machine). Difference is that credentials with roles are temporary.
Policy Documents - As stated earlier, roles are not Permissions. Permissions in AWS are completely handled by objects called Policy Documents. Policy Documents are JSON documents. Policy Documents can directly be attached to Users, Groups or Roles. When a policy document gets attached to any of above operator, then only they get permissions do stuff.
A policy document lists things like: Specific API or wildcard group of APIs that gets whitelisted against which resources, and Conditions for those API executions (like allow only if this user, group or role in the home network or allow from any location, allow only at certain times of day and etc)
Last but not least, Authentication in AWS is done via (IAM users,
groups and roles) whereas Authorization is done by Policies.
What do they mean when they say an IAM role can't make direct requests to AWS services? I can login to AWS Console (the web console) and create stacks etc, so it can't be that.
You are an IAM User (with some attached IAM Roles).
Think of IAM Roles as capabilities.
You give an IAM User capabilities (e.g. "can create Lambda function", "can upload to S3").
Note on Federated Users:
From http://docs.aws.amazon.com/IAM/latest/UserGuide/id.html:
A role can be assigned to a federated user who signs in by using an external identity provider instead of IAM. AWS uses details passed by the identity provider to determine which role is mapped to the federated user.
So, a federated user is similar to an IAM user which you can attach IAM Roles to. Except that you have an external identity provider.
Technically, you are NOT using a role as your identity when you login to AWS console. You are using your federated user account (with its own attached roles) as your identity.
An IAM user is an account which can be used by a person or an application. A user has credentials to log in and perform actions with the privileges assigned to that account.
An IAM role is something virtual that a resource can assume. For example, an EC2 instance can assume a role and execute AWS command with that assigned privileges. The same goes for other services like API gateway, Lambda, Kinesis, RDS and so on.
What do they mean when they say an IAM role can't make direct requests to AWS services?
The role itself is not able to perform any tasks since it has to be assumed by somebody or something. Somebody can also be someone logged in through identity federation and then assume a role.
I am practically new to AWS but I have implemented similar concepts in backend applications. Therefore, I would make an attempt to simplify this more from a newbie perspective.
IAM User - This is an actual account registered into the AWS IAM platform. This means that this is a person/application that is an actual entity. Note that this entity can do nothing, just an existence. Like when I signup for an application, my user entity is created and I can log in with provided credentials and have a profile.
IAM Group - This is a collection of specific users. Although this can also give identity, the focus is on the specific individuals that make the group. For example, how we group employees into departments in organizations based on their specific specialities and skillsets.
IAM Policies - This part seems easiest to understand. This is a specific rule/permission/access to a resource spelt out in clear dos and don'ts in a JSON format. Each policy is about a particular resource. A resource can be anything from an EBS volume, a Lamda Function, or even IAM itself.
IAM Role - This is like a title with specific responsibilities, i.e. a group of policies(permissions/access) that anyone with this title will have. For example, if we have a title of "Note-Taker", anyone from different departments can be assigned this title temporarily for a meeting, a period etc. And only those with this permission will be able to access the note-taking app. However, we can have some roles that will fit well with a group, e.g. all members of the accounting department can have the title of an accountant, which gives access to the books of account. But we can have another title of director, which has access to delete books of account, and this will cut across all departments.
Federated Users - These are entities also, but with no profile in the company(IAM). They are like contractors who can be assigned certain roles or titles through an acquired trust from the Federating platform as well as the access due to those titles. The good thing is that if the Federating platforms replace a user, there would be no reason to deactivate the old user and give access to the new one because the platform is the one with the access and not the "user".
IAM User - An user/application accessing AWS Resources
IAM Roles - Set of permissions/policy that can be applicable to an user or resource.
You can apply Roles to IAM user and to an AWS Resource too.
E.g., Apply IAM Role to Lambda Function. Function can only with that IAM Role.
IAM role is an entity which has specific access defined by the policy. And that access is. It doe snot have the permanent creds (Access keys and Secrets Access Keys)- it works on the "AssumeRole" method where token is granted for accessing the different AWs resources.
IAM User has the permanent access keys and secret access keys, we can define the permissions on the resources , IAM ROLE can be assumed by the IAM USER , as it has the keys - it can have access to the resources all the time...
IAM Policy (permissions- read,write etc.) apply to User,Group and Roles.
User- when a user want to access anything in AWS cloud, it must have IAM policy assigned.
Group - when a group of users is assigned with common IAM policy.
Roles - It needs when a service want to access another service. Service must be assigned with role that have policy assigned to perform certain actions in the AWS cloud. In other words, We can't directly assign policies on Service, first we need to create Role and then assign policy on that role.
Note: Roles are intended to be not used by physical people, instead use by AWS services only.