class AccessToken extends OAuth2Token {

    boolean confirmX509CertPrincipal(X509Certificate cert, final String cn) {

        // if our offset is 0 then the additional confirmation
        // check is disabled

        if (ACCESS_TOKEN_CERT_OFFSET == 0) {
            LOG.error("confirmX509CertPrincipal: check disabled");
            return false;
        }

        // our principal cn must be the client in the token

        if (!cn.equals(clientId)) {
            LOG.error("confirmX509CertPrincipal: Principal mismatch {} vs {}", cn, clientId);
            return false;
        }

        // if the access token cert offset is set to -1 then
        // we only need to verify that the certificate principal
        // matches to the token client id which we have already
        // verified thus we'll return success

        if (ACCESS_TOKEN_CERT_OFFSET == -1) {
            return true;
        }

        // now let's verify our offsets. the certificate must
        // be issued before our token issue time. since athenz
        // always issues certs with backdating one hour, we
        // need to take into account that extra hour

        long certIssueTime = Crypto.extractX509CertIssueTime(cert);
        if (certIssueTime < issueTime - 3600) {
            LOG.error("confirmX509CertPrincipal: Certificate: {} issued before token: {}",
                    certIssueTime, issueTime);
            return false;
        }

        // also the certificate must be issued after the configured
        // number of seconds after our token issue time. again,
        // since athenz issues certs with backdating one hour, we
        // need to take into account that extra hour

        if (certIssueTime > issueTime + ACCESS_TOKEN_CERT_OFFSET - 3600) {
            LOG.error("confirmX509CertPrincipal: Certificate: {} past configured offset {} for token: {}",
                    certIssueTime, ACCESS_TOKEN_CERT_OFFSET, issueTime);
            return false;
        }

        return true;
    }

    public  AccessToken();
    public  AccessToken(final String token, JwtsSigningKeyResolver keyResolver);
    public  AccessToken(final String token, PublicKey publicKey);
    public  AccessToken(final String token, JwtsSigningKeyResolver keyResolver,
                       X509Certificate x509Cert);
    public  AccessToken(final String token, JwtsSigningKeyResolver keyResolver,
                       X509Certificate x509Cert, final String x509CertHash);

}