Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Credentials Management Documentation #889

Merged
merged 13 commits into from
Jan 14, 2020
61 changes: 61 additions & 0 deletions designs/credentials/class-diagram.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
78 changes: 78 additions & 0 deletions designs/credentials/credentials-management.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# Credentials Management

This outlines how the Toolkit produces and obtains credentials.
hunterwerlla marked this conversation as resolved.
Show resolved Hide resolved

## Terminology

### Credentials

Credentials allow the Toolkit to interact with AWS on a user's behalf. Service clients require a [Credentials](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Credentials.html) object, and the Toolkit obtains these objects through Credentials Providers.

### Credentials Provider

Credentials Providers are how the toolkit abstracts away different ways of obtaining a user's credentials, and produces Credentials objects. For example, a Shared Credentials Provider knows how to obtain credentials for a specific profile within [Shared Credentials Files](https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/loading-node-credentials-shared.html).

A Credentials Provider is produced by a Credentials Provider Factory
hunterwerlla marked this conversation as resolved.
Show resolved Hide resolved

### Credentials Provider Factory

A factory is capable of producing one or more Credentials Providers for a single credentials type. For example, a Shared Credentials related factory produces Credentials Providers for each profile found within shared credentials files.

### Credentials Provider Id
hunterwerlla marked this conversation as resolved.
Show resolved Hide resolved

All Credentials Provider instances are uniquely identified by a Credentials Provider Id. These consist of the following parts:

- Credentials Type - a classification of the source data used to produce credentials. For example, the toolkit assigns Shared Credentials the type `profile`
- Credentials Type Id - within a credentials type, this is a unique identifier for the source data used to produce credentials. Using Shared Credentials files as an example, each profile is used as the Id.

A formatted version of the Credentials Provider Id may be surfaced to users, however it is an internal identification construct.

## How it Works

When the user connects to AWS in the Toolkit, a Credentials Provider is requested, which is then used to obtain credentials. The toolkit requests a Credentials Provider by checking which credentials provider factories support the provider's credentials type. The factories of interest are queried to see which (if any) have the requested Credentials Provider.

At the time this document was written, Shared Credentials are the only supported Credentials. Additional credentials providers will reside at [/src/credentials/providers](/src/credentials/providers) as they are implemented.

### Shared Credentials Profiles

Profiles are retrieved from the user's shared credentials files. The profile is handled and validated differently based on which fields are present. Handling and validation logic can be found in [sharedCredentialsProvider.ts](/src/credentials/providers/sharedCredentialsProvider.ts).

Only profiles that are considered valid are provided to the toolkit. When validation issues are detected, they are written to the logs to help users understand why the toolkit is having difficulties with a profile. Users running the 'Connect to AWS' command will not see invalid profiles in the list of Credentials.

Examples of validation include:

- missing fields that are expected to be paired with other fields
- profiles referencing other profiles that do not exist
- profiles referencing other profiles, resulting in a cycle

Supported keys:

- aws_access_key_id
- aws_secret_access_key
- aws_session_token
- role_arn
- source_profile
- credential_process
- region

Credentials Providers for Shared Credentials are only ever refreshed when the user brings up the credential selection list. If a profile is considered to have changed since it was last used in the current toolkit session, Credentials are produced from the updated profile.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not intuitive. We should offer either a more proactive approach to refreshing credentials, or an explicit credential refresh action. Why should a user have to change their credentials to the credentials they already selected?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems like a reasonable behavior to start with. The only times that shared credentials files should be updated are to add new credentials, or to remedy an error in an existing profile. In these cases, it is reasonable to understand that you would need to take a corresponding action in the toolkit.

I'd suggest to release this behavior, and use customer feedback to drive whether or not additional complexities are needed in this area.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd at the very least like to see an alternate design or even considerations of this in the design doc. I'm fine with shipping this in the form of code, but it doesn't make sense to leave it out of the design doc.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added that to the doc now


## Architecture

![Class Diagram](class-diagram.svg)

When the Toolkit is initialized, it sets up a `CredentialsProviderManager` instance to manage Credentials Providers for the Toolkit session. `CredentialsProviderFactory` objects (like `SharedCredentialsProviderFactory`) are added to it during setup.

When the toolkit wants to list available Credentials Providers, `CredentialsProviderManager` is queried using `getAllCredentialsProviders`. This in turn calls `listProviders` on every `CredentialsProviderFactory`. Implementations for `listProviders` determine what `CredentialsProvider` objects are available/valid and return them.

When the toolkit wants a specific Credentials Provider, `getCredentialsProvider` is called on `CredentialsProviderManager`. This in turn queries `getProvider` on its `CredentialsProviderFactory` objects until a provider is returned.

## Alternate Concepts

This section discusses alternative considerations that were not used in the current design.

### Immediately Updating the Toolkit whenever Shared Credentials are updated

File watchers could be created and maintained against shared credentials files. Whenever these files change, the toolkit's current collection of credentials providers is updated, and the current connection would get updated with new credentials if appropriate. If the current connection's credentials are updated, this needs to propagate throughout all of the toolkit's state (for example the AWS Explorer would need to be refreshed).

Credentials files are generally altered to add new credentials, or fix incorrect credentials. This low frequency doesn't seem to justify the additional complexities. We will prefer to evaluate functionality like this based on community input.