func (c *Client) ValidateJWTSVID(ctx context.Context, token, audience string) (*jwtsvid.SVID, error) {
	ctx, cancel := context.WithCancel(withHeader(ctx))
	defer cancel()
	_, err := c.wlClient.ValidateJWTSVID(ctx, &workload.ValidateJWTSVIDRequest{
		Svid:     token,
		Audience: audience,
	})
	if err != nil {
		return nil, err
	}
	return jwtsvid.ParseInsecure(token, []string{audience})
}
ValidateJWTSVID validates the JWT-SVID token. The parsed and validated
JWT-SVID is returned.
package workloadapi
import (
	"context"
	"crypto/x509"
	"errors"
	"fmt"
	"time"
	"github.com/spiffe/go-spiffe/v2/bundle/jwtbundle"
	"github.com/spiffe/go-spiffe/v2/bundle/x509bundle"
	"github.com/spiffe/go-spiffe/v2/logger"
	"github.com/spiffe/go-spiffe/v2/proto/spiffe/workload"
	"github.com/spiffe/go-spiffe/v2/spiffeid"
	"github.com/spiffe/go-spiffe/v2/svid/jwtsvid"
	"github.com/spiffe/go-spiffe/v2/svid/x509svid"
	"google.golang.org/grpc"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/metadata"
	"google.golang.org/grpc/status"
)
type Client struct {
	conn     *grpc.ClientConn
	wlClient workload.SpiffeWorkloadAPIClient
	config   clientConfig
}
func New(ctx context.Context, options ...ClientOption) (*Client, error) {
	c := &Client{
		config: defaultClientConfig(),
	}
	for _, opt := range options {
		opt.configureClient(&c.config)
	}
	err := c.setAddress()
	if err != nil {
		return nil, err
	}
	c.conn, err = c.newConn(ctx)
	if err != nil {
		return nil, err
	}
	c.wlClient = workload.NewSpiffeWorkloadAPIClient(c.conn)
	return c, nil
}
func (c *Client) Close() error {
	return c.conn.Close()
}
func (c *Client) FetchX509SVID(ctx context.Context) (*x509svid.SVID, error) {
	ctx, cancel := context.WithCancel(withHeader(ctx))
	defer cancel()
	stream, err := c.wlClient.FetchX509SVID(ctx, &workload.X509SVIDRequest{})
	if err != nil {
		return nil, err
	}
	resp, err := stream.Recv()
	if err != nil {
		return nil, err
	}
	svids, err := parseX509SVIDs(resp, true)
	if err != nil {
		return nil, err
	}
	return svids[0], nil
}
func (c *Client) FetchX509SVIDs(ctx context.Context) ([]*x509svid.SVID, error) {
	ctx, cancel := context.WithCancel(withHeader(ctx))
	defer cancel()
	stream, err := c.wlClient.FetchX509SVID(ctx, &workload.X509SVIDRequest{})
	if err != nil {
		return nil, err
	}
	resp, err := stream.Recv()
	if err != nil {
		return nil, err
	}
	return parseX509SVIDs(resp, false)
}
func (c *Client) FetchX509Bundles(ctx context.Context) (*x509bundle.Set, error) {
	ctx, cancel := context.WithCancel(withHeader(ctx))
	defer cancel()
	stream, err := c.wlClient.FetchX509SVID(ctx, &workload.X509SVIDRequest{})
	if err != nil {
		return nil, err
	}
	resp, err := stream.Recv()
	if err != nil {
		return nil, err
	}
	return parseX509Bundles(resp)
}
func (c *Client) FetchX509Context(ctx context.Context) (*X509Context, error) {
	ctx, cancel := context.WithCancel(withHeader(ctx))
	defer cancel()
	stream, err := c.wlClient.FetchX509SVID(ctx, &workload.X509SVIDRequest{})
	if err != nil {
		return nil, err
	}
	resp, err := stream.Recv()
	if err != nil {
		return nil, err
	}
	return parseX509Context(resp)
}
func (c *Client) WatchX509Context(ctx context.Context, watcher X509ContextWatcher) error {
	backoff := newBackoff()
	for {
		err := c.watchX509Context(ctx, watcher, backoff)
		watcher.OnX509ContextWatchError(err)
		err = c.handleWatchError(ctx, err, backoff)
		if err != nil {
			return err
		}
	}
}
func (c *Client) FetchJWTSVID(ctx context.Context, params jwtsvid.Params) (*jwtsvid.SVID, error) {
	ctx, cancel := context.WithCancel(withHeader(ctx))
	defer cancel()
	audience := append([]string{params.Audience}, params.ExtraAudiences...)
	resp, err := c.wlClient.FetchJWTSVID(ctx, &workload.JWTSVIDRequest{
		SpiffeId: params.Subject.String(),
		Audience: audience,
	})
	if err != nil {
		return nil, err
	}
	if len(resp.Svids) == 0 {
		return nil, errors.New("there were no SVIDs in the response")
	}
	return jwtsvid.ParseInsecure(resp.Svids[0].Svid, audience)
}
func (c *Client) FetchJWTBundles(ctx context.Context) (*jwtbundle.Set, error) {
	ctx, cancel := context.WithCancel(withHeader(ctx))
	defer cancel()
	stream, err := c.wlClient.FetchJWTBundles(ctx, &workload.JWTBundlesRequest{})
	if err != nil {
		return nil, err
	}
	resp, err := stream.Recv()
	if err != nil {
		return nil, err
	}
	return parseJWTSVIDBundles(resp)
}
func (c *Client) WatchJWTBundles(ctx context.Context, watcher JWTBundleWatcher) error {
	backoff := newBackoff()
	for {
		err := c.watchJWTBundles(ctx, watcher, backoff)
		watcher.OnJWTBundlesWatchError(err)
		err = c.handleWatchError(ctx, err, backoff)
		if err != nil {
			return err
		}
	}
}