AWS Amplify graphql client IAM setup - amazon-web-services

I'm using the Amplify graphql client in my project. After custom auth I have the Access Key ID and Secret Access Key.
I need to provide these to the Amplify configuration but I can find no documentation whatsoever about it. The closest documentation I've seen is :
const myAppConfig = {
// ...
'aws_appsync_graphqlEndpoint': 'https://xxxxxx.appsync-api.us-east-1.amazonaws.com/graphql',
'aws_appsync_region': 'us-east-1',
'aws_appsync_authenticationType': 'AWS_IAM',
// ...
}
Amplify.configure(myAppConfig);
But it does not specify where should the credentials be entered.
They are specified for the AWS Appsync SDK but not the graphql client.
Any assistance or insights are greatly appreciated.
Thanks

I resolved it by using AWS.config
import AWS from "aws-sdk";
AWS.config.credentials = new AWS.Credentials(your credentials here)
Amplify.configure then works fine

Related

Spring boot application can't find aws credentials from any credentials chain

I'm trying to migrate Several spring boot services to EKS and they can't retrieve aws credentials from credentials chain and pods are failing with following error: Unable to load credentials from any of the providers in the chain AwsCredentialsProviderChain
These are what I've tried so far:
I'm using Web identity token from AWS STS for credentials retrieval.
#Bean
public AWSCredentialsProvider awsCredentialsProvider() {
if (System.getenv("AWS_WEB_IDENTITY_TOKEN_FILE") != null) {
return WebIdentityTokenCredentialsProvider.builder().build();
}
return new DefaultAWSCredentialsProviderChain();
}
#Bean
public SqsClient sqsClient(AWSCredentialsProvider awsCredentialsProvider) {
return SqsClient
.builder()
.credentialsProvider(() -> (AwsCredentials) awsCredentialsProvider.getCredentials())
.region(Region.EU_WEST_1).build();
}
#Bean
public SnsClient snsClient(AWSCredentialsProvider awsCredentialsProvider) {
return SnsClient
.builder()
.credentialsProvider(() -> (AwsCredentials) awsCredentialsProvider.getCredentials())
.region(Region.EU_WEST_1).build();
}
The services also have aws-java-sdk-sts maven dependency packaged.
IAM role for the services is also fine and AWS_WEB_IDENTITY_TOKEN_FILE is a also automatically created within pod after each Jenkins build based on K8s manifest file.
From pod I can make GET and POST request to SNS and SQS without any problem.
Problem was fixed.
Main issue was conflicting AWS SDK BOM version with individual models. Also previous version of BOM I was using wasn't supporting AWS SDK v2.x .
These are the main take aways from the issue:
AWS SDK authenticate services using credentials provider chain . The default credential provider chain of the AWS SDK for Java 2.x searches for credentials in your environment using a predefined sequence.
1.1 As of AWS SDK for Java 2.x Web identity token from AWS STS is within default provider chain.
1.2 As long as using v2 of the SDK and having the STS dependency makes explicit configuration of Web identity token redundant.
1.3 Make sure candidate service is using AWS SDK v2 as it’ll reduce the configuration code to minimum.
If a candidate service using AWS SDK v1 following configuration should be added as Web identity token isn’t in default provider chain for v1.
#Bean
public AWSCredentialsProvider awsCredentialsProvider() {
if (System.getenv("AWS_WEB_IDENTITY_TOKEN_FILE") != null) {
return WebIdentityTokenCredentialsProvider.builder().build();
}
return new DefaultAWSCredentialsProviderChain();
}
Last but not least try to use try to use latest AWS SDK BOM dependency . (currently all modules have the same version, but this may not always be the case)
You should have roleArn, sessionname and token details in the identity token cred provider build.
Try this
return WebIdentityTokenCredentialsProvider.builder()
.roleArn(System.getenv("AWS_ROLE_ARN"))
.roleSessionName(System.getenv("AWS_ROLE_SESSION_NAME"))
.webIdentityTokenFile(System.getenv("AWS_WEB_IDENTITY_TOKEN_FILE"))
.build();
than just returning as return WebIdentityTokenCredentialsProvider.builder().build();
You can try to create the file:
Windows: C:\Users[username].aws\config
Mac: /Users/[username]/.aws/config
Linux: /home/[username]/.aws/config
and add an AWS credential to it.
Ex:
[default]
aws_access_key_id = key_value
aws_secret_access_key = secret_value

