diff --git a/cli/exec.go b/cli/exec.go index a5696499b..91d3acea8 100644 --- a/cli/exec.go +++ b/cli/exec.go @@ -32,6 +32,7 @@ type ExecCommandInput struct { Config vault.Config SessionDuration time.Duration NoSession bool + UseStdout bool } func (input ExecCommandInput) validate() error { @@ -88,6 +89,9 @@ func ConfigureExecCommand(app *kingpin.Application, a *AwsVault) { cmd.Flag("ecs-server", "Run a ECS credential server in the background for credentials (the SDK or app must support AWS_CONTAINER_CREDENTIALS_FULL_URI)"). BoolVar(&input.StartEcsServer) + cmd.Flag("stdout", "Print the SSO link to the terminal without automatically opening the browser"). + BoolVar(&input.UseStdout) + cmd.Arg("profile", "Name of the profile"). Required(). HintAction(a.MustGetProfileNames). @@ -104,6 +108,7 @@ func ConfigureExecCommand(app *kingpin.Application, a *AwsVault) { input.Config.MfaPromptMethod = a.PromptDriver input.Config.NonChainedGetSessionTokenDuration = input.SessionDuration input.Config.AssumeRoleDuration = input.SessionDuration + input.Config.SSOUseStdout = input.UseStdout f, err := a.AwsConfigFile() if err != nil { diff --git a/vault/config.go b/vault/config.go index bddd3b76c..a850decf3 100644 --- a/vault/config.go +++ b/vault/config.go @@ -544,6 +544,9 @@ type Config struct { // SSORoleName specifies the AWS SSO Role name to target. SSORoleName string + // SSOUseStdout specifies that the system browser should not be automatically opened + SSOUseStdout bool + // SessionTags specifies assumed role Session Tags SessionTags map[string]string diff --git a/vault/ssorolecredentialsprovider.go b/vault/ssorolecredentialsprovider.go index bd1a7839b..cd3de1b98 100644 --- a/vault/ssorolecredentialsprovider.go +++ b/vault/ssorolecredentialsprovider.go @@ -31,6 +31,7 @@ type SSORoleCredentialsProvider struct { SSOClient *sso.Client AccountID string RoleName string + UseStdout bool } func millisecondsTimeValue(v int64) time.Time { @@ -130,10 +131,14 @@ func (p *SSORoleCredentialsProvider) newOIDCToken() (*ssooidc.CreateTokenOutput, } log.Printf("Created OIDC device code for %s (expires in: %ds)", p.StartURL, deviceCreds.ExpiresIn) - log.Println("Opening SSO authorization page in browser") - fmt.Fprintf(os.Stderr, "Opening the SSO authorization page in your default browser (use Ctrl-C to abort)\n%s\n", aws.ToString(deviceCreds.VerificationUriComplete)) - if err := open.Run(aws.ToString(deviceCreds.VerificationUriComplete)); err != nil { - log.Printf("Failed to open browser: %s", err) + if p.UseStdout { + fmt.Fprintf(os.Stderr, "Open the SSO authorization page in a browser (use Ctrl-C to abort)\n%s\n", aws.ToString(deviceCreds.VerificationUriComplete)) + } else { + log.Println("Opening SSO authorization page in browser") + fmt.Fprintf(os.Stderr, "Opening the SSO authorization page in your default browser (use Ctrl-C to abort)\n%s\n", aws.ToString(deviceCreds.VerificationUriComplete)) + if err := open.Run(aws.ToString(deviceCreds.VerificationUriComplete)); err != nil { + log.Printf("Failed to open browser: %s", err) + } } // These are the default values defined in the following RFC: diff --git a/vault/vault.go b/vault/vault.go index 337b67e59..057771d9a 100644 --- a/vault/vault.go +++ b/vault/vault.go @@ -175,6 +175,7 @@ func NewSSORoleCredentialsProvider(k keyring.Keyring, config *Config) (aws.Crede SSOClient: sso.NewFromConfig(cfg), AccountID: config.SSOAccountID, RoleName: config.SSORoleName, + UseStdout: config.SSOUseStdout, } if UseSessionCache {