0

Using Golang with go-aws-sdk and having some issues catching invalid session credentials.

Using the shared credential files in ~/.aws/{config, credentials}

Sess, err := session.NewSessionWithOptions(session.Options{
    Profile: instance.Config.AWS.AWSProfile,
})

Works fine when the credentials are valid, but if I use an invalid aws_access_key_id in the credentials file, I need a way to detect this with my AWSLogin() func.

What's happening is any subsequent calls to an AWS service raises a panic when using Sess above.

How can I detect a failed login with the above NewSessionWithOptions() method?

UPDATE: yes, the error type is nil, so the following is of no use:

 if err != nil {
        return nil, fmt.Errorf("Error logging into AWS: %v", err.Error())
    }
buildmaestro
  • 1,386
  • 5
  • 22
  • 37
  • Maybe you can use a dummy call and `recover`? This way you can at least catch the error on something you know should work in most cases. – kichik Feb 26 '19 at 19:21
  • I was also mentally going down this path.. We use the least privilege model though so I'm wondering which service I can make a call to that every account should have access to? – buildmaestro Feb 26 '19 at 20:08
  • 1
    Try getting the user id like https://stackoverflow.com/q/33332050/492773 – kichik Feb 26 '19 at 22:29
  • @kichik I ended up testing by listing a known S3 bucket this instance will privedges for. I had the code on hand, but I feel like iam.currentUser as you mentioned would be better. – buildmaestro Feb 26 '19 at 22:45
  • Check this other question: https://stackoverflow.com/questions/33068055/boto3-python-and-how-to-handle-errors – razimbres Feb 26 '19 at 23:28

2 Answers2

0

So you would have to check for invalid errors after making a call to aws. Try and use Credentials.Get() and see if err != nil

  • funny enough, this is exactly what I was trying, but it just prints the invalid access key id that was provided: // log which AWS API Key is being used svc := s3.New(Sess) credentials, err := svc.Config.Credentials.Get() fmt.Printf("Using Access Key ID: (%v)\n", credentials.AccessKeyID) – buildmaestro Feb 26 '19 at 20:20
  • Credentials.Get() is just a test that the credentials can be loaded (environment variables, shared config, instance profile, etc). Unfortunately it can't determine if the credentials are invalid (as far as I know) – buildmaestro Feb 26 '19 at 22:47
0

Here's what I ended up doing. Test that credentials are loaded, test a known service such as an S3 bucket this application needs access to.

// login to AWS
AWSProfile := "default"
fmt.Printf("Using AWS Profile: %v\n", instance.Config.AWS.AWSProfile)
Sess, err := session.NewSessionWithOptions(session.Options{
    Profile: AWSProfile,
})
if err != nil {
    return fmt.Errorf("Error logging into AWS: %v", err.Error())
}

// attempt to load config (e.g. env variables, shared config, instance profile) 
// log which AWS API Key is being used
svc := s3.New(Sess)
credentials, err := svc.Config.Credentials.Get()
if err != nil {
    return errors.New("Error logging into AWS. Check Credentials.")
}
fmt.Printf("Using Access Key ID: (%v)\n", credentials.AccessKeyID)
bucketName := "s3bucketname"

// test the login can access a typical aws service (s3) and known bucket 
params := &s3.ListObjectsInput {
    Bucket: aws.String(bucketName),
}
resp, _ := svc.ListObjects(params)

if len(resp.Contents) < 1 {
    return nil, fmt.Errorf("Error logging into AWS. Can not access bucket (%v). Check Credentials.", bucketName)
}
buildmaestro
  • 1,386
  • 5
  • 22
  • 37