func New(opts ...Option) (Authorizerd, error) {
	var (
		prov = &authority{
			cache: gache.New(),
		}
		err    error
		pkPro  pubkey.Provider
		jwkPro jwk.Provider
	)
	for _, opt := range append(defaultOptions, opts...) {
		if err = opt(prov); err != nil {
			return nil, errors.Wrap(err, "error creating authorizerd")
		}
	}
	if !prov.disablePubkeyd {
		if prov.pubkeyd, err = pubkey.New(
			pubkey.WithAthenzURL(prov.athenzURL),
			pubkey.WithSysAuthDomain(prov.pubkeySysAuthDomain),
			pubkey.WithETagExpiry(prov.pubkeyETagExpiry),
			pubkey.WithETagPurgePeriod(prov.pubkeyETagPurgePeriod),
			pubkey.WithRefreshPeriod(prov.pubkeyRefreshPeriod),
			pubkey.WithRetryDelay(prov.pubkeyRetryDelay),
			pubkey.WithHTTPClient(prov.client),
		); err != nil {
			return nil, err
		}
		pkPro = prov.pubkeyd.GetProvider()
	}
	if !prov.disablePolicyd {
		if prov.policyd, err = policy.New(
			policy.WithAthenzURL(prov.athenzURL),
			policy.WithAthenzDomains(prov.athenzDomains...),
			policy.WithExpiryMargin(prov.policyExpiryMargin),
			policy.WithRefreshPeriod(prov.policyRefreshPeriod),
			policy.WithPurgePeriod(prov.policyPurgePeriod),
			policy.WithRetryDelay(prov.policyRetryDelay),
			policy.WithRetryAttempts(prov.policyRetryAttempts),
			policy.WithHTTPClient(prov.client),
			policy.WithPubKeyProvider(pkPro),
		); err != nil {
			return nil, err
		}
	}
	if !prov.disableJwkd {
		if prov.jwkd, err = jwk.New(
			jwk.WithAthenzJwksURL(prov.athenzURL),
			jwk.WithRefreshPeriod(prov.jwkRefreshPeriod),
			jwk.WithRetryDelay(prov.jwkRetryDelay),
			jwk.WithURLs(prov.jwkURLs),
			jwk.WithHTTPClient(prov.client),
		); err != nil {
			return nil, err
		}
		jwkPro = prov.jwkd.GetProvider()
	}
	if prov.enableRoleToken {
		if prov.roleProcessor, err = role.New(
			role.WithPubkeyProvider(pkPro),
		); err != nil {
			return nil, err
		}
	}
	if prov.accessTokenParam.enable {
		if prov.accessProcessor, err = access.New(
			access.WithJWKProvider(jwkPro),
			access.WithEnableMTLSCertificateBoundAccessToken(prov.accessTokenParam.verifyCertThumbprint),
			access.WithEnableVerifyClientID(prov.accessTokenParam.verifyClientID),
			access.WithAuthorizedClientIDs(prov.accessTokenParam.authorizedClientIDs),
			access.WithClientCertificateGoBackSeconds(prov.accessTokenParam.certBackdateDur),
			access.WithClientCertificateOffsetSeconds(prov.accessTokenParam.certOffsetDur),
		); err != nil {
			return nil, err
		}
	}
	if err = prov.initAuthorizers(); err != nil {
		return nil, errors.Wrap(err, "error create authorizers")
	}
	return prov, nil
}
New creates the Authorizerd object with the options
package authorizerd
import (
	"context"
	"crypto/x509"
	"net/http"
	"strings"
	"time"
	"github.com/golang-jwt/jwt/request"
	"github.com/kpango/gache"
	"github.com/kpango/glg"
	"github.com/pkg/errors"
	"golang.org/x/sync/errgroup"
	"github.com/yahoojapan/athenz-authorizer/v5/access"
	"github.com/yahoojapan/athenz-authorizer/v5/jwk"
	"github.com/yahoojapan/athenz-authorizer/v5/policy"
	"github.com/yahoojapan/athenz-authorizer/v5/pubkey"
	"github.com/yahoojapan/athenz-authorizer/v5/role"
)
type Authorizerd interface {
	Init(ctx context.Context) error
	Start(ctx context.Context) <-chan error
	Verify(r *http.Request, act, res string) error
	Authorize(r *http.Request, act, res string) (Principal, error)
	VerifyAccessToken(ctx context.Context, tok, act, res string, cert *x509.Certificate) error
	AuthorizeAccessToken(ctx context.Context, tok, act, res string, cert *x509.Certificate) (Principal, error)
	VerifyRoleToken(ctx context.Context, tok, act, res string) error
	AuthorizeRoleToken(ctx context.Context, tok, act, res string) (Principal, error)
	VerifyRoleCert(ctx context.Context, peerCerts []*x509.Certificate, act, res string) error
	AuthorizeRoleCert(ctx context.Context, peerCerts []*x509.Certificate, act, res string) (Principal, error)
	GetPolicyCache(ctx context.Context) map[string]interface{}
}
type authorizer func(r *http.Request, act, res string) (Principal, error)
type authority struct {
	pubkeyd         pubkey.Daemon
	policyd         policy.Daemon
	jwkd            jwk.Daemon
	roleProcessor   role.Processor
	accessProcessor access.Processor
	authorizers     []authorizer
	athenzURL string
	client    *http.Client
	cache    gache.Gache
	cacheExp time.Duration
	roleCertURIPrefix string
	disablePubkeyd        bool
	pubkeyRefreshPeriod   string
	pubkeyRetryDelay      string
	pubkeySysAuthDomain   string
	pubkeyETagExpiry      string
	pubkeyETagPurgePeriod string
	disablePolicyd      bool
	athenzDomains       []string
	policyExpiryMargin  string
	policyRefreshPeriod string
	policyPurgePeriod   string
	policyRetryDelay    string
	policyRetryAttempts int
	disableJwkd      bool
	jwkRefreshPeriod string
	jwkRetryDelay    string
	jwkURLs          []string
	accessTokenParam AccessTokenParam
	enableRoleToken bool
	roleAuthHeader  string
	enableRoleCert bool
	translator Translator
}
type mode uint8
const (
	cacheKeyDelimiter      = ':'
	roleInCNDelimiter      = ":role."
	roleToken         mode = iota
	accessToken
)