Skip to content

Commit

Permalink
aws/credentials/stscreds: Added TokenFetcher (#3256)
Browse files Browse the repository at this point in the history
This change makes it possible to fetch a token from an arbitrary source, rather than the file system (Ex: Fetch from an HTTP service)

```go
type FetchTokenFromMoon struct {}
func (v FetchTokenFromMoon) FetchToken(ctx credentials.Context) ([]byte, error) {
	return /* do something cool */
}
```
  • Loading branch information
micahhausler committed Apr 22, 2020
1 parent ef9f9cf commit 6a1ae3f
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 5 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG_PENDING.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
### SDK Features

### SDK Enhancements
* `aws/credentials/stscreds`: Add support for custom web identity TokenFetcher ([#3256](https://github.com/aws/aws-sdk-go/pull/3256))
* Adds new constructor, `NewWebIdentityRoleProviderWithToken` for `WebIdentityRoleProvider` which takes a `TokenFetcher`. Implement `TokenFetcher` to provide custom sources for web identity tokens. The `TokenFetcher` must be concurrency safe. `TokenFetcher` may return unique value each time it is called.

### SDK Bugs
33 changes: 28 additions & 5 deletions aws/credentials/stscreds/web_identity_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,24 @@ const (
// compare test values.
var now = time.Now

// TokenFetcher shuold return WebIdentity token bytes or an error
type TokenFetcher interface {
FetchToken(credentials.Context) ([]byte, error)
}

// FetchTokenPath is a path to a WebIdentity token file
type FetchTokenPath string

// FetchToken returns a token by reading from the filesystem
func (f FetchTokenPath) FetchToken(ctx credentials.Context) ([]byte, error) {
data, err := ioutil.ReadFile(string(f))
if err != nil {
errMsg := fmt.Sprintf("unable to read file at %s", f)
return nil, awserr.New(ErrCodeWebIdentity, errMsg, err)
}
return data, nil
}

// WebIdentityRoleProvider is used to retrieve credentials using
// an OIDC token.
type WebIdentityRoleProvider struct {
Expand All @@ -36,7 +54,7 @@ type WebIdentityRoleProvider struct {
client stsiface.STSAPI
ExpiryWindow time.Duration

tokenFilePath string
tokenFetcher TokenFetcher
roleARN string
roleSessionName string
}
Expand All @@ -52,9 +70,15 @@ func NewWebIdentityCredentials(c client.ConfigProvider, roleARN, roleSessionName
// NewWebIdentityRoleProvider will return a new WebIdentityRoleProvider with the
// provided stsiface.STSAPI
func NewWebIdentityRoleProvider(svc stsiface.STSAPI, roleARN, roleSessionName, path string) *WebIdentityRoleProvider {
return NewWebIdentityRoleProviderWithToken(svc, roleARN, roleSessionName, FetchTokenPath(path))
}

// NewWebIdentityRoleProviderWithToken will return a new WebIdentityRoleProvider with the
// provided stsiface.STSAPI and a TokenFetcher
func NewWebIdentityRoleProviderWithToken(svc stsiface.STSAPI, roleARN, roleSessionName string, tokenFetcher TokenFetcher) *WebIdentityRoleProvider {
return &WebIdentityRoleProvider{
client: svc,
tokenFilePath: path,
tokenFetcher: tokenFetcher,
roleARN: roleARN,
roleSessionName: roleSessionName,
}
Expand All @@ -71,10 +95,9 @@ func (p *WebIdentityRoleProvider) Retrieve() (credentials.Value, error) {
// 'WebIdentityTokenFilePath' specified destination and if that is empty an
// error will be returned.
func (p *WebIdentityRoleProvider) RetrieveWithContext(ctx credentials.Context) (credentials.Value, error) {
b, err := ioutil.ReadFile(p.tokenFilePath)
b, err := p.tokenFetcher.FetchToken(ctx)
if err != nil {
errMsg := fmt.Sprintf("unable to read file at %s", p.tokenFilePath)
return credentials.Value{}, awserr.New(ErrCodeWebIdentity, errMsg, err)
return credentials.Value{}, awserr.New(ErrCodeWebIdentity, "failed fetching WebIdentity token: ", err)
}

sessionName := p.roleSessionName
Expand Down

0 comments on commit 6a1ae3f

Please sign in to comment.