func TestPreResignRequestExpiredCreds(t *testing.T) { provider := &credentials.StaticProvider{Value: credentials.Value{ AccessKeyID: "AKID", SecretAccessKey: "SECRET", SessionToken: "SESSION", }} creds := credentials.NewCredentials(provider) svc := awstesting.NewClient(&aws.Config{Credentials: creds}) r := svc.NewRequest( &request.Operation{ Name: "BatchGetItem", HTTPMethod: "POST", HTTPPath: "/", }, nil, nil, ) r.ExpireTime = time.Minute * 10 Sign(r) querySig := r.HTTPRequest.URL.Query().Get("X-Amz-Signature") creds.Expire() r.Time = time.Now().Add(time.Hour * 48) Sign(r) assert.NotEqual(t, querySig, r.HTTPRequest.URL.Query().Get("X-Amz-Signature")) }
// GetSessions returns the current session from the SessionProvider. func (dsp *ConfigurableSessionProvider) GetSession() *session.Session { dsp.sessionMutex.Lock() defer dsp.sessionMutex.Unlock() if dsp._session != nil { return dsp._session } cfgs := []*aws.Config{ aws.NewConfig().WithRegion(dsp.ConfigRegion), } if dsp.ConfigAccessKey != "" { cfgs = append(cfgs, aws.NewConfig().WithCredentials(credentials.NewStaticCredentials( dsp.ConfigAccessKey, dsp.ConfigSecretKey, dsp.ConfigSessionToken, ))) } else if !dsp.ConfigDisableENVCredentials { // NOTE: We may want to init all credential providers in one config, as they might overwrite each other cfgs = append(cfgs, aws.NewConfig().WithCredentials(credentials.NewCredentials(&credentials.EnvProvider{}))) } else { panic("no valid configuration parameters for aws credentials found.") } dsp._session = session.New(cfgs...) return dsp._session }
func TestAfterRetryRefreshCreds(t *testing.T) { os.Clearenv() credProvider := &mockCredsProvider{} svc := awstesting.NewClient(&aws.Config{ Credentials: credentials.NewCredentials(credProvider), MaxRetries: aws.Int(1), }) svc.Handlers.Clear() svc.Handlers.ValidateResponse.PushBack(func(r *request.Request) { r.Error = awserr.New("UnknownError", "", nil) r.HTTPResponse = &http.Response{StatusCode: 400, Body: ioutil.NopCloser(bytes.NewBuffer([]byte{}))} }) svc.Handlers.UnmarshalError.PushBack(func(r *request.Request) { r.Error = awserr.New("ExpiredTokenException", "", nil) }) svc.Handlers.AfterRetry.PushBackNamed(corehandlers.AfterRetryHandler) assert.True(t, svc.Config.Credentials.IsExpired(), "Expect to start out expired") assert.False(t, credProvider.retrieveCalled) req := svc.NewRequest(&request.Operation{Name: "Operation"}, nil, nil) req.Send() assert.True(t, svc.Config.Credentials.IsExpired()) assert.False(t, credProvider.retrieveCalled) _, err := svc.Config.Credentials.Get() assert.NoError(t, err) assert.True(t, credProvider.retrieveCalled) }
// assumeRole uses IAM credentials to assume a role func (p *VaultProvider) assumeRole(creds credentials.Value, roleArn string) (sts.Credentials, error) { client := sts.New(session.New(&aws.Config{ Credentials: credentials.NewCredentials(&credentials.StaticProvider{Value: creds}), })) input := &sts.AssumeRoleInput{ RoleArn: aws.String(roleArn), RoleSessionName: aws.String(p.roleSessionName()), DurationSeconds: aws.Int64(int64(p.AssumeRoleDuration.Seconds())), } // if we don't have a session, we need to include MFA token in the AssumeRole call if mfa, ok := p.profiles[p.profile]["mfa_serial"]; ok { input.SerialNumber = aws.String(mfa) if p.MfaToken == "" { token, err := p.MfaPrompt(fmt.Sprintf("Enter token for %s: ", mfa)) if err != nil { return sts.Credentials{}, err } input.TokenCode = aws.String(token) } else { input.TokenCode = aws.String(p.MfaToken) } } log.Printf("Assuming role %s with iam credentials", roleArn) resp, err := client.AssumeRole(input) if err != nil { return sts.Credentials{}, err } return *resp.Credentials, nil }
// GetAWSCreds returns the appropriate value as the need arises. // // evaluated in the following order // 1. input variable // 2. Environment variable // 3. IAM Role // // "/.aws/credentials" necessary item increased about that, so it isn't used. func (c *Config) GetAWSCreds() (*credentials.Credentials, error) { var creds *credentials.Credentials var err error err = nil // 1. input variable used if c.Aws.Accesskey != "" && c.Aws.SecretKey != "" { creds = credentials.NewStaticCredentials(c.Aws.Accesskey, c.Aws.SecretKey, "") creds.Expire() _, err = creds.Get() } if err != nil { // 2. Environment variable used creds = credentials.NewEnvCredentials() creds.Expire() _, err = creds.Get() if err != nil { // 3. IAM Role used creds = credentials.NewCredentials(&ec2rolecreds.EC2RoleProvider{}) creds.Expire() _, err = creds.Get() } } return creds, err }
func (p *VaultProvider) getSessionToken(creds *credentials.Value) (sts.Credentials, error) { params := &sts.GetSessionTokenInput{ DurationSeconds: aws.Int64(int64(p.SessionDuration.Seconds())), } if mfa, ok := p.profiles[p.profile]["mfa_serial"]; ok { params.SerialNumber = aws.String(mfa) if p.MfaToken == "" { token, err := p.MfaPrompt(fmt.Sprintf("Enter token for %s: ", mfa)) if err != nil { return sts.Credentials{}, err } params.TokenCode = aws.String(token) } else { params.TokenCode = aws.String(p.MfaToken) } } client := sts.New(session.New(&aws.Config{ Credentials: credentials.NewCredentials(&credentials.StaticProvider{ Value: *creds, }), })) log.Printf("Getting new session token for profile %s", sourceProfile(p.profile, p.profiles)) resp, err := client.GetSessionToken(params) if err != nil { return sts.Credentials{}, err } return *resp.Credentials, nil }
func TestAfterRetryRefreshCreds(t *testing.T) { os.Clearenv() credProvider := &mockCredsProvider{} svc := NewService(&Config{Credentials: credentials.NewCredentials(credProvider), MaxRetries: 1}) svc.Handlers.Clear() svc.Handlers.ValidateResponse.PushBack(func(r *Request) { r.Error = apierr.New("UnknownError", "", nil) r.HTTPResponse = &http.Response{StatusCode: 400} }) svc.Handlers.UnmarshalError.PushBack(func(r *Request) { r.Error = apierr.New("ExpiredTokenException", "", nil) }) svc.Handlers.AfterRetry.PushBack(func(r *Request) { AfterRetryHandler(r) }) assert.True(t, svc.Config.Credentials.IsExpired(), "Expect to start out expired") assert.False(t, credProvider.retreiveCalled) req := NewRequest(svc, &Operation{Name: "Operation"}, nil, nil) req.Send() assert.True(t, svc.Config.Credentials.IsExpired()) assert.False(t, credProvider.retreiveCalled) _, err := svc.Config.Credentials.Get() assert.NoError(t, err) assert.True(t, credProvider.retreiveCalled) }
// NewCredentials returns a pointer to a new Credentials object wrapping the // AssumeRoleProvider. The credentials will expire every 15 minutes and the // role will be named after a nanosecond timestamp of this operation. // // The sts and roleARN parameters are used for building the "AssumeRole" call. // Pass nil as sts to use the default client. // // Window is the expiry window that will be subtracted from the expiry returned // by the role credential request. This is done so that the credentials will // expire sooner than their actual lifespan. func NewCredentials(client AssumeRoler, roleARN string, window time.Duration) *credentials.Credentials { return credentials.NewCredentials(&AssumeRoleProvider{ Client: client, RoleARN: roleARN, ExpiryWindow: window, }) }
func mergeConfigSrcs(cfg, userCfg *aws.Config, envCfg envConfig, sharedCfg sharedConfig, handlers request.Handlers) { // Merge in user provided configuration cfg.MergeIn(userCfg) // Region if not already set by user if len(aws.StringValue(cfg.Region)) == 0 { if len(envCfg.Region) > 0 { cfg.WithRegion(envCfg.Region) } else if envCfg.EnableSharedConfig && len(sharedCfg.Region) > 0 { cfg.WithRegion(sharedCfg.Region) } } // Configure credentials if not already set if cfg.Credentials == credentials.AnonymousCredentials && userCfg.Credentials == nil { if len(envCfg.Creds.AccessKeyID) > 0 { cfg.Credentials = credentials.NewStaticCredentialsFromCreds( envCfg.Creds, ) } else if envCfg.EnableSharedConfig && len(sharedCfg.AssumeRole.RoleARN) > 0 && sharedCfg.AssumeRoleSource != nil { cfgCp := *cfg cfgCp.Credentials = credentials.NewStaticCredentialsFromCreds( sharedCfg.AssumeRoleSource.Creds, ) cfg.Credentials = stscreds.NewCredentials( &Session{ Config: &cfgCp, Handlers: handlers.Copy(), }, sharedCfg.AssumeRole.RoleARN, func(opt *stscreds.AssumeRoleProvider) { opt.RoleSessionName = sharedCfg.AssumeRole.RoleSessionName if len(sharedCfg.AssumeRole.ExternalID) > 0 { opt.ExternalID = aws.String(sharedCfg.AssumeRole.ExternalID) } // MFA not supported }, ) } else if len(sharedCfg.Creds.AccessKeyID) > 0 { cfg.Credentials = credentials.NewStaticCredentialsFromCreds( sharedCfg.Creds, ) } else { // Fallback to default credentials provider, include mock errors // for the credential chain so user can identify why credentials // failed to be retrieved. cfg.Credentials = credentials.NewCredentials(&credentials.ChainProvider{ VerboseErrors: aws.BoolValue(cfg.CredentialsChainVerboseErrors), Providers: []credentials.Provider{ &credProviderError{Err: awserr.New("EnvAccessKeyNotFound", "failed to find credentials in the environment.", nil)}, &credProviderError{Err: awserr.New("SharedCredsLoad", fmt.Sprintf("failed to load profile, %s.", envCfg.Profile), nil)}, defaults.RemoteCredProvider(*cfg, handlers), }, }) } } }
func (c *KMSCredential) KMS() security.KMS { config := aws.NewConfig().WithCredentials(credentials.NewCredentials(c)).WithRegion(c.Region) session := session.New(config) return &KMS{ kms: kms.New(session), keyID: c.KeyID, } }
func NewVaultCredentials(k keyring.Keyring, profile string, opts VaultOptions) (*VaultCredentials, error) { provider, err := NewVaultProvider(k, profile, opts) if err != nil { return nil, err } return &VaultCredentials{credentials.NewCredentials(provider), provider}, nil }
func connect(profile string) *route53.Route53 { return route53.New(&aws.Config{ Region: aws.String("eu-west-1"), Credentials: credentials.NewCredentials(&credentials.SharedCredentialsProvider{ Profile: profile, }), }) }
func (dynamoDBSource *DynamoDBSource) Get() (map[string]interface{}, error) { config := defaults.Config() if dynamoDBSource.AccessKey != "" { config = config.WithCredentials(credentials.NewCredentials(&credentials.StaticProvider{ Value: credentials.Value{ AccessKeyID: dynamoDBSource.AccessKey, SecretAccessKey: dynamoDBSource.SecretKey, }, })) } if dynamoDBSource.Endpoint != "" { config = config.WithEndpoint(dynamoDBSource.Endpoint) } if dynamoDBSource.Region != "" { config = config.WithRegion(dynamoDBSource.Region) } else { config = config.WithRegion("us-west-1") } client := dynamodb.New(session.New(config)) tableName := aws.String(dynamoDBSource.Table) describeTableInput := &dynamodb.DescribeTableInput{TableName: tableName} if _, err := client.DescribeTable(describeTableInput); err != nil { return nil, err } if err := client.WaitUntilTableExists(describeTableInput); err != nil { return nil, err } key := dynamoDBSource.Key response, err := client.GetItem(&dynamodb.GetItemInput{ Key: map[string]*dynamodb.AttributeValue{ "key": {S: aws.String(key)}, }, TableName: tableName, ConsistentRead: aws.Bool(true), }) if err != nil { return nil, err } result := make(map[string]interface{}) err = dynamodbattribute.ConvertFromMap(response.Item, &result) delete(result, key) return result, err }
func newScheduler(t testing.TB) *ecs.Scheduler { creds := &credentials.EnvProvider{} if _, err := creds.Retrieve(); err != nil { t.Skip("Skipping ECS test because AWS_ environment variables are not present.") } config := defaults.DefaultConfig.WithCredentials(credentials.NewCredentials(creds)) return ecs.NewScheduler(config) }
// CredChain returns the default credential chain. // // Generally you shouldn't need to use this method directly, but // is available if you need to reset the credentials of an // existing service client or session's Config. func CredChain(cfg *aws.Config, handlers request.Handlers) *credentials.Credentials { return credentials.NewCredentials(&credentials.ChainProvider{ VerboseErrors: aws.BoolValue(cfg.CredentialsChainVerboseErrors), Providers: []credentials.Provider{ &credentials.EnvProvider{}, &credentials.SharedCredentialsProvider{Filename: "", Profile: ""}, RemoteCredProvider(*cfg, handlers), }, }) }
func (c *KMSCredential) KMS() security.KMS { config := &aws.Config{ Credentials: credentials.NewCredentials(c), Region: &c.Region, } return &KMS{ kms: kms.New(config), keyID: c.KeyID, } }
// NewCredentials returns a pointer to a new Credentials object wrapping // the EC2RoleProvider. Takes a ConfigProvider to create a EC2Metadata client. // The ConfigProvider is satisfied by the session.Session type. func NewCredentials(c client.ConfigProvider, options ...func(*EC2RoleProvider)) *credentials.Credentials { p := &EC2RoleProvider{ Client: ec2metadata.New(c), } for _, option := range options { option(p) } return credentials.NewCredentials(p) }
// NewUserBucket creates new bucket value for the given configuration. func NewUserBucket(cfg *Config) *UserBucket { p := NewProvider(cfg) return &UserBucket{ cfg: cfg, s3: s3.New(session.New(&aws.Config{ Credentials: credentials.NewCredentials(p), Region: aws.String(cfg.region()), })), } }
// newManagedInstanceCredentials returns a pointer to a new Credentials object wrapping // the managedInstancesRoleProvider. func newManagedInstanceCredentials() *credentials.Credentials { instanceID := managedInstance.InstanceID() region := managedInstance.Region() privateKey := managedInstance.PrivateKey() p := &managedInstancesRoleProvider{ Client: rsaauth.NewRsaService(instanceID, region, privateKey), ExpiryWindow: EarlyExpiryTimeWindow, } return credentials.NewCredentials(p) }
// NewCredentialsWithClient returns a pointer to a new Credentials object wrapping // the EC2RoleProvider. Takes a EC2Metadata client to use when connecting to EC2 // metadata service. func NewCredentialsWithClient(client *ec2metadata.EC2Metadata, options ...func(*EC2RoleProvider)) *credentials.Credentials { p := &EC2RoleProvider{ Client: client, } for _, option := range options { option(p) } return credentials.NewCredentials(p) }
func mergeConfigSrcs(cfg, userCfg *aws.Config, envCfg envConfig, sharedCfg sharedConfig, handlers request.Handlers) { // Merge in user provided configuration cfg.MergeIn(userCfg) // Region if not already set by user if len(aws.StringValue(cfg.Region)) == 0 { if len(envCfg.Region) > 0 { cfg.WithRegion(envCfg.Region) } else if envCfg.EnableSharedConfig && len(sharedCfg.Region) > 0 { cfg.WithRegion(sharedCfg.Region) } } // Configure credentials if not already set if cfg.Credentials == credentials.AnonymousCredentials && userCfg.Credentials == nil { if len(envCfg.Creds.AccessKeyID) > 0 { cfg.Credentials = credentials.NewStaticCredentialsFromCreds( envCfg.Creds, ) } else if envCfg.EnableSharedConfig && len(sharedCfg.AssumeRole.RoleARN) > 0 && sharedCfg.AssumeRoleSource != nil { cfgCp := *cfg cfgCp.Credentials = credentials.NewStaticCredentialsFromCreds( sharedCfg.AssumeRoleSource.Creds, ) cfg.Credentials = stscreds.NewCredentials( &Session{ Config: &cfgCp, Handlers: handlers.Copy(), }, sharedCfg.AssumeRole.RoleARN, func(opt *stscreds.AssumeRoleProvider) { opt.RoleSessionName = sharedCfg.AssumeRole.RoleSessionName if len(sharedCfg.AssumeRole.ExternalID) > 0 { opt.ExternalID = aws.String(sharedCfg.AssumeRole.ExternalID) } // MFA not supported }, ) } else if len(sharedCfg.Creds.AccessKeyID) > 0 { cfg.Credentials = credentials.NewStaticCredentialsFromCreds( sharedCfg.Creds, ) } else { // Fallback to default credentials provider cfg.Credentials = credentials.NewCredentials( defaults.RemoteCredProvider(*cfg, handlers), ) } } }
func NewS3(filename, profile, region string) *S3 { var creds *credentials.Credentials if _, err := os.Stat(filename); err == nil { log.Printf("Connecting to AWS using credentials from '%s'", filename) creds = credentials.NewSharedCredentials(filename, profile) } else { log.Printf("AWS credentials file '%s' dosen't exists, I will be using EC2 Role credentials", filename) sess := session.New() creds = credentials.NewCredentials(&ec2rolecreds.EC2RoleProvider{Client: ec2metadata.New(sess)}) } sess := session.New(&aws.Config{Credentials: creds, Region: aws.String(region)}) return &S3{svc: s3.New(sess)} }
// NewCredentialsWithClient returns a pointer to a new Credentials object wrapping the // AssumeRoleProvider. The credentials will expire every 15 minutes and the // role will be named after a nanosecond timestamp of this operation. // // Takes an AssumeRoler which can be satisfiede by the STS client. func NewCredentialsWithClient(svc AssumeRoler, roleARN string, options ...func(*AssumeRoleProvider)) *credentials.Credentials { p := &AssumeRoleProvider{ Client: svc, RoleARN: roleARN, Duration: DefaultDuration, } for _, option := range options { option(p) } return credentials.NewCredentials(p) }
// NewCredentials returns a pointer to a new Credentials object wrapping the // AssumeRoleProvider. The credentials will expire every 15 minutes and the // role will be named after a nanosecond timestamp of this operation. // // Takes a Config provider to create the STS client. The ConfigProvider is // satisfied by the session.Session type. func NewCredentials(c client.ConfigProvider, roleARN string, options ...func(*AssumeRoleProvider)) *credentials.Credentials { p := &AssumeRoleProvider{ Client: sts.New(c), RoleARN: roleARN, Duration: DefaultDuration, } for _, option := range options { option(p) } return credentials.NewCredentials(p) }
func EC2RoleAwsConfig() *aws.Config { ec2m := ec2metadata.New(session.New(), &aws.Config{ HTTPClient: &http.Client{Timeout: 10 * time.Second}, Endpoint: aws.String("http://169.254.169.254/latest"), }) cr := credentials.NewCredentials(&ec2rolecreds.EC2RoleProvider{ Client: ec2m, }) return &aws.Config{ Region: &awsRegion, Credentials: cr, } }
// CredChain returns the default credential chain. // // Generally you shouldn't need to use this method directly, but // is available if you need to reset the credentials of an // existing service client or session's Config. func CredChain(cfg *aws.Config, handlers request.Handlers) *credentials.Credentials { endpoint, signingRegion := endpoints.EndpointForRegion(ec2metadata.ServiceName, *cfg.Region, true) return credentials.NewCredentials(&credentials.ChainProvider{ VerboseErrors: aws.BoolValue(cfg.CredentialsChainVerboseErrors), Providers: []credentials.Provider{ &credentials.EnvProvider{}, &credentials.SharedCredentialsProvider{Filename: "", Profile: ""}, &ec2rolecreds.EC2RoleProvider{ Client: ec2metadata.NewClient(*cfg, handlers, endpoint, signingRegion), ExpiryWindow: 5 * time.Minute, }, }}) }
func (o *S3Behavior) Initialize(connString string) error { // bucketName can either be a single value (just the bucket name itself, defaulting to "/var/cb/data/event-forwarder" as the // temporary file directory and "us-east-1" for the AWS region), or: // // if bucketName contains two colons, treat it as follows: (temp-file-directory):(region):(bucket-name) parts := strings.SplitN(connString, ":", 2) if len(parts) == 1 { o.bucketName = connString o.region = "us-east-1" } else if len(parts) == 2 { o.bucketName = parts[1] o.region = parts[0] } else { return errors.New(fmt.Sprintf("Invalid connection string: '%s' should look like (temp-file-directory):(region):bucket-name", connString)) } awsConfig := &aws.Config{Region: aws.String(o.region)} if config.S3CredentialProfileName != nil { parts = strings.SplitN(*config.S3CredentialProfileName, ":", 2) credentialProvider := credentials.SharedCredentialsProvider{} if len(parts) == 2 { credentialProvider.Filename = parts[0] credentialProvider.Profile = parts[1] } else { credentialProvider.Profile = parts[0] } creds := credentials.NewCredentials(&credentialProvider) awsConfig.Credentials = creds } sess := session.New(awsConfig) o.out = s3.New(sess) _, err := o.out.HeadBucket(&s3.HeadBucketInput{Bucket: &o.bucketName}) if err != nil { return errors.New(fmt.Sprintf("Could not open bucket %s: %s", o.bucketName, err)) } return nil }
// Use IAM roles to get credentials func NewCloudWatchConnection() *CloudWatchConn { creds := credentials.NewCredentials(&ec2rolecreds.EC2RoleProvider{}) creds.Expire() credsValue, _ := creds.Get() metadata := ec2metadata.GetMetadata() mdAV := *metadata.AvailabilityZone region := mdAV[:len(mdAV)-1] cw_conn := &CloudWatchConn{cloudwatch.New(&aws.Config{Region: aws.String(region), Credentials: credentials.NewStaticCredentials( credsValue.AccessKeyID, credsValue.SecretAccessKey, credsValue.SessionToken)}), metadata} return cw_conn }
func assumeRole(roleArn string) { client := sts.New(session.New()) duration := time.Hour * 1 stsProvider := &stscreds.AssumeRoleProvider{ Client: client, Duration: duration, RoleARN: roleArn, RoleSessionName: "drone", } value, err := credentials.NewCredentials(stsProvider).Get() if err != nil { logrus.WithFields(logrus.Fields{ "error": err, }).Fatal("Error assuming role!") } os.Setenv("AWS_ACCESS_KEY_ID", value.AccessKeyID) os.Setenv("AWS_SECRET_ACCESS_KEY", value.SecretAccessKey) os.Setenv("AWS_SESSION_TOKEN", value.SessionToken) }
func TestPreResignRequestExpiredCreds(t *testing.T) { provider := &credentials.StaticProvider{Value: credentials.Value{ AccessKeyID: "AKID", SecretAccessKey: "SECRET", SessionToken: "SESSION", }} creds := credentials.NewCredentials(provider) svc := awstesting.NewClient(&aws.Config{Credentials: creds}) r := svc.NewRequest( &request.Operation{ Name: "BatchGetItem", HTTPMethod: "POST", HTTPPath: "/", }, nil, nil, ) r.ExpireTime = time.Minute * 10 SignSDKRequest(r) querySig := r.HTTPRequest.URL.Query().Get("X-Amz-Signature") signedHeaders := r.HTTPRequest.URL.Query().Get("X-Amz-SignedHeaders") assert.NotEmpty(t, signedHeaders) origSignedAt := r.LastSignedAt creds.Expire() signSDKRequestWithCurrTime(r, func() time.Time { // Simulate the request occurred 15 minutes in the past return time.Now().Add(-48 * time.Hour) }) assert.NotEqual(t, querySig, r.HTTPRequest.URL.Query().Get("X-Amz-Signature")) resignedHeaders := r.HTTPRequest.URL.Query().Get("X-Amz-SignedHeaders") assert.Equal(t, signedHeaders, resignedHeaders) assert.NotContains(t, signedHeaders, "x-amz-signedHeaders") assert.NotEqual(t, origSignedAt, r.LastSignedAt) }