Possible to trick AWS SDK `defaultProvider` function with a custom environment variable?

Problem: Netlify serverless functions run on AWS Lambda. So AWS_ is a reserved prefix in Netlify, meaning I can't use e.g. AWS_SECRET_ACCESS_KEY for my own environment var that I set in the Netlify admin panel.
But the only way I have been auble to authenticate Nodemailer with AWS SES (the email service) is with #aws/aws-sdk and its defaultProvider function that requires process.env.AWS_SECRET_ACCESS_KEY and process.env.AWS_ACCESS_KEY_ID – spelled exactly like that:
import 'dotenv/config'
import nodemailer from 'nodemailer'
import aws from '#aws-sdk/client-ses'
import { defaultProvider } from '#aws-sdk/credential-provider-node'
const ses = new aws.SES({
apiVersion: '2019-09-29',
region: 'eu-west-1',
defaultProvider,
rateLimit: 1
})
const sesTransporter = nodemailer.createTransport({ SES: { ses, aws } })
When building the function locally with the Netlify CLI, emails are sent.
It fails with 403 and InvalidClientTokenId: The security token included in the request is invalid in the live Netlify environment.
Netlify doesn't have a solution afaik, but mention in a forum post that custom env variables in AWS is a thing. I haven't been able to find anything in searches (they didn't provide any links). The AWS docs are pretty unhelpful as always :/
So the question is, how can this be done?
I thought I was clever when I tried the following, but setting the vars just before creating the SES Transport apparently doesn't help:
// Trick Netlify reserved env vars:
process.env.AWS_ACCESS_KEY_ID = process.env.ACCESS_KEY_ID
process.env.AWS_SECRET_ACCESS_KEY = process.env.SECRET_KEY
console.log('AWS access key id ', process.env.AWS_ACCESS_KEY_ID) // Logs the correct key!
console.log('AWS sec key ', process.env.AWS_SECRET_ACCESS_KEY ) // Logs the correct

Accessing AWS AppSync without using API Keys in React Native

In my React Native App I am using API Keys with AWS AppSync and I want to move to using Cognito or IAM but with no user sign in.
My React Native app that just uses AWS Appsync to read to and write from DyanmoDB.
I initially set up the app to use API keys as it was easier to understand and I'm now attempting to transition to using AWS Cognito or IAM.
To do this in my AWS Console I changed the "Appsync->MyAppAPI->Settings->Default authorisation mode"/"API-level" from "API key" to "AWS Identity and Access Management (IAM)".
I then created an Identity Pool and allowed "Enable access to unauthenticated identities".
My aws-exports file is
// WARNING: DO NOT EDIT. This file is automatically generated by AWS Amplify. It will be overwritten.
const awsmobile = {
"aws_appsync_graphqlEndpoint": "https://xxxxx.appsync-api.eu-west-x.amazonaws.com/graphql",
"aws_appsync_region": "eu-west-X",
"aws_appsync_authenticationType": "AWS_IAM",
"aws_appsync_apiKey": "xxx-xxxxxxxxxxxxxxxxxxxxxxxxxx",
};
export default awsmobile;
In my App.js file I have attempted to get the identityPoolId to be used and I have created this:
Amplify.configure({
url: config.aws_appsync_graphqlEndpoint,
region: config.aws_appsync_region,
auth: {
type: config.aws_appsync_authenticationType,
apiKey: config.aws_appsync_apiKey,
region: 'eu-west-x',
identityPoolId: 'eu-west-x:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',
}
})
When I use the app to read from DynamoDB I get this error
[WARN] 04:51.835 API - ensure credentials error, No Cognito Federated Identity pool provided
I then went back to the Cognito Manage Identity Pool page and changed my identity pool to use Cognito as an authentication source and provided a User Pool ID and an App client id. But I still get the same error.
I am fundamentally missunderstanding something, could you offer any insight?

How can I access an AWS DynamoDB as a guest user?

I am using aws-amplify and aws-sdk in Angular JS/Typescript.
I can successfully access my AWS DynamoDB as an authenticated user.
I am also trying to add guest user access for a certain table in Dynamo, but I am struggling to understand how I would get a reference to the DynamoDB without any credentials.
My code looks like this at the moment
getDocumentClient() {
return Auth.currentCredentials()
.then(credentials => new AWS.DynamoDB.DocumentClient({ credentials: credentials }))
.catch(err => logger.debug('error getting document client', err));
How would I do something similar to get access to the DynamoDB as an unauthenticated guest user?
Cheers
Lee
Try makeUnauthenticatedRequest.
Here's an example with S3 - I've shown this because I know you can make requests to S3 from the AWS SDK as an unauthenticated user. I'm assuming that this will also work for DynamoDB but have not tested it.
var s3 = new AWS.S3();
var params = {
Bucket: 'mybucket'
};
s3.makeUnauthenticatedRequest('listObjects', params, callback);
The more strategic approach would be Amazon Cognito Identity Pools which support unauthenticated/guest identities. Cognito vends an identity and AWS credentials, and you can configure an IAM role allowing DynamoDB read access for unauthenticated identity types.
I think you can refer to what is mentioned in the blog post below.
https://aws.amazon.com/blogs/compute/using-amazon-api-gateway-as-a-proxy-for-dynamodb/
The basic idea is to use API Gateway as a proxy for DynamoDB API. Permission to access DynamoDB is granted to API Gateway via execution role, and API Gateway is configured to open to public. In doing so, the flow will be as follows:
Web Browser <----- HTTPS -----> API Gateway <----- AWS Service Proxy integration -----> DynamoDB

Using Firebase OpenID Connect provider as AWS IAM Identity Provider

I get the following error while setting up Firebase as an AWS IAM Identity Provider using OpenID Connect.
We encountered the following errors while processing your request:
Please check .well-known/openid-configuration of provider:
https://securetoken.google.com/<Project ID> is valid.
The AWS IAM Identity Provider setup requires two input parameters, to which I plugged in the following:
Provider URL: https://securetoken.google.com/<Firebase Project ID>
Audience: <Firebase Client ID>
To troubleshoot the error, I opened http://<Provider URL>/.well-known/openid-configuration in a browser and noted the JSON response has the Issuer and jwks_uri fields. I believe these JSON fields indicate the Firebase OpenID Connect Provider URL is valid.
Any idea how I could avoid the above error and successfully set up the AWS IAM Identity Provider?
I contacted AWS support and they helped resolve the problem. Thanks to Shaun H # AWS!
The solution to the problem is to use AWS CLI instead of AWS console to set up an OIDC provider.
I'm pasting relevant parts of Shaun's response below:
1.) Manually obtain and verify the thumbprint using the procedure described here[1].
"ThumbprintList" = "6040DB92306CC8BCEB31CACAC88D107430B16AFF"
2.) Create the OIDC identity provider using the AWS Cli [2].
For example: $ aws iam create-open-id-connect-provider --cli-input-json file://oidc.json Note - the format would be:
aud Audience Must be your Firebase project ID, the unique identifier for your Firebase project, which can be found in the URL of that project's console.
iss Issuer Must be https://securetoken.google.com/<projectId>, where is the same project ID used for aud above.
Content for file://oidc.json: (replace with your Project ID)
{
"Url": "https://securetoken.google.com/<Firebase Client ID>",
"ClientIDList": [ "<Firebase Client ID>" ],
"ThumbprintList": [ "6040DB92306CC8BCEB31CACAC88D107430B16AFF" ]
}
[1] http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_oidc_verify-thumbprint.html
[2] http://docs.aws.amazon.com/cli/latest/reference/iam/create-open-id-connect-provider.html