Table of Contents

Class InstanceMetadataCredentialsProvider

Namespace
DynaSharp.Credentials
Assembly
DynaSharp.dll

Supplies temporary credentials of the IAM role of an Amazon EC2 instance from the instance metadata service (IMDS), and refreshes them before they expire.

public sealed class InstanceMetadataCredentialsProvider : IRefreshableCredentialsProvider, ICredentialsProvider
Inheritance
InstanceMetadataCredentialsProvider
Implements
Inherited Members

Remarks

A fetch has three steps, as in botocore: PUT /latest/api/token with a token lifetime of 6 hours (IMDSv2), then GET /latest/meta-data/iam/security-credentials/ for the role name, then the same path plus the role name for the credentials, both with the token. Every request has 1 second and is tried once. If the token request answers 403, 404 or 405, or times out, the service does not offer IMDSv2 (or the hop limit swallows the answer) and the provider falls back to IMDSv1, which is the same requests without a token. Any other failure of the token request, such as a refused connection or a server error, ends the fetch. AWS_EC2_METADATA_V1_DISABLED=true turns the fallback off.

AWS_EC2_METADATA_DISABLED=true (not case sensitive) switches the provider off: GetCredentialsAsync(CancellationToken) then throws a CredentialsUnavailableException that says so, without any network traffic. AWS_EC2_METADATA_SERVICE_ENDPOINT replaces the endpoint http://169.254.169.254; it must be an absolute http or https URL without user info. The IPv6 endpoint (AWS_EC2_METADATA_SERVICE_ENDPOINT_MODE) is not supported, set the endpoint instead. Redirects, proxies and cookies are not used.

Not being on an EC2 instance is the normal reason for a failure, so every problem of the service (unreachable, no role attached, an error document, a response without the four fields AccessKeyId, SecretAccessKey, Token and Expiration) is reported as a CredentialsUnavailableException with the reason; a wrong endpoint variable as well. Nothing is retried within a call, and a failure is not cached.

The same AwsCredentials instance is returned until it is refreshed. Refreshing starts 15 minutes before the expiration. In that advisory period the fetch runs in the background and every caller keeps the current credentials, so a slow source delays no request; if the fetch fails a warning is logged and it is tried again after 30 seconds. From 10 minutes before the expiration every caller waits for the fetch, and a failure is thrown. If DynamoDB rejects the credentials as expired before that, a client drops them with TryInvalidate(AwsCredentials) and the next call fetches. Concurrent callers share one fetch, which a caller's cancellation does not cancel. The provider is thread-safe.

As botocore does, the provider limits how often it asks again when the service keeps handing out credentials that are about to expire (the service renews them at least five minutes before they expire, and not at all while it has a problem): if the received credentials expire within 15 minutes plus a random 2 to 10 minutes, the Expiration of the returned instance is set to that point in the future instead. The next refresh is then attempted 2 to 10 minutes later, rather than with every request. The credentials themselves are unchanged and may expire earlier than they say.

Constructors

InstanceMetadataCredentialsProvider()

Initializes a new instance of the InstanceMetadataCredentialsProvider class that reads the environment of the current process and uses the system clock.

public InstanceMetadataCredentialsProvider()

Methods

GetCredentialsAsync(CancellationToken)

Gets the credentials of the instance role, fetching or refreshing them when needed.

public ValueTask<AwsCredentials> GetCredentialsAsync(CancellationToken cancellationToken)

Parameters

cancellationToken CancellationToken

Stops this call from waiting. The fetch itself, which other callers may share, is not cancelled.

Returns

ValueTask<AwsCredentials>

The same AwsCredentials instance until it is refreshed.

Exceptions

CredentialsUnavailableException

The service is disabled by AWS_EC2_METADATA_DISABLED, cannot be reached, has no role or no valid credentials, or the endpoint variable is invalid. During the mandatory refresh period, the failure of a refresh is thrown as well.

OperationCanceledException

cancellationToken was cancelled.

TryInvalidate(AwsCredentials)

Drops credentials that DynamoDB rejected as expired, so that the next GetCredentialsAsync(CancellationToken) fetches new ones. A client does this by itself.

public bool TryInvalidate(AwsCredentials rejected)

Parameters

rejected AwsCredentials

The instance that was rejected. Any other than the current one has been replaced already, and is ignored.

Returns

bool

Always true: this source can be asked again.

Exceptions

ArgumentNullException

rejected is null.