Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Log caller identity for debugging credentials #7

Merged
merged 1 commit into from
Aug 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,23 @@ $ cd signer
$ go test
```

## Troubleshooting
### Finding out which identity is being used
You may receive an `Access denied` error and there may be some doubt as to which credential is being exactly used. The credential may be sourced from a role ARN, EC2 instance profile, credential profile etc.
You can set the field `AwsDebugCreds` set to true before getting the token:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did not understand this. How will customers set this to true? Is it a method argument?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, it looks like it is a first class field. Is it not an anti-pattern in Go to be able to use such setters?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is like a script and not a class, it is a field that can be set directly. I have avoided adding additional argument to function for parity.


```go
signer.AwsDebugCreds = true
```
the client library will print a debug log of the form:
```
Credentials Identity: {UserId: ABCD:test124, Account: 1234567890, Arn: arn:aws:sts::1234567890:assumed-role/abc/test124}
```

The log line provides the IAM Account, IAM user id and the ARN of the IAM Principal corresponding to the credential being used.

Please note that the log level should also be set to DEBUG for this information to be logged. It is not recommended to run with AwsDebugCreds=true since it makes an additional remote call.

## Getting Help

Please use these community resources for getting help. We use the GitHub issues
Expand Down
34 changes: 34 additions & 0 deletions signer/msk_auth_token_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import (
"encoding/base64"
"encoding/hex"
"fmt"

"log"
"net/http"
"net/url"
"runtime"
Expand All @@ -16,6 +18,7 @@ import (
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/aws/signer/v4"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/credentials"
"github.com/aws/aws-sdk-go-v2/service/sts"
)

Expand All @@ -32,6 +35,7 @@ const (

var (
endpointURLTemplate = "kafka.%s.amazonaws.com" // endpointURLTemplate represents the template for the Kafka endpoint URL
AwsDebugCreds = false // AwsDebugCreds flag indicates whether credentials should be debugged
)

// GenerateAuthToken generates base64 encoded signed url as auth token from default credentials.
Expand Down Expand Up @@ -162,6 +166,10 @@ func constructAuthToken(ctx context.Context, region string, credentials *aws.Cre
return "", 0, fmt.Errorf("aws credentials cannot be empty")
}

if AwsDebugCreds {
logCallerIdentity(ctx, region, *credentials)
}

req, err := buildRequest(DefaultExpirySeconds, endpointURL)
if err != nil {
return "", 0, fmt.Errorf("failed to build request for signing: %w", err)
Expand Down Expand Up @@ -269,3 +277,29 @@ func addUserAgent(signedURL string) (string, error) {

return parsedSignedURL.String(), nil
}

// Log caller identity to debug which credentials are being picked up
func logCallerIdentity(ctx context.Context, region string, awsCredentials aws.Credentials) {
cfg, err := config.LoadDefaultConfig(ctx,
config.WithRegion(region),
config.WithCredentialsProvider(credentials.StaticCredentialsProvider{
Value: awsCredentials,
}),
)
if err != nil {
log.Printf("failed to load AWS configuration: %v", err)
}

stsClient := sts.NewFromConfig(cfg)

callerIdentity, err := stsClient.GetCallerIdentity(ctx, &sts.GetCallerIdentityInput{})

if err != nil {
log.Printf("failed to get caller identity: %v", err)
}

log.Printf("Credentials Identity: {UserId: %s, Account: %s, Arn: %s}\n",
*callerIdentity.UserId,
*callerIdentity.Account,
*callerIdentity.Arn)
}
Loading