Skip to content

Commit

Permalink
docs(clients): document client-level profile configuration (#6737)
Browse files Browse the repository at this point in the history
* docs(clients): document client-level profile configuration

* docs(credential-providers): client region and fromIni interaction

* docs(credential-providers): client region and fromIni

* docs(credential-providers): add terminology section
  • Loading branch information
kuhe authored Dec 17, 2024
1 parent afd9eea commit 0e65e09
Show file tree
Hide file tree
Showing 2 changed files with 195 additions and 42 deletions.
187 changes: 148 additions & 39 deletions packages/credential-providers/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@
[![NPM version](https://img.shields.io/npm/v/@aws-sdk/credential-providers/latest.svg)](https://www.npmjs.com/package/@aws-sdk/credential-providers)
[![NPM downloads](https://img.shields.io/npm/dm/@aws-sdk/credential-providers.svg)](https://www.npmjs.com/package/@aws-sdk/credential-providers)

A collection of all credential providers, with default clients.
A collection of all credential providers.

# Table of Contents

1. [Terminology](#terminology)
1. [From Cognito Identity](#fromcognitoidentity)
1. [From Cognito Identity Pool](#fromcognitoidentitypool)
1. [From Temporary Credentials](#fromtemporarycredentials)
Expand All @@ -27,12 +28,64 @@ A collection of all credential providers, with default clients.
1. [From Node.js default credentials provider chain](#fromNodeProviderChain)
1. [Creating a custom credentials chain](#createCredentialChain)

## Terminology

#### Credentials Provider

An `AwsCredentialIdentityProvider` is any function that matches the signature:

```ts
() =>
Promise<{
/**
* AWS access key ID
*/
readonly accessKeyId: string;
/**
* AWS secret access key
*/
readonly secretAccessKey: string;
/**
* A security or session token to use with these credentials. Usually
* present for temporary credentials.
*/
readonly sessionToken?: string;
/**
* A `Date` when the identity or credential will no longer be accepted.
* You can set or override this on the client side to force a refresh
* call of the function supplying the credentials when 5 minutes remain.
*/
readonly expiration?: Date;
}>;
```

#### Outer and inner clients

A "parent/outer/upper/caller" (position), or "data" (purpose) client refers
to a client being initialized explicitly by the SDK user.

An "inner" (position), or "credentials" (purpose) client
refers to a client being initialized by the SDK in the course
of retrieving credentials. Several AWS SDK credentials providers
make use of inner clients such as Cognito, SSO, STS, and SSO-OIDC.

```ts
// Example: outer client and inner client
const s3 = new S3Client({
credentials: fromIni(),
});
```

In the above example, `S3Client` is the outer client, and
if the `fromIni` credentials provider uses STS::AssumeRole, the
`STSClient` initialized by the SDK is the inner client.

## `fromCognitoIdentity()`

- Uses `@aws-sdk/client-cognito-identity`
- Available in browsers & native apps

The function `fromCognitoIdentity()` returns `CredentialsProvider` that retrieves credentials for
The function `fromCognitoIdentity()` returns a credentials provider that retrieves credentials for
the provided identity ID. See [GetCredentialsForIdentity API][getcredentialsforidentity_api]
for more information.

Expand All @@ -58,9 +111,10 @@ const client = new FooClient({
"api.twitter.com": "TWITTERTOKEN'",
"www.digits.com": "DIGITSTOKEN",
},
// Optional. Custom client config if you need overwrite default Cognito Identity client
// configuration.
clientConfig: { region },
// Optional overrides. This is passed to an inner Cognito client
// instantiated to resolve the credentials. Region and profile
// are inherited from the upper client if present unless overridden.
clientConfig: {},
}),
});
```
Expand Down Expand Up @@ -106,9 +160,10 @@ const client = new FooClient({
"api.twitter.com": "TWITTERTOKEN",
"www.digits.com": "DIGITSTOKEN",
},
// Optional. Custom client config if you need overwrite default Cognito Identity client
// configuration.
clientConfig: { region },
// Optional overrides. This is passed to an inner Cognito client
// instantiated to resolve the credentials. Region and profile
// are inherited from the upper client if present unless overridden.
clientConfig: {},
}),
});
```
Expand Down Expand Up @@ -144,13 +199,15 @@ const client = new FooClient({
DurationSeconds: 3600,
// ... For more options see https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRole.html
},
// Optional. Custom STS client configurations overriding the default ones.
clientConfig: { region },
// Optional. A function that returns a promise fulfilled with an MFA token code for the provided
// MFA Serial code. Required if `params` has `SerialNumber` config.
mfaCodeProvider: async (mfaSerial) => {
return "token";
},
// Optional overrides. This is passed to an inner STS client instantiated to
// resolve the credentials. Region and profile
// are inherited from the upper client if present unless overridden.
clientConfig: {},
}),
});
```
Expand All @@ -172,24 +229,29 @@ const client = new FooClient({
credentials: fromWebToken({
// Required. ARN of the role that the caller is assuming.
roleArn: "arn:aws:iam::1234567890:role/RoleA",
// Required. The OAuth 2.0 access token or OpenID Connect ID token that is provided by the
// identity provider.
// Required. The OAuth 2.0 access token or OpenID Connect ID token that is
// provided by the identity provider.
webIdentityToken: await openIdProvider(),
// Optional. Custom STS client configurations overriding the default ones.
clientConfig: { region },
// Optional. A function that assumes a role with web identity and returns a promise fulfilled
// with credentials for the assumed role.
// Optional. A function that assumes a role with web identity and returns
// a promise fulfilled with credentials for the assumed role.
roleAssumerWithWebIdentity,
// Optional. An identifier for the assumed role session.
roleSessionName: "session_123",
// Optional. The fully qualified host component of the domain name of the identity provider.
// Optional. The fully qualified host component of the domain name of the
// identity provider.
providerId: "graph.facebook.com",
// Optional. ARNs of the IAM managed policies that you want to use as managed session.
// Optional. ARNs of the IAM managed policies that you want to use as
// managed session.
policyArns: [{ arn: "arn:aws:iam::1234567890:policy/SomePolicy" }],
// Optional. An IAM policy in JSON format that you want to use as an inline session policy.
// Optional. An IAM policy in JSON format that you want to use as an
// inline session policy.
policy: "JSON_STRING",
// Optional. The duration, in seconds, of the role session. Default to 3600.
// Optional. The duration, in seconds, of the role session. Default 3600.
durationSeconds: 7200,
// Optional overrides. This is passed to an inner STS client
// instantiated to resolve the credentials. Region and profile
// are inherited from the upper client if present unless overridden.
clientConfig: {},
}),
});
```
Expand Down Expand Up @@ -380,7 +442,7 @@ const client = new FooClient({
on how the file is configured.
- Not available in browsers & native apps.

`fromIni` creates `AwsCredentialIdentityProvider` functions that read from a shared credentials file at
`fromIni` creates an `AwsCredentialIdentityProvider` function that reads from a shared credentials file at
`~/.aws/credentials` and a shared configuration file at `~/.aws/config`. Both files are expected to
be INI formatted with section names corresponding to profiles. Sections in the credentials file are
treated as profile names, whereas profile sections in the config file must have the format of
Expand All @@ -395,10 +457,29 @@ import { fromIni } from "@aws-sdk/credential-providers"; // ES6 import
// const { fromIni } = require("@aws-sdk/credential-providers"); // CommonJS import

const client = new FooClient({
// As of v3.714.0, an easy way to select a profile is to set it on the client.
// This will read both client configuration and credentials instructions
// from that profile. The order of priority is:
// 1. this field (only applies to this client).
// 2. AWS_PROFILE environment variable (affects all clients).
// 3. the default profile.
profile: "my-profile",

// Please note that the data client's region
// will not be used by STS requests originating from the `fromIni`
// provider if the profile(s) used have their own configured regions.
// If the profile(s) have no regions set, then the data client's
// region will be the fallback for the inner STS client.
// For SSO via `fromIni`, the `sso_region` value will be used, since it is required.
region: "us-west-2",

credentials: fromIni({
// Optional. The configuration profile to use. If not specified, the provider will use the value
// in the `AWS_PROFILE` environment variable or a default of `default`.
profile: "profile",
// Optional. Defaults to the client's profile if that is set.
// You can specify a profile here as well, but this applies
// only to the credential resolution and not to the upper client.
// Use this instead of the client profile if you need a separate profile
// for credentials.
profile: "my-profile",
// Optional. The path to the shared credentials file. If not specified, the provider will use
// the value in the `AWS_SHARED_CREDENTIALS_FILE` environment variable or a default of
// `~/.aws/credentials`.
Expand All @@ -412,8 +493,14 @@ const client = new FooClient({
mfaCodeProvider: async (mfaSerial) => {
return "token";
},
// Optional. Custom STS client configurations overriding the default ones.
clientConfig: { region },
// Optional overrides. This is passed to an inner STS or SSO client
// instantiated to resolve the credentials. Region and profile
// are inherited from the upper client if present unless overridden, so
// it should not be necessary to set those.
//
// Warning: setting a region here overrides the region set in the config file
// for the selected profile.
clientConfig: {},
}),
});
```
Expand Down Expand Up @@ -540,10 +627,15 @@ import { fromProcess } from "@aws-sdk/credential-providers"; // ES6 import
// const { fromProcess } = require("@aws-sdk/credential-providers"); // CommonJS import

const client = new FooClient({
// Optional, available on clients as of v3.714.0.
profile: "my-profile",
credentials: fromProcess({
// Optional. The configuration profile to use. If not specified, the provider will use the value
// in the `AWS_PROFILE` environment variable or a default of `default`.
profile: "profile",
// Optional. Defaults to the client's profile if that is set.
// You can specify a profile here as well, but this applies
// only to the credential resolution and not to the upper client.
// Use this instead of the client profile if you need a separate profile
// for credentials.
profile: "my-profile",
// Optional. The path to the shared credentials file. If not specified, the provider will use
// the value in the `AWS_SHARED_CREDENTIALS_FILE` environment variable or a default of
// `~/.aws/credentials`.
Expand Down Expand Up @@ -617,9 +709,12 @@ import { fromTokenFile } from "@aws-sdk/credential-providers"; // ES6 import
// const { fromTokenFile } = require("@aws-sdk/credential-providers"); // CommonJS import

const client = new FooClient({
region: "us-west-2",
credentials: fromTokenFile({
// Optional. STS client config to make the assume role request.
clientConfig: { region }
// Optional overrides. This is passed to an inner STS client
// instantiated to resolve the credentials. Region is inherited
// from the upper client if present unless overridden.
clientConfig: {}
});
});
```
Expand Down Expand Up @@ -655,9 +750,14 @@ import { fromSSO } from "@aws-sdk/credential-providers"; // ES6 import
// const { fromSSO } = require("@aws-sdk/credential-providers") // CommonJS import

const client = new FooClient({
credentials: fromSSO({
// Optional. The configuration profile to use. If not specified, the provider will use the value
// in the `AWS_PROFILE` environment variable or `default` by default.
// Optional, available on clients as of v3.714.0.
profile: "my-sso-profile",
credentials: fromProcess({
// Optional. Defaults to the client's profile if that is set.
// You can specify a profile here as well, but this applies
// only to the credential resolution and not to the upper client.
// Use this instead of the client profile if you need a separate profile
// for credentials.
profile: "my-sso-profile",
// Optional. The path to the shared credentials file. If not specified, the provider will use
// the value in the `AWS_SHARED_CREDENTIALS_FILE` environment variable or a default of
Expand Down Expand Up @@ -778,10 +878,19 @@ messages be sent to the Instance Metadata Service
import { fromNodeProviderChain } from "@aws-sdk/credential-providers"; // ES6 import
// const { fromNodeProviderChain } = require("@aws-sdk/credential-providers") // CommonJS import
const credentialProvider = fromNodeProviderChain({
//...any input of fromEnv(), fromSSO(), fromTokenFile(), fromIni(),
// fromProcess(), fromInstanceMetadata(), fromContainerMetadata()
// Optional. Custom STS client configurations overriding the default ones.
clientConfig: { region },
// This provider accepts any input of fromEnv(), fromSSO(), fromTokenFile(),
// fromIni(), fromProcess(), fromInstanceMetadata(), fromContainerMetadata()
// that exist in the default credential chain.

// Optional client overrides. This is passed to an inner credentials client
// that may be STS, SSO, or other instantiated to resolve the credentials.
// Region and profile are inherited from the upper client if present
// unless overridden, so it should not be necessary to set those.
//
// Warning: setting a region here may override the region set in
// the config file for the selected profile if profile-based
// credentials are used.
clientConfig: {},
});
```

Expand All @@ -799,7 +908,7 @@ All the providers from this package are compatible, and can be used to create su
As with _any_ function provided to the `credentials` SDK client constructor configuration field, if the credential object returned does not contain
an `expiration` (type `Date`), the client will only ever call the provider function once. You do not need to memoize this function.

To enable automatic refresh, the credential provider function should set an `expiration` (`Date`) field. When this expiration approaches within 5 minutes, the
To enable automatic refresh, the credential provider function should set an `expiration` (`Date`) field. When this expiration approaches within 5 minutes, the
provider function will be called again by the client in the course of making SDK requests.

To assist with this, the `createCredentialChain` has a chainable helper `.expireAfter(milliseconds: number)`. An example is included below.
Expand Down
50 changes: 47 additions & 3 deletions supplemental-docs/CLIENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,50 @@ const client = new S3Client({
});
```

### AWS Profile `profile`

Available since [v3.714.0](https://github.com/aws/aws-sdk-js-v3/releases/tag/v3.714.0).

You can set a `profile: string` value at the client initialization point in code.

```js
// Example: setting a non-default profile for a single client.
new S3Client({
profile: "my-profile",
});
```

```js
import { fromIni } from "@aws-sdk/credential-providers";
// Example: setting a non-default profile affects credential resolution.
// the fromIni function will use the client's designated profile if no
// profile is set on the `fromIni({ profile: "..." })` function.
new S3Client({
profile: "my-profile",
credentials: fromIni(),
});
```

```js
import { fromIni } from "@aws-sdk/credential-providers";
// Example: you can set different profiles for credentials and the client itself if needed.
// We expect this to be rarely needed.
new S3Client({
profile: "my-profile",
credentials: fromIni({ profile: "my-other-profile" }),
});
```

- This profile applies only to the client on which it is set, and overrides the AWS_PROFILE environment variable in that case.
- Setting a profile does nothing if running in an environment that does not have an AWS configuration file, such as browsers.
- Values configured in the profile will be used _unless_ an overriding environment variable or code level configuration exists.
- This includes fields such as `region`, `retry_mode`, `max_attempts`, `use_fips_endpoint` etc.
- Different client instances may have different profiles set.
- If this profile is set, and the client's credentials are resolved through the AWS configuration file, the profile will be
used unless another profile is set in the credentials provider function.
- Setting a profile only reads configuration from that one profile. If the profile points to another profile for e.g.
`source_profile` credentials, the source profile is only used for credentials, and not other configuration fields.

### Custom Endpoint `endpoint`

Each SDK client, by default, resolves the target endpoint with rule-based system
Expand Down Expand Up @@ -262,16 +306,16 @@ new S3Client({
});
```

A note on **socket exhaustion**:
A note on **socket exhaustion**:

The SDK may emit the following warning when detecting socket exhaustion:

```
@smithy/node-http-handler:WARN - socket usage at capacity=${socketsInUse} and ${requestsEnqueued} additional requests are enqueued.
```

Socket exhaustion detection is not an exact determination.
We only warn on this when there is a high count of `requestsEnqueued`,
Socket exhaustion detection is not an exact determination.
We only warn on this when there is a high count of `requestsEnqueued`,
because running at socket capacity may be intentional and normal in your application.

If you encounter the above warning or an error that indicates
Expand Down

0 comments on commit 0e65e09

Please sign in to comment.