class InstanceZTSProvider implements InstanceProvider {

    @Override
    public InstanceConfirmation confirmInstance(InstanceConfirmation confirmation) {

        // we need to validate the token which is our attestation
        // data for the service requesting a certificate

        final String instanceDomain = confirmation.getDomain();
        final String instanceService = confirmation.getService();

        final Map<String, String> instanceAttributes = confirmation.getAttributes();
        final String csrPublicKey = InstanceUtils.getInstanceProperty(instanceAttributes,
                InstanceProvider.ZTS_INSTANCE_CSR_PUBLIC_KEY);

        // make sure this service has been configured to be supported
        // by this zts provider

        if (principals != null && !principals.contains(instanceDomain + "." + instanceService)) {
            throw forbiddenError("Service not supported to be launched by ZTS Provider");
        }

        StringBuilder errMsg = new StringBuilder(256);
        if (!validateToken(confirmation.getAttestationData(), instanceDomain,
                instanceService, csrPublicKey, errMsg)) {
            LOGGER.error(errMsg.toString());
            throw forbiddenError("Unable to validate Certificate Request Auth Token");
        }

        String clientIp = InstanceUtils.getInstanceProperty(instanceAttributes, InstanceProvider.ZTS_INSTANCE_CLIENT_IP);
        String sanIpStr = InstanceUtils.getInstanceProperty(instanceAttributes, InstanceProvider.ZTS_INSTANCE_SAN_IP);
        String hostname = InstanceUtils.getInstanceProperty(instanceAttributes, InstanceProvider.ZTS_INSTANCE_HOSTNAME);
        String sanUri   = InstanceUtils.getInstanceProperty(instanceAttributes, InstanceProvider.ZTS_INSTANCE_SAN_URI);

        // validate the IP address if one is provided

        String[] sanIps = null;
        if (sanIpStr != null && !sanIpStr.isEmpty()) {
            sanIps = sanIpStr.split(",");
        }

        if (!validateSanIp(sanIps, clientIp)) {
            throw forbiddenError("Unable to validate request IP address");
        }

        // validate the hostname in payload
        // IP in clientIP can be NATed. For validating hostname, rely on sanIPs, which come from the client, and are already matched with clientIp

        if (!validateHostname(hostname, sanIps)) {
            throw forbiddenError("Unable to validate certificate request hostname");
        }

        // validate san URI
        if (!validateSanUri(sanUri, hostname)) {
            throw forbiddenError("Unable to validate certificate request URI hostname");
        }

        // validate the certificate san DNS names

        StringBuilder instanceId = new StringBuilder(256);
        if (!InstanceUtils.validateCertRequestSanDnsNames(instanceAttributes, instanceDomain,
                instanceService, dnsSuffix, instanceId)) {
            throw forbiddenError("Unable to validate certificate request DNS");
        }

        // set our cert attributes in the return object
        // for ZTS we do not allow refresh of those certificates

        Map<String, String> attributes = new HashMap<>();
        attributes.put(InstanceProvider.ZTS_CERT_REFRESH, "false");

        confirmation.setAttributes(attributes);
        return confirmation;
    }

}