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
cancellationTokenCancellationTokenStops 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
cancellationTokenwas 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
rejectedAwsCredentialsThe instance that was rejected. Any other than the current one has been replaced already, and is ignored.
Returns
Exceptions
- ArgumentNullException
rejectedis null.