func()

in auth/auth.go [123:205]


func (c *Client) Token(ctx context.Context, cfg *config.MountConfig) (*oauth2.Token, error) {

	var audience string
	idPool, idProvider, err := c.gkeWorkloadIdentity(ctx, cfg)
	if err != nil {
		idPool, idProvider, audience, err = c.fleetWorkloadIdentity(ctx, cfg)
		if err != nil {
			return nil, err
		}
	}
	if audience == "" {
		audience = fmt.Sprintf("identitynamespace:%s:%s", idPool, idProvider)
		klog.V(5).InfoS("workload id configured", "pool", idPool, "provider", idProvider)
	} else {
		klog.V(5).InfoS("workload federation pool audience", audience)
	}

	// Get iam.gke.io/gcp-service-account annotation to see if the
	// identitybindingtoken token should be traded for a GCP SA token.
	// See https://cloud.google.com/kubernetes-engine/docs/how-to/workload-identity#creating_a_relationship_between_ksas_and_gsas
	saResp, err := c.KubeClient.
		CoreV1().
		ServiceAccounts(cfg.PodInfo.Namespace).
		Get(ctx, cfg.PodInfo.ServiceAccount, v1.GetOptions{})
	if err != nil {
		return nil, fmt.Errorf("unable to fetch SA info: %w", err)
	}
	gcpSA := saResp.Annotations["iam.gke.io/gcp-service-account"]
	klog.V(5).InfoS("matched service account", "service_account", gcpSA)

	// Obtain a serviceaccount token for the pod.
	var saTokenVal string
	if cfg.PodInfo.ServiceAccountTokens != "" {
		saToken, err := c.extractSAToken(cfg, idPool, audience) // calling function to extract token received from driver.
		if err != nil {
			return nil, fmt.Errorf("unable to fetch SA token from driver: %w", err)
		}
		saTokenVal = saToken.Token
	} else {
		saToken, err := c.generatePodSAToken(ctx, cfg, idPool, audience) // if no token received, provider generates its own token.
		if err != nil {
			return nil, fmt.Errorf("unable to fetch pod token: %w", err)
		}
		saTokenVal = saToken.Token
	}

	// Trade the kubernetes token for an identitybindingtoken token.
	idBindToken, err := tradeIDBindToken(ctx, c.HTTPClient, saTokenVal, audience)
	if err != nil {
		return nil, fmt.Errorf("unable to fetch identitybindingtoken: %w", err)
	}

	// If no `iam.gke.io/gcp-service-account` annotation is present the
	// identitybindingtoken will be used directly, allowing bindings on secrets
	// of the form "serviceAccount:<project>.svc.id.goog[<namespace>/<sa>]".
	if gcpSA == "" {
		return idBindToken, nil
	}

	req := &credentialspb.GenerateAccessTokenRequest{
		Name:  fmt.Sprintf("projects/-/serviceAccounts/%s", gcpSA),
		Scope: secretmanager.DefaultAuthScopes(),
	}

	if gcpSADelegates, ok := saResp.Annotations["iam.gke.io/gcp-service-account-delegates"]; ok {
		var delegates []string
		if err := json.Unmarshal([]byte(gcpSADelegates), &delegates); err != nil {
			return nil, fmt.Errorf("unable to parse delegates annotation on SA: %w", err)
		}

		klog.V(5).InfoS("matched service account delegates", "service_account_delegates", delegates)

		for _, delegate := range delegates {
			req.Delegates = append(req.Delegates, fmt.Sprintf("projects/-/serviceAccounts/%s", delegate))
		}
	}

	gcpSAResp, err := c.IAMClient.GenerateAccessToken(ctx, req, gax.WithGRPCOptions(grpc.PerRPCCredentials(oauth.TokenSource{TokenSource: oauth2.StaticTokenSource(idBindToken)})))
	if err != nil {
		return nil, fmt.Errorf("unable to fetch gcp service account token: %w", err)
	}
	return &oauth2.Token{AccessToken: gcpSAResp.GetAccessToken()}, nil
}