Greengrass Token Exchange Service not providing credentials to component

0

I have a very basic component that lists Named Shadows for thing using NodeJS and the AWS-SDK V3 SDK

My recipe is as follows:

{
  "RecipeFormatVersion": "2020-01-25",
  "ComponentName": "data-server",
  "ComponentVersion": "1.0.10",
  "ComponentType": "aws.greengrass.generic",
  "ComponentDescription": "",
  "ComponentPublisher": "Amazon",
  "ComponentDependencies": {
    "aws.greengrass.DockerApplicationManager": {
      "VersionRequirement": ">=2.0.0 <2.1.0",
      "DependencyType": "HARD"
    },
    "aws.greengrass.TokenExchangeService": {
      "VersionRequirement": ">=2.0.0 <3.0.0",
      "DependencyType": "HARD"
    }
  },
  "Manifests": [
    {
      "Platform": {
        "os": "all"
      },
      "Lifecycle": {
        "Run": {
          "Script": "node /home/umpadmin/test/index.js"
        }
      },
      "Artifacts": []
    }
  ],
  "Lifecycle": {}
}

Everytime I run the component I get the same error:

TypeError: Cannot read properties of undefined (reading 'sso_session').

at /home/test/test/node_modules/@aws-sdk/credential-provider-sso/dist-cjs/fromSSO.js:15:21

This is the same error I get on my pc when I run it with out credentials. I'm sure I have had this working on GGv2 before with no extra set up.

To test I have provided the environment variables:

AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY

And the component runs perfectly.

I can also see the env variables provided by the Token Exchage Service are working as I can log them before a make the call to AWS.


console.log(AWS_CONTAINER_CREDENTIALS_FULL_URI)

console.log(AWS_CONTAINER_AUTHORIZATION_TOKEN)

If it were a permission error I would expect to receive a different error. Can any one point me in the right direction?

asked 2 years ago334 views
2 Answers
0

Hi Phil,

The default provider chain should select the TES credentials if other providers with higher precedence are not available (https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/modules/_aws_sdk_credential_providers.html#fromnodeproviderchain) but you can also force it to use the container credential provider using https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/modules/_aws_sdk_credential_providers.html#fromcontainermetadata-1.

From your error it seems that you have either forced the client to use the SSO provider or you have your host configured to use SSO but without a valid token. Normally Greengrass is installed on devices that do not have SSO authentication configured, but if you are installing it on a development machine that could happen. I would advice then to force your code to use the Container Metadata provider as pointed above.

Cheers,

Massimiliano

AWS
EXPERT
answered 2 years ago
  • Hello,

    Additionally to this question, when I reboot my device the first time it requests the credentials I get an Error: Could not load credentials from any providers CredentialsProviderError: Could not load credentials from any providers at

    I then look at my greengrass log and approx 2 seconds after and it caches the credentials: Received IAM credentials that will be cached until 2022-11-21T00:33:37Z.

    I have to manually restart the node js app for it to receive the credentials. How to handle automatic retries to ensure the credentials have been fetched?

0

Hello Massimiliano,

Thanks very much for your help.

I had a few questions: As you mentioned I am testing this on a development machine. What would the credential provider be looking for to use the SSO provider? I understand that fromEnv() looks for: AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY env variables. So what would I have on my system that would point it to SSO Provider and how to remove it?

I believe there is an error in the documentation on the reference you provided. https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/modules/_aws_sdk_credential_providers.html#fromcontainermetadata-1 the example is incorrect you import fromContainerMetadata however you use the fromInstanceMetadata in the credentials provider. This throws an error.

I changed the code to

const {
	fromContainerMetadata
} = require("@aws-sdk/credential-providers")

var secretsClient = new SecretsManagerClient({
	region: <REGION>,
	credentials: fromContainerMetadata({
		// Optional. The connection timeout (in milliseconds) to apply to any remote requests. If not specified, a default value
		// of`1000` (one second) is used.
		timeout: 1000,
		// Optional. The maximum number of times any HTTP connections should be retried. If not specified, a default value of `0`
		// will be used.
		maxRetries: 0,
	})
});

and I can confirm that this now works as expected.

Can I create an issue for this somewhere?

answered 2 years ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions