Creating AWS SSM client with credentials - amazon-web-services

I'm trying to create a SSMClient in JavaScript/TypeScript. I've found a ton of examples but nothing seems to work. I'm trying to get a value from the SSM parameter store. Here is my latest:
const stsClient = new STSClient({ region: REGION });
const params = {
RoleArn: "arn:aws:iam::425112775363:policy/SSMFullAccessCognito",
RoleSessionName: "session1",
DurationSeconds: 900,
};
//Assume Role
const data = await stsClient.send(new AssumeRoleCommand(params));
const rolecreds = {
accessKeyId: data.Credentials!.AccessKeyId,
secretAccessKey: data.Credentials!.SecretAccessKey,
sessionToken: data.Credentials!.SessionToken,
};
const ssmClient = new SSMClient({ region: REGION });
console.info(ssmClient);
const cmd = new GetParameterCommand({ Name: 'test', WithDecryption: false });
const result = await ssmClient.send(cmd);
console.info(result);
With the above it says creds are missing, which they are. I just can't anywhere to convert "rolecreds" to Somethng SSM wants. I can assume the role fine and I get back valid creds.
I've found 100 different ways from multiple sources but nothing works. I'm running AWSv3.
EDIT: I am using Amplify too.

You don't seem to actually using roleCreds.
If you look at the documentation for SSMClient, you'll see that it takes an optional credential object which you need to use in your situation: (https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/clients/client-ssm/interfaces/ssmclientconfig.html#credentials)

Assuming the SSMFullAccessCognito role has the correct permissions to access the required SSM parameter, what you have to do is to pass the rolecreds object to the SSMClient. You can do the following:
const data = await stsClient.send(new AssumeRoleCommand(params));
const rolecreds = {
accessKeyId: data.Credentials!.AccessKeyId!,
secretAccessKey: data.Credentials!.SecretAccessKey!,
sessionToken: data.Credentials!.SessionToken!,
};
const ssmClient = new SSMClient({ region: REGION, credentials: rolecreds });

Related

Missing region in config when requesting list of users in Cognito

Hi I’m trying to get all of the users from cognito, to be exact their phone numbers.
The code it’s partially working, because I can see the users, but also I’m getting an error.
“ Missing region in config “
I’m pretty new with AWS, could any of you have a similar problem or maybe found a solution for that. I would really appreciate any help.
Here is my code:
`
import AWS from 'aws-sdk';
const { CognitoIdentityServiceProvider, } = require('aws-sdk');
const cognitoidentityserviceprovider = new CognitoIdentityServiceProvider();
AWS.config.update({
accessKeyId: `${config.AWS_ACCESS_KEY_ID}`,
secretAccessKey: `${config.AWS_SECRET_ACCESS_KEY}`,
region: `${config.AWS_DEFAULT_REGION}`
});
const params = {
UserPoolId: `${config.AWS_USER_POOL_ID}`,
AttributesToGet: [
'phone_number'
],
};
cognitoidentityserviceprovider.listUsers(params, (err, data) => {
if (err) {
console.log(err);
}
else {
console.log(data)
}
})
`
I tried to change the region but it’s not making the error disappear.

how to update secrets manager secret value from lambda function?

