Skip to content

Commit

Permalink
Add support for AWS SSO profiles
Browse files Browse the repository at this point in the history
Co-authored-by: Rickard Löfström <rickard.lofstrom@gmail.com>
  • Loading branch information
itsdalmo and rickardl committed Mar 31, 2020
1 parent 181c09a commit 01e8d5a
Show file tree
Hide file tree
Showing 6 changed files with 375 additions and 13 deletions.
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)

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

0 comments on commit 01e8d5a

Please # to comment.