Skip to content
New issue

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

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

Already on GitHub? # to your account

Add support for AWS SSO profiles #549

Merged
merged 3 commits into from
Apr 21, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 26 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,16 +114,33 @@ mfa_serial = arn:aws:iam::111111111111:mfa/jonsmith

Here's what you can expect from aws-vault

| Command | Credentials | Cached | MFA |
| ---------------------------------------- | -----------------------------| ------------- | ----- |
| `aws-vault exec jonsmith --no-session` | Long-term credentials | No | No |
| `aws-vault exec jonsmith` | session-token | session-token | Yes |
| `aws-vault exec foo-readonly` | role | No | No |
| `aws-vault exec foo-admin` | session-token + role | session-token | Yes |
| `aws-vault exec foo-admin --duration=2h` | role | No | Yes |
| `aws-vault exec bar-role2` | session-token + role + role | session-token | Yes |
| `aws-vault exec bar-role2 --no-session` | role + role | No | Yes |
| Command | Credentials | Cached | MFA |
|------------------------------------------|-----------------------------|---------------|-----|
| `aws-vault exec jonsmith --no-session` | Long-term credentials | No | No |
| `aws-vault exec jonsmith` | session-token | session-token | Yes |
| `aws-vault exec foo-readonly` | role | No | No |
| `aws-vault exec foo-admin` | session-token + role | session-token | Yes |
| `aws-vault exec foo-admin --duration=2h` | role | No | Yes |
| `aws-vault exec bar-role2` | session-token + role + role | session-token | Yes |
| `aws-vault exec bar-role2 --no-session` | role + role | No | Yes |

## AWS SSO integration

If your organization uses AWS Single Sign-On ([AWS SSO](https://aws.amazon.com/single-sign-on/)), AWS Vault provides a method for using the credential information defined by [AWS SSO CLI v2](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-sso.html). The integration supports caching of the temporary credentials for each profile, and will automatically refresh the credentials using an SSO Access Token (with a life-time that is specific to your integration). For more information about AWS SSO, please see this [blog post](https://aws.amazon.com/blogs/aws/the-next-evolution-in-aws-single-sign-on/) from AWS.

The AWS CLI v2 provides a wizard to generate the required profile configuration, but it's also possible to directly input this information in your `~/.aws/config` file.

Here's an example configuration using AWS SSO:

```ini
[profile Administrator-123456789012]
sso_start_url=https://aws-sso-portal.awsapps.com/start
sso_region=eu-west-1
sso_account_id=123456789012
sso_role_name=Administrator
```

This profile should work expected with AWS Vault commands, e.g. `exec` and `login`. See [Basic Usage](#basic-usage) for more information.

## Development

Expand Down
19 changes: 19 additions & 0 deletions USAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,25 @@ role_arn = arn:aws:iam::123456789012:role/target

You can also set the `mfa_serial` with the environment variable `AWS_MFA_SERIAL`.

## AWS Single Sign-On (AWS SSO)
Copy link
Member

Choose a reason for hiding this comment

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

Add this to the TOC at the top


The AWS CLI can [generate the SSO profile configuration](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-sso.html), but it's also possible to directly input this information in your `~/.aws/config` file. The configuration options are as follows:
* `sso_start_url` The URL that points to the organization's AWS SSO user portal.
* `sso_region` The AWS Region that contains the AWS SSO portal host. This is separate from, and can be a different region than the default CLI region parameter.
* `sso_account_id` The AWS account ID that contains the IAM role that you want to use with this profile.
* `sso_role_name` The name of the IAM role that defines the user's permissions when using this profile.

### Example ~/.aws/config

Here is an example `~/.aws/config` file, to help show the configuration for use with AWS SSO.

```ini
[profile Administrator-123456789012]
sso_start_url=https://aws-sso-portal.awsapps.com/start
sso_region=eu-west-1
sso_account_id=123456789012
sso_role_name=Administrator
```

## Removing stored sessions

Expand Down
8 changes: 4 additions & 4 deletions cli/#.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,11 @@ func LoginCommand(input LoginCommandInput) error {

var creds *credentials.Credentials

// if AssumeRole isn't used, GetFederationToken has to be used for IAM credentials
if config.RoleARN == "" {
creds, err = vault.NewFederationTokenCredentials(input.ProfileName, input.Keyring, config)
} else {
// If AssumeRole or sso.GetRoleCredentials isn't used, GetFederationToken has to be used for IAM credentials
if config.HasRole() || config.HasSSOStartURL() {
creds, err = vault.NewTempCredentials(config, input.Keyring)
} else {
creds, err = vault.NewFederationTokenCredentials(input.ProfileName, input.Keyring, config)
}
if err != nil {
return err
Expand Down
32 changes: 32 additions & 0 deletions vault/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,10 @@ type ProfileSection struct {
DurationSeconds uint `ini:"duration_seconds,omitempty"`
SourceProfile string `ini:"source_profile,omitempty"`
ParentProfile string `ini:"parent_profile,omitempty"`
SSOStartURL string `ini:"sso_start_url,omitempty"`
SSORegion string `ini:"sso_region,omitempty"`
SSOAccountID string `ini:"sso_account_id,omitempty"`
SSORoleName string `ini:"sso_role_name,omitempty"`
}

func (s ProfileSection) IsEmpty() bool {
Expand Down Expand Up @@ -296,6 +300,18 @@ func (cl *ConfigLoader) populateFromConfigFile(config *Config, profileName strin
if config.SourceProfileName == "" {
config.SourceProfileName = psection.SourceProfile
}
if config.SSOStartURL == "" {
config.SSOStartURL = psection.SSOStartURL
}
if config.SSORegion == "" {
config.SSORegion = psection.SSORegion
}
if config.SSOAccountID == "" {
config.SSOAccountID = psection.SSOAccountID
}
if config.SSORoleName == "" {
config.SSORoleName = psection.SSORoleName
}

if psection.ParentProfile != "" {
err := cl.populateFromConfigFile(config, psection.ParentProfile)
Expand Down Expand Up @@ -448,6 +464,18 @@ type Config struct {

// GetFederationTokenDuration specifies the wanted duration for credentials generated with GetFederationToken
GetFederationTokenDuration time.Duration

// SSOStartURL specifies the URL for the AWS SSO user portal.
SSOStartURL string

// SSORegion specifies the region for the AWS SSO user portal.
SSORegion string

// SSOAccountID specifies the AWS account ID for the profile.
SSOAccountID string

// SSORoleName specifies the AWS SSO Role name to target.
SSORoleName string
}

func (c *Config) IsChained() bool {
Expand All @@ -466,6 +494,10 @@ func (c *Config) HasRole() bool {
return c.RoleARN != ""
}

func (c *Config) HasSSOStartURL() bool {
return c.SSOStartURL != ""
}

// CanUseGetSessionToken determines if GetSessionToken should be used, and if not returns a reason
func (c *Config) CanUseGetSessionToken() (bool, string) {
if !UseSession {
Expand Down
Loading