Entrust Certificate Deprecation

We have an important change coming to Xero’s Partner API in early 2017.

What is happening?

Our move to Amazon Web Services has provided several new security tools through the AWS platform. Two way SSL was a great way to secure our API partner communications but it came with a high cost to implement and maintain. Modern standards allow us to give just as much security, and more, without the same overheads.

Therefore, we will begin deprecating support for 2-way SSL for Partner Apps in 2017.

How does this affect my Xero integration?

Starting in 2017, Partner Apps will be able to access Xero’s Partner API through api.xero.com without the need for Entrust SSL certificates. We will not issue new Entrust SSL certificates when yours expires. You will need to make the required changes prior to their expiration.

What do I need to change in my Xero Integration?

  • Update any reference from “https://api-partner.network.xero.com” to "https://api.xero.com/"
  • Optional: Remove Entrust SSL certificates when creating an instance of http client object. If you do nothing, Xero’s API will simply ignore the certificates. See below for any SDK specific changes.

Please continue using the same Xero Partner App you created at http://app.xero.com and continue using the same public/private key pair for RSA-SHA1 oAuth signing.

How do I test my integration?

Xero doesn’t have the concept of a developer sandbox, so we recommend using your existing Xero Partner App and the Demo company. Find out more about Xero’s Demo Company and how to use it. If you’ve been granted additional Partner Apps for development or QA, those are enable to connect via api.xero.com as well.

How do I get a Xero Partner App?

Find out more about Xero Partner apps and apply to join our Partner Program.

SDK specific changes

This section provides information regarding specific changes to be made within each of the sample SDK listed under Libraries section to get them to work in partner mode without having to use two way SSL (Entrust certificates).


The following modifications are required to run XeroOAuth-PHP library  in partner mode

  1. Update any reference from “https://api-partner.network.xero.com” to "https://api.xero.com/"
  2. Remove validation that check for entrust-private.pem and entrust-cert.pem files within cert's forlder when using 'Partner.php' here. Else it will return "Curl error: could not load PEM client certificate, OpenSSL error "
  3. if ($this->config ['application_type'] == "Partner") {
    			curl_setopt_array ( $c, array (
    					// ssl client cert options for partner apps
    					CURLOPT_SSLCERT => $this->config ['curl_ssl_cert'],
    					CURLOPT_SSLKEYPASSWD => $this->config ['curl_ssl_password'],
    					CURLOPT_SSLKEY => $this->config ['curl_ssl_key']
    			) );
  4. You will need to modify the 'XeroOAuth.php' file under the 'lib' folder  here, to ignore the certificate expiry validation before running 'partner.php' file.
if ($this->config ['application_type'] == 'Partner') {
			if (! file_get_contents ( $this->config ['curl_ssl_cert'] )) {
				$testOutput ['ssl_cert_error'] = "Can't read the Xero Entrust cert. You need one for partner API applications. https://developer.xero.com/documentation/auth-and-limits/partner-applications \n";
			} else {
				$data = openssl_x509_parse ( file_get_contents ( $this->config ['curl_ssl_cert'] ) );
				$validFrom = date ( 'Y-m-d H:i:s', $data ['validFrom_time_t'] );
				if (time () < $data ['validFrom_time_t']) {
					$testOutput ['ssl_cert_error'] = "Xero Entrust cert not yet valid - cert valid from " . $validFrom . "\n";
				$validTo = date ( 'Y-m-d H:i:s', $data ['validTo_time_t'] );
				if (time () > $data ['validTo_time_t']) {
					$testOutput ['ssl_cert_error'] = "Xero Entrust cert expired - cert valid to " . $validFrom . "\n";


Update any reference from “https://api-partner.network.xero.com” to "https://api.xero.com/"

If you're using the example partner 'Core' implementation, your app.config/web.config should be all that needs to be changed. The implementation of the example no longer requires config settings for a 'PartnerBaseUrl', 'PartnerCertificate', or 'PartnerCertificatePassword'. You should be able to simply remove these settings form your config files and have your application run as normal.

If you're not using the 'Core' classes but still instantiating the example 'PartnerAuthenticator' yourself, you'll see compilation errors and will need to remove the now extraneous parameters for the client-cert-path and password. You'll also want to swap the URL you're using from 'api-partner.network.xero.com' to 'api.xero.com'

If you've built your own implementation of the 'IAuthenticator' or 'ICertificateAuthenticator' interfaces there will probably be some more work required in addition to the config changes mentioned above. The 'ICertifacteAuthenticator' no longer exists as it only provided method outlines for methods referring to client certificates. You will need to stop inheriting from this interface. In any other 'IAuthenticator' inheriting classes you've implemented, you will want to remove any references and implementations of client certificates, and swap any uses of the 'api-partner.network.xero.com' URL to be the 'api.xero.com' URL.

You can get an idea for what may need to be changed by looking at the pull request here: https://github.com/XeroAPI/Xero-Net/pull/233.


Update any reference from “https://api-partner.network.xero.com” to "https://api.xero.com/"

If you have an existing Partner App running on a CFML engine, you'll need to remove the clientCert and clientCertPassword attributes from all cfhttp tags.


<cfhttp url="#oREQ.getString()#"


<cfhttp url="#oREQ.getString()#"


Update any reference from “https://api-partner.network.xero.com” to "https://api.xero.com/"


Update XERO_PARTNER_BASE_URL from "https://api-partner.network.xero.com” to "https://api.xero.com/" in constants.py

XERO_BASE_URL = "https://api.xero.com"
XERO_PARTNER_BASE_URL = "https://api.xero.com"

Update class PartnerCredentials(PublicCredentials): __init__(....):. Set the client_cert argument with a default equal to "None" in auth.py.

class PartnerCredentials(PublicCredentials):
    def __init__(self, consumer_key, consumer_secret, rsa_key, client_cert=None,
                 callback_uri=None, verified=False,
                 oauth_token=None, oauth_token_secret=None,
                 oauth_expires_at=None, oauth_authorization_expires_at=None,
                 oauth_session_handle=None, scope=None):


Update any reference from “https://api-partner.network.xero.com” to "https://api.xero.com/"