Skip to content

Commit

Permalink
add token supplier for easier WIF exchange
Browse files Browse the repository at this point in the history
  • Loading branch information
vinay-gopalan committed Apr 26, 2024
1 parent 1c0b4a2 commit 0cdd7f1
Showing 1 changed file with 29 additions and 12 deletions.
41 changes: 29 additions & 12 deletions plugin/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@ import (
"github.com/hashicorp/errwrap"
"github.com/hashicorp/go-cleanhttp"
"github.com/hashicorp/go-gcp-common/gcputil"
"github.com/hashicorp/go-hclog"
"github.com/hashicorp/vault/sdk/framework"
"github.com/hashicorp/vault/sdk/helper/pluginutil"
"github.com/hashicorp/vault/sdk/helper/useragent"
"github.com/hashicorp/vault/sdk/logical"
"golang.org/x/oauth2"
"golang.org/x/oauth2/google"
"golang.org/x/oauth2/google/externalaccount"
"google.golang.org/api/iam/v1"
"google.golang.org/api/option"

Expand Down Expand Up @@ -177,7 +179,14 @@ func (b *backend) credentials(s logical.Storage) (*google.Credentials, error) {
return nil, errwrap.Wrapf("failed to parse credentials: {{err}}", err)
}
} else if cfg.IdentityTokenAudience != "" {
creds, err = b.GetExternalAccountConfig(cfg).GetCredentials()
ts := &PluginIdentityTokenSupplier{
sys: b.System(),
logger: b.Logger(),
audience: cfg.IdentityTokenAudience,
ttl: cfg.IdentityTokenTTL,
}

creds, err = b.GetExternalAccountConfig(cfg, ts).GetExternalAccountCredentials(ctx)
if err != nil {
return nil, fmt.Errorf(fmt.Sprintf("failed to fetch external account credentials: %s", err))
}
Expand All @@ -196,32 +205,40 @@ func (b *backend) credentials(s logical.Storage) (*google.Credentials, error) {
return creds.(*google.Credentials), nil
}

func (b *backend) GetExternalAccountConfig(c *config) *gcputil.ExternalAccountConfig {
func (b *backend) GetExternalAccountConfig(c *config, ts *PluginIdentityTokenSupplier) *gcputil.ExternalAccountConfig {
b.Logger().Info("adding web identity token fetcher")
cfg := &gcputil.ExternalAccountConfig{
ServiceAccountEmail: c.ServiceAccountEmail,
Audience: c.IdentityTokenAudience,
TTL: c.IdentityTokenTTL,
TokenFetcher: b.FetchWorkloadIdentityToken,
TokenSupplier: ts,
}

return cfg
}

func (b *backend) FetchWorkloadIdentityToken(ctx context.Context, cfg *gcputil.ExternalAccountConfig) (string, error) {
b.Logger().Info("fetching new plugin identity token")
resp, err := b.System().GenerateIdentityToken(ctx, &pluginutil.IdentityTokenRequest{
Audience: cfg.Audience,
TTL: cfg.TTL,
type PluginIdentityTokenSupplier struct {
sys logical.SystemView
logger hclog.Logger
audience string
ttl time.Duration
}

var _ externalaccount.SubjectTokenSupplier = (*PluginIdentityTokenSupplier)(nil)

func (p *PluginIdentityTokenSupplier) SubjectToken(ctx context.Context, opts externalaccount.SupplierOptions) (string, error) {
p.logger.Info("fetching new plugin identity token")
resp, err := p.sys.GenerateIdentityToken(ctx, &pluginutil.IdentityTokenRequest{
Audience: p.audience,
TTL: p.ttl,
})
if err != nil {
return "", fmt.Errorf("failed to generate plugin identity token: %w", err)
}
b.Logger().Info("fetched new plugin identity token")

if resp.TTL < cfg.TTL {
b.Logger().Debug("generated plugin identity token has shorter TTL than requested",
"requested", cfg.TTL.Seconds(), "actual", resp.TTL)
if resp.TTL < p.ttl {
p.logger.Debug("generated plugin identity token has shorter TTL than requested",
"requested", p.ttl.Seconds(), "actual", resp.TTL)
}

return resp.Token.Token(), nil
Expand Down

0 comments on commit 0cdd7f1

Please sign in to comment.