Skip to content

How to specify config profile for role and region in @aws-crypto/client-node? #771

@mildmojo

Description

@mildmojo

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions