Skip to content

Commit

Permalink
Merge pull request #147 from okta/m2m_alt_open_browser
Browse files Browse the repository at this point in the history
Alternate open browser command
  • Loading branch information
monde authored Oct 12, 2023
2 parents b382cf4 + 4272e84 commit 30d97ee
Show file tree
Hide file tree
Showing 16 changed files with 218 additions and 118 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
- name: Setup Go
uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568
with:
go-version: 1.19
go-version: 1.21

- name: Setup Go Tools
run: make tools
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
name: Set up Go
uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568 #v3.5.0
with:
go-version: 1.19
go-version: 1.21
-
name: Import GPG key
id: import_gpg
Expand Down
67 changes: 26 additions & 41 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,20 @@ in the naming convention for `okta-aws-cli` specific names.
| `OKTA_OIDC_CLIENT_ID` | `OKTA_AWSCLI_OIDC_CLIENT_ID` |
| `OKTA_AWS_ACCOUNT_FEDERATION_APP_ID` | `OKTA_AWSCLI_AWS_ACCOUNT_FEDERATION_APP_ID` |

### (Completed) Process credential provider output as JSON
### (completed) Process credential provider output as JSON

Emits IAM temporary credentials as JSON in [process
credentials](https://docs.aws.amazon.com/sdkref/latest/guide/feature-process-credentials.html)
format.

### (Complete) Execute follow-on command
```
# In $/.aws/config
[default]
# presumes OKTA_AWSCLI_* env vars are set
credential_process = okta-aws-cli m2m --format process-credentials
```

### (completed) Execute follow-on command

Instead of scripting and/or eval'ing `okta-aws-cli` into a shell and then
running another command have `okta-aws-cli` run the command directly passing
Expand All @@ -46,7 +53,7 @@ $ okta-aws-cli web \
--exec -- aws ec2 describe-instances
```

### (Complete) Collect all roles for an AWS Fed App (IdP) at once
### (completed) Collect all roles for an AWS Fed App (IdP) at once

`okta-aws-cli web` will collect all available AWS IAM Roles for a given Okta AWS
Federation app (IdP) at once. This is a feature specific to writing the
Expand All @@ -64,12 +71,17 @@ $ okta-aws-cli web \
--write-aws-credentials \
--all-profiles
? Choose an IdP: AWS Account Federation
Updated profile "myorg-S3-read" in credentials file "/Users/me/.aws/credentials".
Updated profile "myorg-S3-write" in credentials file "/Users/me/.aws/credentials".
Web browser will open the following URL to begin Okta device authorization for the AWS CLI
https://test.okta.com/activate?user_code=QHDMVQTZ
Updated profile "devorg-idp1-role1" in credentials file "/Users/me/.aws/credentials".
Updated profile "devorg-idp1-role2" in credentials file "/Users/me/.aws/credentials".
Updated profile "devorg-idp2-role1" in credentials file "/Users/me/.aws/credentials".
Updated profile "prodorg-idp1-role1" in credentials file "/Users/me/.aws/credentials".
```

### (expected) Alternate web browser open command
### (completed) Alternate web browser open command

The `web` command will open the system's default web browser when the
`--open-browser` flag is present. It is convenient to have the browser open on a
Expand All @@ -81,19 +93,21 @@ system an alternate open command can be specified.
$ okta-aws-cli web \
--org-domain test.okta.com \
--oidc-client-id 0oa5wyqjk6Wm148fE1d7 \
--open-browser \
--open-browser-command "open -na 'Google Chrome' --args -incognito"
--open-browser-command "open -na \"Google\ Chrome\" --args --incognito"
```

```
# Open browser in Chrome "Profile 1" on macOS calling the Chrome executable directly
$ okta-aws-cli web \
--org-domain test.okta.com \
--oidc-client-id 0oa5wyqjk6Wm148fE1d7 \
--open-browser \
--open-browser-command "/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --args --profile-directory='Profile 1'"
--open-browser-command "/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --profile-directory=\"Profile\ 1\""
```

## 2.0.0-beta.4 (October 12, 2023)

`okta-aws-cli web` can have it's open browser command customized.

## 2.0.0-beta.3 (October 10, 2023)

`okta-aws-cli web` can collect all roles to an AWS credentials file for a given
Expand All @@ -103,46 +117,17 @@ AWS Federation App (IdP) in one invocation of the CLI.

Execute a subcommand directly from `okta-aws-cli`

```
$ okta-aws-cli m2m --format noop --exec -- aws s3 ls s3://example
PRE aaa/
2023-03-08 16:01:01 4 a.log
```

## 2.0.0-beta.1 (October 2, 2023)

Support for AWS CLI [process credential provider](https://docs.aws.amazon.com/sdkref/latest/guide/feature-process-credentials.html)

```
# $/.aws/config
[default]
# presumes OKTA_AWSCLI_* env vars are set
credential_process = okta-aws-cli m2m --format process-credentials
```

## 2.0.0-beta.0 (September 29, 2023)

### New commands

`okta-aws-cli`'s functions are encapsulated as (sub)commands e.g. `$ okta-aws-cli [sub-command]`

| Command | Description |
|-----|-----|
| `web` | Human oriented retrieval of temporary IAM credentials through Okta authentication and device authorization. Note: if `okta-aws-cli` is not given a command it defaults to this original `web` command. |
| `m2m` | Machine/headless oriented retrieval of temporary IAM credentials through Okta authentication with a private key. |
| `debug` | Debug okta.yaml config file and exit. |

### Environment variable name changes
`okta-aws-cli`'s functions are encapsulated as (sub)commands `web`, `m2m`, `debug`

A small number of environment variable names have been renamed to be consistent
in the naming convention for `okta-aws-cli` specific names.

| old name | new name |
|----------|----------|
| `OKTA_ORG_DOMAIN` | `OKTA_AWSCLI_ORG_DOMAIN` |
| `OKTA_OIDC_CLIENT_ID` | `OKTA_AWSCLI_OIDC_CLIENT_ID` |
| `OKTA_AWS_ACCOUNT_FEDERATION_APP_ID` | `OKTA_AWSCLI_AWS_ACCOUNT_FEDERATION_APP_ID` |

## 1.2.2 (August 30, 2023)

* Ensure evaluation of CLI flag for profile is in the same order as the other flags [#124](https://github.com/okta/okta-aws-cli/pull/124)
Expand Down
32 changes: 27 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,8 @@ These settings are all optional:
| AWS IAM Identity Provider ARN | Preselects the IdP list to this preferred IAM Identity Provider. If there are other IdPs available they will not be listed. | `--aws-iam-idp [value]` | `OKTA_AWSCLI_IAM_IDP` |
| Display QR Code | `true` if flag is present | `--qr-code` | `OKTA_AWSCLI_QR_CODE=true` |
| Automatically open the activation URL with the system web browser | `true` if flag is present | `--open-browser` | `OKTA_AWSCLI_OPEN_BROWSER=true` |
| Gather all profiles for a given IdP (implies aws-credentials file output format)) | `true` if flag is present | `--all-profiles` | `OKTA_AWSCLI_OPEN_BROWSER=true` |
| Automatically open the activation URL with the given web browser command | Shell escaped browser command | `--open-browser-command [command]` | `OKTA_AWSCLI_OPEN_BROWSER_COMMAND` |
| Gather all profiles for all IdPs and Roles associated with an AWS Fed App (implies aws-credentials file output format)) | `true` if flag is present | `--all-profiles` | `OKTA_AWSCLI_OPEN_BROWSER=true` |

#### Allowed Web SSO Client ID

Expand Down Expand Up @@ -745,8 +746,9 @@ Federation app (IdP) at once. This is a feature specific to writing the
aliases is available on the given role) then `-` then abbreviated role name.

```
# AWS account alias "myorg", given IdP associated with "AWS Account Federation"
# and an app associated with two roles.
# Two Okta "AWS Account Federation" apps, one on AWS alias "prod-org", the other
# on alias "dev-org". Includes short name for the actual IAM IdPs and IAM Roles
# on the Fed App.
$ okta-aws-cli web \
--org-domain test.okta.com \
Expand All @@ -755,8 +757,28 @@ $ okta-aws-cli web \
--all-profiles
? Choose an IdP: AWS Account Federation
Updated profile "myorg-S3-read" in credentials file "/Users/me/.aws/credentials".
Updated profile "myorg-S3-write" in credentials file "/Users/me/.aws/credentials".
Updated profile "dev-org-s3ops-read" in credentials file "/Users/me/.aws/credentials".
Updated profile "dev-org-s3ops-write" in credentials file "/Users/me/.aws/credentials".
Updated profile "prod-org-containerops-ec2-full" in credentials file "/Users/me/.aws/credentials".
Updated profile "prod-org-containerops-eks-full" in credentials file "/Users/me/.aws/credentials".
```

### Alternative open browser command

`okta-aws-cli web` can have it's open browser command customized.

```
# OSX examples, the device authorization URL is appended to the browser args.
$ okta-aws-cli web \
--oidc-client-id abc \
--org-domain test.okta.com \
--open-browser-command "/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --profile-directory=\"Profile\ 1\""
$ okta-aws-cli web \
--oidc-client-id abc \
--org-domain test.okta.com \
--open-browser-command "open -na \"Google\ Chrome\" --args --incognito"
```

### Help
Expand Down
7 changes: 7 additions & 0 deletions cmd/root/web/web.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,13 @@ var (
Usage: "Automatically open the activation URL with the system web browser",
EnvVar: config.OpenBrowserEnvVar,
},
{
Name: config.OpenBrowserCommandFlag,
Short: "m",
Value: "",
Usage: "Automatically open the activation URL with the given web browser command",
EnvVar: config.OpenBrowserCommandEnvVar,
},
{
Name: config.AllProfilesFlag,
Short: "k",
Expand Down
7 changes: 5 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/okta/okta-aws-cli

go 1.19
go 1.21

require (
github.com/AlecAivazis/survey/v2 v2.3.6
Expand All @@ -23,7 +23,10 @@ require (
gopkg.in/yaml.v2 v2.4.0
)

require golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e // indirect
require (
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e // indirect
)

require (
github.com/davecgh/go-spew v1.1.1 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,8 @@ github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLe
github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
Expand Down
22 changes: 0 additions & 22 deletions internal/aws/aws.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,6 @@ import (
"time"
)

// Credential Interface to represent AWS credentials in different formats.
type Credential interface {
// Trivial function to allow concrete structs to be represented by this
// interface.
IsCredential() bool
}

// CredentialContainer denormalized struct of all the values can be presented in
// the different credentials formats
type CredentialContainer struct {
Expand All @@ -47,9 +40,6 @@ type EnvVarCredential struct {
SessionToken string
}

// IsCredential env var credential is a credential
func (e *EnvVarCredential) IsCredential() bool { return true }

// CredsFileCredential representation of an AWS credential for the AWS
// credentials file
type CredsFileCredential struct {
Expand All @@ -60,9 +50,6 @@ type CredsFileCredential struct {
profile string
}

// IsCredential creds file credential is a credential
func (c *CredsFileCredential) IsCredential() bool { return true }

// SetProfile sets the profile name associated with this AWS credential.
func (c *CredsFileCredential) SetProfile(p string) { c.profile = p }

Expand All @@ -79,9 +66,6 @@ type ProcessCredential struct {
Version int `json:"Version,omitempty"`
}

// IsCredential process credential is a credential
func (c *ProcessCredential) IsCredential() bool { return true }

// MarshalJSON ensure Expiration date time is formatted RFC 3339 format.
func (c *ProcessCredential) MarshalJSON() ([]byte, error) {
type Alias ProcessCredential
Expand All @@ -101,9 +85,3 @@ func (c *ProcessCredential) MarshalJSON() ([]byte, error) {
}
return json.Marshal(obj)
}

// NoopCredential Convenience representation for not printing credentials
type NoopCredential struct{}

// IsCredential noop credential is a credential
func (n *NoopCredential) IsCredential() bool { return true }
26 changes: 25 additions & 1 deletion internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func init() {

const (
// Version app version
Version = "2.0.0-beta.3"
Version = "2.0.0-beta.4"

// AWSCredentialsFormat format const
AWSCredentialsFormat = "aws-credentials"
Expand Down Expand Up @@ -76,6 +76,8 @@ const (
OIDCClientIDFlag = "oidc-client-id"
// OpenBrowserFlag cli flag const
OpenBrowserFlag = "open-browser"
// OpenBrowserCommandFlag cli flag const
OpenBrowserCommandFlag = "open-browser-command"
// OrgDomainFlag cli flag const
OrgDomainFlag = "org-domain"
// PrivateKeyFlag cli flag const
Expand Down Expand Up @@ -139,6 +141,8 @@ const (
OldOktaAWSAccountFederationAppIDEnvVar = "OKTA_AWS_ACCOUNT_FEDERATION_APP_ID"
// OpenBrowserEnvVar env var const
OpenBrowserEnvVar = "OKTA_AWSCLI_OPEN_BROWSER"
// OpenBrowserCommandEnvVar env var const
OpenBrowserCommandEnvVar = "OKTA_AWSCLI_OPEN_BROWSER_COMMAND"
// PrivateKeyEnvVar env var const
PrivateKeyEnvVar = "OKTA_AWSCLI_PRIVATE_KEY"
// KeyIDEnvVar env var const
Expand Down Expand Up @@ -200,6 +204,7 @@ type Config struct {
legacyAWSVariables bool
oidcAppID string
openBrowser bool
openBrowserCommand string
orgDomain string
privateKey string
profile string
Expand Down Expand Up @@ -228,6 +233,7 @@ type Attributes struct {
LegacyAWSVariables bool
OIDCAppID string
OpenBrowser bool
OpenBrowserCommand string
OrgDomain string
PrivateKey string
Profile string
Expand Down Expand Up @@ -266,6 +272,7 @@ func NewConfig(attrs *Attributes) (*Config, error) {
format: attrs.Format,
legacyAWSVariables: attrs.LegacyAWSVariables,
openBrowser: attrs.OpenBrowser,
openBrowserCommand: attrs.OpenBrowserCommand,
privateKey: attrs.PrivateKey,
keyID: attrs.KeyID,
profile: attrs.Profile,
Expand Down Expand Up @@ -315,6 +322,7 @@ func readConfig() (Attributes, error) {
CacheAccessToken: viper.GetBool(CacheAccessTokenFlag),
OIDCAppID: viper.GetString(OIDCClientIDFlag),
OpenBrowser: viper.GetBool(OpenBrowserFlag),
OpenBrowserCommand: viper.GetString(OpenBrowserCommandFlag),
OrgDomain: viper.GetString(OrgDomainFlag),
PrivateKey: viper.GetString(PrivateKeyFlag),
KeyID: viper.GetString(KeyIDFlag),
Expand Down Expand Up @@ -433,6 +441,11 @@ func readConfig() (Attributes, error) {
if !attrs.OpenBrowser {
attrs.OpenBrowser = viper.GetBool(downCase(OpenBrowserEnvVar))
}
if attrs.OpenBrowserCommand == "" {
// open browser command implies open browser
attrs.OpenBrowser = true
attrs.OpenBrowserCommand = viper.GetString(downCase(OpenBrowserCommandEnvVar))
}
if !attrs.Debug {
attrs.Debug = viper.GetBool(downCase(DebugEnvVar))
}
Expand Down Expand Up @@ -678,6 +691,17 @@ func (c *Config) SetOpenBrowser(openBrowser bool) error {
return nil
}

// OpenBrowserCommand --
func (c *Config) OpenBrowserCommand() string {
return c.openBrowserCommand
}

// SetOpenBrowserCommand --
func (c *Config) SetOpenBrowserCommand(openBrowserCommand string) error {
c.openBrowserCommand = openBrowserCommand
return nil
}

// OrgDomain --
func (c *Config) OrgDomain() string {
return c.orgDomain
Expand Down
Loading

0 comments on commit 30d97ee

Please sign in to comment.