-
Notifications
You must be signed in to change notification settings - Fork 65
Description
Problem:
Is this library a replacement for AWS.KMS from the original aws-sdk node package? I haven't been able to find detailed documentation (vs. the high-level docs), and the examples in this repo are incomplete (#398).
I attempted to use @aws-crypto/client-node, but quickly found that the examples don't work in my setup. I need to specify a profile from my ~/.aws/config file to load the proper role and region to access my KMS key, but I can't figure out how you'd do that with this library. Maybe the examples assume you're using environment variables?
My AWS config looks like:
# ~/.aws/config
[default]
region=us-east-2
output=json
[profile staging]
role_arn=arn:aws:iam::000000000000:role/StagingAccessRole
source_profile=default
region=us-east-1# ~/.aws/credentials
[staging]
aws_access_key_id = <redacted>
aws_secret_access_key = <redacted>
aws_session_token = <redacted>My working aws-sdk code looks like:
// test-aws-sdk.js
// Must set AWS_SDK_LOAD_CONFIG to get SDK to load profiles from config files.
process.env.AWS_SDK_LOAD_CONFIG = '1';
const aws = require('aws-sdk');
// (Redacted.)
const KEY_ID = 'arn:aws:kms:us-east-1:000000000000:key/00000000-0000-0000-0000-000000000000';
aws.config.credentials = new aws.SharedIniFileCredentials({profile: 'staging'});
// WORKAROUND: SDK does not load region from profile or key ARN. Must specify here.
const kms = new aws.KMS({
apiVersion: '2014-11-01',
region: 'us-east-1'
});
const params = {
KeyId: KEY_ID,
Plaintext: 'hello',
};
kms.encrypt(params, function(err, data) {
if (err) {
console.log(err, err.stack);
} else {
console.log(data);
console.log(String(data.CiphertextBlob));
}
});My non-functional @aws-crypto/client-node attempt, based on examples:
// test-crypto-sdk.js
// Still needed with new SDK? Unknown, keep it just in case.
process.env.AWS_SDK_LOAD_CONFIG = '1';
const {
KmsKeyringNode,
buildClient,
CommitmentPolicy,
} = require('@aws-crypto/client-node');
const { encrypt, decrypt } = buildClient(
CommitmentPolicy.REQUIRE_ENCRYPT_REQUIRE_DECRYPT,
);
// (Redacted.)
const KEY_ID = ''arn:aws:kms:us-east-1:000000000000:key/00000000-0000-0000-0000-000000000000';
const generatorKeyId = KEY_ID;
const keyring = new KmsKeyringNode({ generatorKeyId });
encrypt(keyring, "hi", { encryptionContext: {foo: '5'} })
.then(data => console.dir(data))
.catch(err => console.dir(err));I don't know what profile the library tries to use, but that code throws errors:
# Without AWS_REGION or AWS_PROFILE or any AWS_* in the environment
$ node test-crypto-sdk.js
Error: A region is required
<stack trace>
# With env vars set
$ AWS_REGION=us-east-1 AWS_PROFILE=staging node test-crypto-sdk.js
Error [CredentialsError]: Missing credentials in config, if using AWS_CONFIG_FILE, set AWS_SDK_LOAD_CONFIG=1
at Timeout.connectTimeout [as _onTimeout] (/home/timk/code/xometry/cli/node_modules/aws-sdk/lib/http/node.js:69:15)
at listOnTimeout (internal/timers.js:554:17)
at processTimers (internal/timers.js:497:7) {
code: 'CredentialsError',
time: 2021-10-19T18:19:20.998Z,
retryable: true,
originalError: {
message: 'Could not load credentials from any providers',
code: 'CredentialsError',
time: 2021-10-19T18:19:20.998Z,
retryable: true,
originalError: {
message: 'EC2 Metadata roleName request returned error',
code: 'TimeoutError',
time: 2021-10-19T18:19:20.997Z,
retryable: true,
originalError: [Object]
}
}
}
How do I give @aws-crypto/client-node the profile from which to load credentials? How do I tell it to use the region from the profile, or how do I specify a region in code without using the AWS_PROFILE environment variable?
I ended up going back to aws-sdk for the project I was working on, but it would be really great to have documentation or examples with credentials here.