class OAuthCertBoundJwtAccessTokenAuthority implements Authority, AuthorityKeyStore, KeyStore {

    @Override
    public void initialize() {
        String authnChallengeRealm = OAuthAuthorityUtils.getProperty(OAuthAuthorityConsts.JA_PROP_AUTHN_CHALLENGE_REALM, "https://athenz.io");
        this.authenticateChallenge = String.format("Bearer realm=\"%s\"", authnChallengeRealm);

        // no need to load user domain
        // this.userDomain = userDomain;

        // certificate parser
        boolean excludeRoleCertificates = Boolean.valueOf(OAuthAuthorityUtils.getProperty(OAuthAuthorityConsts.JA_PROP_CERT_EXCLUDE_ROLE_CERTIFICATES, "false"));
        Set<String> excludedPrincipals = OAuthAuthorityUtils.csvToSet(OAuthAuthorityUtils.getProperty(OAuthAuthorityConsts.JA_PROP_CERT_EXCLUDED_PRINCIPALS, ""), OAuthAuthorityConsts.CSV_DELIMITER);
        this.certificateIdentityParser = new CertificateIdentityParser(excludedPrincipals, excludeRoleCertificates);

        // JWT parser
        String jwtParserFactoryClass = OAuthAuthorityUtils.getProperty(OAuthAuthorityConsts.JA_PROP_PARSER_FACTORY_CLASS, "com.yahoo.athenz.auth.oauth.parser.DefaultOAuthJwtAccessTokenParserFactory");
        try {
            OAuthJwtAccessTokenParserFactory jwtParserFactory = (OAuthJwtAccessTokenParserFactory) Class.forName(jwtParserFactoryClass).newInstance();
            this.parser = jwtParserFactory.create(this);
        } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
            LOG.error("Invalid OAuthJwtAccessTokenParserFactory class: " + jwtParserFactoryClass + " error: " + e.getMessage());
            throw new IllegalArgumentException("Invalid JWT parser class", e);
        }

        // JWT validator controls
        this.shouldVerifyCertThumbprint = Boolean.valueOf(OAuthAuthorityUtils.getProperty(OAuthAuthorityConsts.JA_PROP_VERIFY_CERT_THUMBPRINT, "true"));
        // JWT validator client ID mapping
        String authorizedClientIdsPath = OAuthAuthorityUtils.getProperty(OAuthAuthorityConsts.JA_PROP_AUTHORIZED_CLIENT_IDS_PATH, "");
        Map<String, Set<String>> authorizedClientIds = new HashMap<>();
        Map<String, String> authorizedServices = new HashMap<>();
        this.processAuthorizedClientIds(authorizedClientIdsPath, authorizedClientIds, authorizedServices);
        this.authorizedServices = authorizedServices;
        // JWT validator values
        String trustedIssuer = OAuthAuthorityUtils.getProperty(OAuthAuthorityConsts.JA_PROP_CLAIM_ISS, "https://athenz.io");
        Set<String> requiredAudiences = OAuthAuthorityUtils.csvToSet(OAuthAuthorityUtils.getProperty(OAuthAuthorityConsts.JA_PROP_CLAIM_AUD, "https://zms.athenz.io"), OAuthAuthorityConsts.CSV_DELIMITER);
        Set<String> requiredScopes = OAuthAuthorityUtils.csvToSet(OAuthAuthorityUtils.getProperty(OAuthAuthorityConsts.JA_PROP_CLAIM_SCOPE, "sys.auth:role.admin"), OAuthJwtAccessToken.SCOPE_DELIMITER);
        // JWT validator
        this.validator = new DefaultOAuthJwtAccessTokenValidator(trustedIssuer, requiredAudiences, requiredScopes, authorizedClientIds);
    }

}