func AllowTrustDomain(trustDomain string) ValidationMode {
	return validationMode{
		options: validationOptions{
			trustDomain:         trustDomain,
			trustDomainRequired: true,
			idType:              trustDomainId,
		},
	}
}
Allows a well-formed SPIFFE ID for the specific trust domain (e.g. spiffe://domain.test)
package spiffe
import (
	"crypto/x509"
	"errors"
	"fmt"
	"net/url"
	"strings"
)
type idType int
const (
	anyId idType = iota
	trustDomainId
	workloadId
)
func ValidateID(spiffeID string, mode ValidationMode) error {
	_, err := ParseID(spiffeID, mode)
	return err
}
func ValidateURI(id *url.URL, mode ValidationMode) error {
	options := mode.validationOptions()
	validationError := func(format string, args ...interface{}) error {
		var kind string
		switch options.idType {
		case trustDomainId:
			kind = "trust domain "
		case workloadId:
			kind = "workload "
		}
		var idStr string
		if id != nil {
			idStr = id.String()
		}
		return fmt.Errorf("invalid %sSPIFFE ID %q: "+format,
			append([]interface{}{kind, idStr}, args...)...)
	}
	if id == nil || *id == (url.URL{}) {
		return validationError("SPIFFE ID is empty")
	}
	switch {
	case strings.ToLower(id.Scheme) != "spiffe":
		return validationError("invalid scheme")
	case id.User != nil:
		return validationError("user info is not allowed")
	case id.Host == "":
		return validationError("trust domain is empty")
	case id.Port() != "":
		return validationError("port is not allowed")
	case id.Fragment != "":
		return validationError("fragment is not allowed")
	case id.RawQuery != "":
		return validationError("query is not allowed")
	}
	if options.trustDomainRequired {
		if options.trustDomain == "" {
			return errors.New("trust domain to validate against cannot be empty")
		}
		if id.Host != options.trustDomain {
			return fmt.Errorf("%q does not belong to trust domain %q", id, options.trustDomain)
		}
	}
	switch options.idType {
	case anyId:
	case trustDomainId:
		if id.Path != "" {
			return validationError("path is not empty")
		}
	case workloadId:
		if id.Path == "" {
			return validationError("path is empty")
		}
	default:
		return validationError("internal error: unhandled id type %v", options.idType)
	}
	return nil
}
func ParseID(spiffeID string, mode ValidationMode) (*url.URL, error) {
	u, err := url.Parse(spiffeID)
	if err != nil {
		return nil, fmt.Errorf("invalid SPIFFE ID: %v", err)
	}
	if err := ValidateURI(u, mode); err != nil {
		return nil, err
	}
	return normalizeURI(u), nil
}
type ValidationMode interface {
	validationOptions() validationOptions
}
type validationOptions struct {
	trustDomain         string
	trustDomainRequired bool
	idType              idType
}
type validationMode struct {
	options validationOptions
}
func (m validationMode) validationOptions() validationOptions {
	return m.options
}
func AllowAny() ValidationMode {
	return validationMode{}
}