Unable to sts:AssumeRoleWithWebIdentity for a Cognito user - amazon-web-services

I have a simple use case to authenticate a user using AWS Cognito and the assume a role to be able to do something useful (read from S3 in my case). Apparently I am missing something very obvious.
I am using pure web http client with cognito authentication (so Cognito can federate other identity providers) and the backend receive only the id_token.
I could get session credentials using getCredentialsForIdentity, apparently this credentials have assigned permissions from the role defined by the Cognito identity pool (in my case Cognito_demoidpoolAuth_Role)
My idea was creating another role which the federated web identity could assume.
So I created a new role for Web Identity, the role to access the data has Trust Relationship with following policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "cognito-identity.amazonaws.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"cognito-identity.amazonaws.com:aud": "eu-central-1:500a5721-abca-xxxx-xxxx-c15625a7xxxx"
}
}
}
]
}
Following code should assume the role needed to read from the bucket
WebIdentityFederationSessionCredentialsProvider credProvider = new WebIdentityFederationSessionCredentialsProvider(
idToken,
null,
"arn:aws:iam::535544306598:role/docmgr-test-role" );
under the hood this object calls assumeRoleWithWebIdentity and I get following exception:
com.amazonaws.services.securitytoken.model.AWSSecurityTokenServiceException:
Not authorized to perform sts:AssumeRoleWithWebIdentity (Service: AWSSecurityTokenService;
Status Code: 403; Error Code: AccessDenied; Request ID: 059e56ee-25c8-11e8-8852-f7ca4d49742b)
Calling directly STS assumeRoleWithWebIdentity with the id_token ends with the same result, so apparently I have set wrong policy or trying to do things wrong way.

Related

AWS API Gateway - Issues in setting up cross-account access

I am trying to use an existing API gateway which is present in accountA. I am having some EC2 instances which are having some scripts to invoke the API gateway present. These instances may/may not reside in the same AWS account as the one where my API gateway is present (Let's call the other account as accountB).
For the authentication part currently, there's only AWS_IAM authentication implemented at the API gateway level. The EC2 instances (in both the accounts) are having IAM roles attached which are having IAM permissions to invoke the API.
The permission for the same looks as:
{
"Sid": "InvokeAPI",
"Effect": "Allow",
"Action": "execute-api:Invoke",
"Resource": "*"
}
When I try to invoke the API from the instances which are in accountA, it is working as expected. However, when I try to invoke the API from my instances in accountB, the gateway returns a 403 error with the following message:
User: arn:aws:sts::accountB:assumed-role/invoke_api_iam_role/i-xxxxxxxxx is not authorized to access this resource
I tried to look at API gateway resource policies and tried to whitelist the accountB's EC2 IAM role in accountA API Gateway's resource policy and still, I'm getting the same error.
Current resource policy implemented at the API gateway kinda looks like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::accountB:role/invoke_api_iam_role"
},
"Action": "execute-api:Invoke",
"Resource": "arn:aws:execute-api:us-east-1:accountA:myAPIID/*"
}
]
}
For signing the requests to the API gateway through the awsv4 signature, I use aws-requests-auth
Please help to resolve this issue.
So as it turns out, everything above is correct and you need to deploy the API to a particular stage for applying the resource policy against it.

API Gateway does not have permission to assume the provided role, yet role seems to have them attached (sts assume role)