I have a access token retrieved from an api and its lifetimes is 5 hours. I saw that secrets manager can rotate a secret but minimum rotation time is 1 day. Because of this i thought that i can write a lambda function that works every 5 hours and takes a new token from api and updates secret with this token. This answer https://stackoverflow.com/a/66610124/11902308 mentions that it can be done but i couldn't find any resource about how to update a secret from a lambda function.
Note:
I have multiple task and token is invalid when a new one is generated because of that task have to share it.
You didn't mention which AWS SDK you are using, but here is an example for AWS SDK for JS to create or update a Secret.
Additionally, it handles the case for deleted secrets (SecretsManager doesn't delete secrets immediately, it marks them as scheduled for deletion) and restores and updates them.
import { AWSError } from 'aws-sdk';
import SecretsManager, { SecretARNType } from 'aws-sdk/clients/secretsmanager';
const secretsManager = new SecretsManager({ apiVersion: '2017-10-17' });
const putSecret = async (name: string, secret: Record<string, unknown>, secretId?: SecretARNType): Promise<SecretARNType> => {
try {
const result = secretId
? secretsManager.updateSecret({
SecretId: secretId,
SecretString: JSON.stringify(secret),
})
: secretsManager.createSecret({
Name: name,
SecretString: JSON.stringify(secret),
});
const { ARN } = await result.promise();
if (!ARN) throw new Error(`Error saving secret ${name}`);
return ARN;
} catch (error) {
const awsError = error as AWSError;
// InvalidRequestException indicates that the secret is scheduled for deletion
if (awsError.code === 'InvalidRequestException') {
// restore existng secret
await secretsManager
.restoreSecret({
SecretId: secretId || name,
})
.promise();
// update secret
const { ARN } = await secretsManager
.updateSecret({
SecretId: secretId || name,
SecretString: JSON.stringify(secret),
})
.promise();
if (!ARN) throw new Error(`Error restoring secret ${name}`);
return ARN;
}
throw error;
}
};
The code is in TypeScript, but should be easily converted into the language of your choice because the AWS SDK functions have the same name in other languages.

"Missing credentials in config" error when using amplify Auth.currentCredentials()

We are using Amplify to manage the coginto credentials and once a while we will get this error when using the credentials:
Missing credentials in config, if using AWS_CONFIG_FILE, set AWS_SDK_LOAD_CONFIG=1
It does not happen often, happens once a day for us. Very hard to trigger.
The way we use it is like this:
const getDocumentClient = (): Promise<DocumentClient> =>
Auth.currentCredentials().then(
(credentials) =>
new DynamoDB.DocumentClient({
region: REGION,
credentials: Auth.essentialCredentials(credentials),
})
)
export const getItemFromSettingsTable = async (
Key: KeyType
): Promise<DocumentClient.GetItemOutput> => {
const params = {
TableName: xxx,
Key,
}
const client = await getDocumentClient()
return client.get(params).promise()
}
According to the stacktrace, we are getting the error when call the getItemFromSettingsTable.
It seems to be a race condition issue, since it usually does not happen.
Anyone run into this before?
Thanks.

SageMakerRuntime: MissingAuthenticationTokenException

When trying to access SageMakerRuntime -> invokeEndPoint method with Javascript and im getting this error:
MissingAuthenticationTokenException
The strange thing is when i access a random SageMaker method my code works.
Make sure you include AWS.Credentials when you create the AWS.SageMakerRuntime instance. So for example:
var creds = new AWS.Credentials({
accessKeyId: 'your-string',
secretAccessKey: 'your-string'
});
var sagemakerruntime = new AWS.SageMakerRuntime({
region: 'us-east-2',
credentials: creds
});
If it's not that, then I'm not sure what's the issue here.

What is [account:caller-specified-name] in aws:userid for aws Federated users

I would like to ask about 'AWS get Federation Token'.
What I want to do is that
someone authorized by using getFederationToken
could access ONLY HIS/HER NAMED AWS S3 folder like [bob] or [alice], etc.
Here is what I've done.
Make Temporary Credentials by using getFederationToken for aws:userid
AWS.config.update({
accessKeyId: [Removed],
secreteAccessKey: [Removed],
region: [Removed]
});
var params = {
Name : 'bob',
Policy : "{\"Version\": \"2012-10-17\",\"Statement\": [{\"Effect\": \"Allow\", \"Action\": [\"s3:ListBucket\"],\"Resource\": [\"arn:aws:s3:::mybucket\"]}, {\"Effect\": \"Allow\", \"Action\": [\"s3:PutObject\", \"s3:GetObject\"],\"Resource\": [\"arn:aws:s3:::mybucket/${aws:userid}/*\"]}]}",
DurationSeconds: "129600"
}
var sts = new AWS.STS({apiVersion: '2011-06-15'});
sts.getFederationToken(params, function(err, data) {
if(err)
console.log(err, err.stack);
else
console.log(data);
});
But I don't know what will be called from ${aws:userid}. AWS User Guide say that [account:caller-specified-name] will be called when the principal is Federated user... However, I checked whether it's [AWS account ID (12-digit number):bob]. It's not..
If you have something to tell me, plz let me know.
Thank you.
I've found a solution even not perfect.
[account:caller-specified-name] is working correctly as [123456789012:bob] only with s3 policy, not JS code parameter.
I was looking for an answer to the same question. With some trial and error, I found the solution:
You can use
"arn:aws:s3:::mybucket/${aws:userid}/*\"
but then the folder name must be mybucket/[accountId]:bob
However, depending on where this code is executed, you might want to NOT use your account id as part of an URL or folder name.
You are passing the entire policy anyway, you could simply change the code above to accept the Name:
const tempAccountName = 'bob'; // passed as parameter I presume?
AWS.config.update({
accessKeyId: [Removed],
secreteAccessKey: [Removed],
region: [Removed]
});
var params = {
Name : tempAccountName,
Policy : `{\"Version\": \"2012-10-17\",\"Statement\": [{\"Effect\": \"Allow\", \"Action\": [\"s3:ListBucket\"],\"Resource\": [\"arn:aws:s3:::mybucket\"]}, {\"Effect\": \"Allow\", \"Action\": [\"s3:PutObject\", \"s3:GetObject\"],\"Resource\": [\"arn:aws:s3:::mybucket/${tempAccountName}/*\"]}]}`,
DurationSeconds: "129600"
}
var sts = new AWS.STS({apiVersion: '2011-06-15'});
sts.getFederationToken(params, function(err, data) {
if(err)
console.log(err, err.stack);
else
console.log(data);
});