142 lines
4.2 KiB
Go
142 lines
4.2 KiB
Go
package cli
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
|
|
"github.com/aws/aws-sdk-go/aws"
|
|
"github.com/aws/aws-sdk-go/aws/session"
|
|
"github.com/aws/aws-sdk-go/service/cognitoidentity"
|
|
"github.com/stoggi/aws-oidc/provider"
|
|
|
|
kingpin "gopkg.in/alecthomas/kingpin.v2"
|
|
)
|
|
|
|
type ExecConfig struct {
|
|
RoleArn string
|
|
Duration int64
|
|
ProviderURL string
|
|
ClientID string
|
|
ClientSecret string
|
|
PKCE bool
|
|
Nonce bool
|
|
ReAuth bool
|
|
AgentCommant []string
|
|
}
|
|
|
|
// json metadata for AWS credential process. Ref: https://docs.aws.amazon.com/cli/latest/topic/config-vars.html#sourcing-credentials-from-external-processes
|
|
type AwsCredentialHelperData struct {
|
|
Version int `json:"Version"`
|
|
AccessKeyID string `json:"AccessKeyId"`
|
|
SecretAccessKey string `json:"SecretAccessKey"`
|
|
SessionToken string `json:"SessionToken"`
|
|
Expiration string `json:"Expiration,omitempty"`
|
|
}
|
|
|
|
type LambdaPayload struct {
|
|
Role string `json:"role"`
|
|
Token string `json:"token"`
|
|
}
|
|
|
|
func ConfigureExec(app *kingpin.Application, config *GlobalConfig) {
|
|
|
|
execConfig := ExecConfig{}
|
|
|
|
cmd := app.Command("exec", "Execute a command with temporary AWS credentials")
|
|
|
|
cmd.Default()
|
|
|
|
cmd.Flag("role_arn", "The AWS role you want to assume").
|
|
StringVar(&execConfig.RoleArn)
|
|
|
|
cmd.Flag("duration", "The duration to assume the role for in seconds").
|
|
Default("3600").
|
|
Int64Var(&execConfig.Duration)
|
|
|
|
cmd.Flag("provider_url", "The OpenID Connect Provider URL").
|
|
Required().
|
|
StringVar(&execConfig.ProviderURL)
|
|
|
|
cmd.Flag("client_id", "The OpenID Connect Client ID").
|
|
Required().
|
|
StringVar(&execConfig.ClientID)
|
|
|
|
cmd.Flag("client_secret", "The OpenID Connect Client Secret").
|
|
Default("").
|
|
StringVar(&execConfig.ClientSecret)
|
|
|
|
cmd.Flag("pkce", "Use PKCE in the OIDC code flow").
|
|
Default("true").
|
|
BoolVar(&execConfig.PKCE)
|
|
|
|
cmd.Flag("nonce", "Require a nonce included and verified in the token").
|
|
Default("true").
|
|
BoolVar(&execConfig.Nonce)
|
|
|
|
cmd.Flag("reauth", "Require reauthentication by the identity provider").
|
|
Default("false").
|
|
BoolVar(&execConfig.ReAuth)
|
|
|
|
cmd.Arg("agent", "The executable and arguments of the local browser to use").
|
|
Default("open", "{}").
|
|
StringsVar(&execConfig.AgentCommant)
|
|
|
|
cmd.Action(func(c *kingpin.ParseContext) error {
|
|
ExecCommand(app, config, &execConfig)
|
|
return nil
|
|
})
|
|
}
|
|
|
|
func ExecCommand(app *kingpin.Application, config *GlobalConfig, execConfig *ExecConfig) {
|
|
|
|
providerConfig := &provider.ProviderConfig{
|
|
ClientID: execConfig.ClientID,
|
|
ClientSecret: execConfig.ClientSecret,
|
|
ProviderURL: execConfig.ProviderURL,
|
|
PKCE: execConfig.PKCE,
|
|
Nonce: execConfig.Nonce,
|
|
ReAuth: execConfig.ReAuth,
|
|
AgentCommand: execConfig.AgentCommant,
|
|
}
|
|
|
|
authResult, err := provider.Authenticate(providerConfig)
|
|
app.FatalIfError(err, "Error authenticating to identity provider: %v", err)
|
|
|
|
svc := cognitoidentity.New(session.New(&aws.Config{
|
|
Region: aws.String("ap-southeast-2"),
|
|
}))
|
|
inputGetID := &cognitoidentity.GetIdInput{
|
|
AccountId: aws.String("811702477007"),
|
|
IdentityPoolId: aws.String("ap-southeast-2:b0a04ab4-9989-4ee0-b9f7-9b1e56fe0f19"),
|
|
Logins: map[string]*string{
|
|
"cognito-idp.ap-southeast-2.amazonaws.com/ap-southeast-2_XloydykNV": aws.String(authResult.JWT),
|
|
},
|
|
}
|
|
getIDResult, err := svc.GetId(inputGetID)
|
|
app.FatalIfError(err, "Unable to get ID: %v", err)
|
|
|
|
inputGetCredentials := &cognitoidentity.GetCredentialsForIdentityInput{
|
|
IdentityId: getIDResult.IdentityId,
|
|
Logins: map[string]*string{
|
|
"cognito-idp.ap-southeast-2.amazonaws.com/ap-southeast-2_XloydykNV": aws.String(authResult.JWT),
|
|
},
|
|
}
|
|
credentialsResult, err := svc.GetCredentialsForIdentity(inputGetCredentials)
|
|
app.FatalIfError(err, "Unable to get credentials: %v", err)
|
|
|
|
expiry := *credentialsResult.Credentials.Expiration
|
|
credentialData := AwsCredentialHelperData{
|
|
Version: 1,
|
|
AccessKeyID: *credentialsResult.Credentials.AccessKeyId,
|
|
SecretAccessKey: *credentialsResult.Credentials.SecretKey,
|
|
SessionToken: *credentialsResult.Credentials.SessionToken,
|
|
Expiration: expiry.Format("2006-01-02T15:04:05Z"),
|
|
}
|
|
|
|
output, err := json.Marshal(credentialData)
|
|
if err != nil {
|
|
app.Fatalf("Error encoding credential json")
|
|
}
|
|
fmt.Println(string(output))
|
|
}
|