I test my API Gateway but I get:
Sat Nov 09 02:12:13 UTC 2019 : Execution failed due to configuration error:
API Gateway does not have permission to assume the provided role
arn:aws:iam::193693970645:role/service-role/DoubleMeLambda-role-0erzzpmz`
However, my API Gateway uses:
arn:aws:iam::193693970645:role/service-role/DoubleMeLambda-role-0erzzpmz
and that role has
I made it super powerful (*) to try and get it to work but that didn't help
The lambda uses the same role (not ideal in real world I know but it seems like it should work):
I edited the trust relationship for that role and added:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
You'll need to configure a trust relationship between your IAM role and API gateway / lambda so that it can assume your IAM role:
https://docs.aws.amazon.com/directoryservice/latest/admin-guide/edit_trust.html
The permission you have granted, is for anyone with that role to be able to assume another role, rather than allowing anyone to assume that role.

AWS Cognito and Kibana: it does not ask for credentials

We have configured Cognito and Kibana to use the Cognito pools for authentication, but when I open Kibana endpoint - it just let me in, without asking for login / password. We used this doc, but IAM part isn't quite clear.
In ES cluster I see:
Amazon Cognito for authentication: Enabled
Cognito User Pool: my-user-pool
Cognito Identity Pool: my-id-pool
IAM Role Name: the_role_name
the_role_name has standard AWS-managed AmazonESCognitoAccess attached.
I'm a bit confused that at VPC we have
IAM Role: AWSServiceRoleForAmazonElasticsearchService
The identity pool has Enable access to unauthenticated identities disabled.
So, how to enable the authentication properly?
There were missing permissinos in elasticsearch "access policy", was needed like that:
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::1111111111:role/acl-Cognito-Auth-Role-my"
},
"Action": "es:ESHttp*",
"Resource": "arn:aws:es:eu-west-1:1111111111:domain/es-name/*"
}

DynamoDB fine-grain access with Lambda

I'm trying to access user data in DynamoDB table using identity level fine grained access. For user authentication I'm using Developer Authenicated Identities.
To accomplish that my policy includes:
{
"Action": [
"dynamodb:GetItem",
"dynamodb:UpdateItem"
],
"Effect": "Allow",
"Resource": "arn:aws:dynamodb:eu-west-1:817949094961:table/Users",
"Condition": {
"ForAllValues:StringEquals": {
"dynamodb:LeadingKeys": [
"${cognito-identity.amazonaws.com:sub}"
]
}
}
}
When trying to access user's data from DynamoDB table - in a Lambda function I'm getting following error:
Error in updateUser: AccessDeniedException: User:
arn:aws:sts::12312313:assumed-role/LambdAuthEditAccount/awslambda_123_20160410184653936
is not authorized to perform: dynamodb:UpdateItem on resource:
arn:aws:dynamodb:eu-west-1:12312312:table/Users"}
However it works just fine when accessing DynamoDB directly from the client browser using JS API - fine-grain access control works correctly. The policy block above is added to both user authenticated role and the role assumed by Lambda function.
I'm wondering if the role assumed by the Lambda (included in the error above) shouldn't resolve to user authenticated role?
Above policy will not work for the role assumed by lambda function, since it requires the id token issued by Cognito to assume the role and get credentials.
You can try the following approach:
1) Pass the identity id and the token (received from GetOpenIdTokenForDeveloperIdentity) to the lambda function.
2) Call getCredentialsforIdentity from lambda function and pass the identity id and above token in logins map.
3) Use these credentials to access to dynamoDB.

AWS Cognito Invalid identity pool configuration

I am using the AWS Javascript API and trying to get the assigned cognito id:
AWS.config.credentials.get(function(err) {
if (!err) {
console.log("Cognito Identity Id: " + AWS.config.credentials.identityId);
}
});
Why does this result in a 400 error with the message below?
{"__type":"InvalidIdentityPoolConfigurationException","message":"Invalid identity pool configuration. Check assigned IAM roles for this pool."}
I have IAM roles configured for authenticated and non-authenticated users.
{
"Version": "2012-10-17",
"Statement": [{
"Action": [
"mobileanalytics:PutEvents",
"cognito-sync:*"
],
"Effect": "Allow",
"Resource": [
"*"
]
}]
}
The most common reason for this error is your roles aren't set up to trust your identity pool. You should confirm that the identity pool id listed in your trust relationships matches the identity pool you are using.
More info on trust relationships in Amazon Cognito can be found in our developer guide.
After some digging I realized that you must add the RoleArn and AccountId to your credentials.
Even though most of the documentation out there mention this as being enough:
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
IdentityPoolId: 'us-east-1:xxxxx-a87e-46ed-9519-xxxxxxx',
});
This was not enough.
I had to do this:
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
IdentityPoolId: 'us-east-1:xxxxx-a87e-46ed-9519-xxxxx',
RoleArn: 'arn:aws:iam::xxxxx:role/Cognito_xxxxUsersUnauth_Role',
AccountId: 'xxxxxxxxx', // your AWS account ID
});
You must mention the ARN of your Role for your identity pool.
The only doc that mention it right is this one.
The wrong ones:
http://docs.aws.amazon.com/AWSJavaScriptSDK/guide/browser-configuring.html
https://mobile.awsblog.com/post/TxBVEDL5Z8JKAC/Use-Amazon-Cognito-in-your-website-for-simple-AWS-authentication
https://blogs.aws.amazon.com/javascript/post/TxTUNTVES4AL15/Authentication-in-the-Browser-with-Amazon-Cognito-and-Public-Identity-Providers
Maybe I'm missing something but this is certainly confusing.
Check the "Trust Relationship" section of the role that is assigned to your Identity Pool, authentication users.
Make sure you have policies defining access to your Cognito pool.
The easiest way to get the requirement policy statements is,
Edit the pool
Create new role for identity pool
In IAM edit this role to copy the policy statements
Add these Trust Relationships to your required existing role
Another - probably less common - reason: Make sure that you are actually using an identity pool and if not, remove the identity pool id from your aws-exports.js.
I was getting this error after adding federated sign ins to my user pool (not identity pool). For reasons unknown my config included an aws_cognito_identity_pool_id. Removing this id solved the error for me.
I checked the Trust Relationship of my roles configured for "Authenticated role" and "Unauthenticated role" for my identity pool more than once, but still the error occured.
After reviewing my whole identity pool configuration I recognized that in
Authentication providers
Cognito
Authenticated role selection
I have chosen "Choose role from token" and my wrong configured role was the one I attached to the cognito group for my users.
So updating the Trust Relationship for this role fixed the problem.
Hope this helps someone :)
In my case, I am using SAML identity provider. The action in the IAM role policy should be: "Action": "sts:AssumeRoleWithSAML". But this is the root cause of the exception. I have to manually change it to "Action": "sts:AssumeRoleWithWebIdentity". It turns out any role created by the Cognito identity pool will use "Action": "sts:AssumeRoleWithWebIdentity". It won't check your identity provider type. I believe this is a bug.
I encountered this error and my problem turned out to be that my user was assuming an unauthenticated role because I was returning AWSTask(result:nil) from the logins() function in my custom CognitoDeveloperIdentityProvider.
I had the same error when trying to retrieve files from S3 through my Identity pool users.
Solution: You can create a role in IAM for "Web Identity". Then provide your identity pool ID and add the permissions that you want the role to have, e.g. S3FullAccess. Then navigate back to Amazon Cognito Identity pools and assign the role you just created to the unauthrole or authrole. The users in the Identity pool should now be able to access the S3 resources
Another -way less probably scenario- is that either the provider or identityPoolId you are using is invalid. I spent hours debugging a missing ENV in my code.
Had this issue, after several hours of checking our what the problem could be, found out that the Trust Policy is actually missing this line sts:TagSession in the Action List so eventually the Authenticated Trust Policy is as defined below:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "cognito-identity.amazonaws.com"
},
"Action": [
"sts:AssumeRoleWithWebIdentity",
**"sts:TagSession"** //this does the trick for me
],
"Condition": {
"StringEquals": {
"cognito-identity.amazonaws.com:aud": "{IDENTITY_POOL_ID}"
},
"ForAnyValue:StringLike": {
"cognito-identity.amazonaws.com:amr": "authenticated"
}
}
}
]
}