diff --git a/pkg/vpn/bonafide/auth_sip.go b/pkg/vpn/bonafide/auth_sip.go
index d8ebedb924306c6ad3cbce31265b6cc4e0ba6753..072812f907433e7a011d9686ac16b640b4172f96 100644
--- a/pkg/vpn/bonafide/auth_sip.go
+++ b/pkg/vpn/bonafide/auth_sip.go
@@ -19,7 +19,6 @@ import (
 	"encoding/json"
 	"fmt"
 	"io/ioutil"
-	"log"
 	"net/http"
 	"strings"
 )
@@ -33,11 +32,11 @@ func (a *SipAuthentication) GetPemCertificate() ([]byte, error) {
 	if cred == nil {
 		return nil, fmt.Errorf("Need bonafide credentials for sip auth")
 	}
-	credJson, err := formatCredentials(cred.User, cred.Password)
+	credJSON, err := formatCredentials(cred.User, cred.Password)
 	if err != nil {
 		return nil, fmt.Errorf("Cannot encode credentials: %s", err)
 	}
-	token, err := a.getToken(credJson)
+	token, err := a.getToken(credJSON)
 	if err != nil {
 		return nil, fmt.Errorf("Error while getting token: %s", err)
 	}
@@ -49,7 +48,11 @@ func (a *SipAuthentication) GetPemCertificate() ([]byte, error) {
 }
 
 func (a *SipAuthentication) getProtectedCert(token string) ([]byte, error) {
-	req, err := http.NewRequest("POST", certAPI, strings.NewReader(""))
+	certURL, err := a.bonafide.GetURL("certv3")
+	if err != nil {
+		return nil, err
+	}
+	req, err := http.NewRequest("POST", certURL, strings.NewReader(""))
 	req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", token))
 	resp, err := a.bonafide.client.Do(req)
 	if err != nil {
@@ -57,7 +60,7 @@ func (a *SipAuthentication) getProtectedCert(token string) ([]byte, error) {
 	}
 	defer resp.Body.Close()
 	if resp.StatusCode != 200 {
-		return nil, fmt.Errorf("Cannot get cert: Error %d", resp.StatusCode)
+		return nil, fmt.Errorf("Error %d", resp.StatusCode)
 	}
 	return ioutil.ReadAll(resp.Body)
 }
@@ -67,9 +70,13 @@ func (a *SipAuthentication) getToken(credJson string) ([]byte, error) {
 	[ ] get token from disk?
 	[ ] check if expired? set a goroutine to refresh it periodically?
 	*/
-	resp, err := http.Post(authAPI, "text/json", strings.NewReader(credJson))
+	authURL, err := a.bonafide.GetURL("auth")
+	if err != nil {
+		return nil, fmt.Errorf("Error getting auth url")
+	}
+	resp, err := http.Post(authURL, "text/json", strings.NewReader(credJson))
 	if err != nil {
-		log.Fatal("Error on auth request: ", err)
+		return nil, fmt.Errorf("Error on auth request: %v", err)
 	}
 	defer resp.Body.Close()
 	if resp.StatusCode != 200 {
@@ -80,9 +87,9 @@ func (a *SipAuthentication) getToken(credJson string) ([]byte, error) {
 
 func formatCredentials(user, pass string) (string, error) {
 	c := Credentials{User: user, Password: pass}
-	credJson, err := json.Marshal(c)
+	credJSON, err := json.Marshal(c)
 	if err != nil {
 		return "", err
 	}
-	return string(credJson), nil
+	return string(credJSON), nil
 }
diff --git a/pkg/vpn/bonafide/bonafide.go b/pkg/vpn/bonafide/bonafide.go
index 16a900d4c81ee3d3009b951f085f67971e5ba336..1bc60724c0533f8181dcfe55fa8ade2ea355a1dc 100644
--- a/pkg/vpn/bonafide/bonafide.go
+++ b/pkg/vpn/bonafide/bonafide.go
@@ -30,23 +30,29 @@ import (
 )
 
 const (
-	certAPI               = config.APIURL + "1/cert"
-	certAPI3              = config.APIURL + "3/cert"
-	authAPI               = config.APIURL + "3/auth"
 	secondsPerHour        = 60 * 60
 	retryFetchJSONSeconds = 15
 )
 
-// Bonafide exposes all the methods needed to communicate with the LEAP server.
+const (
+	certPathv1 = "1/cert"
+	certPathv3 = "3/cert"
+	authPathv3 = "3/auth"
+
+	certAPI  = config.APIURL + certPathv1
+	certAPI3 = config.APIURL + certPathv3
+	authAPI  = config.APIURL + authPathv3
+)
+
 type Bonafide struct {
 	client        httpClient
 	eip           *eipService
 	tzOffsetHours int
 	auth          Authentication
 	credentials   *Credentials
+	apiURL        string
 }
 
-// A Gateway is each one of the remotes we can pass to OpenVPN. It contains a description of all the fields that the eip-service advertises.
 type Gateway struct {
 	Host      string
 	IPAddress string
@@ -106,7 +112,33 @@ func (b *Bonafide) SetCredentials(username, password string) {
 	b.credentials = &Credentials{username, password}
 }
 
+func (b *Bonafide) GetURL(object string) (string, error) {
+	if b.apiURL == "" {
+		switch object {
+		case "cert":
+			return certAPI, nil
+		case "certv3":
+			return certAPI3, nil
+		case "auth":
+			return authAPI, nil
+		}
+	} else {
+		switch object {
+		case "cert":
+			return b.apiURL + certPathv1, nil
+		case "certv3":
+			return b.apiURL + certPathv3, nil
+		case "auth":
+			return b.apiURL + authPathv3, nil
+		}
+	}
+	return "", fmt.Errorf("ERROR: unknown object for api url")
+}
+
 func (b *Bonafide) GetPemCertificate() ([]byte, error) {
+	if b.auth == nil {
+		log.Fatal("ERROR: bonafide did not initialize auth")
+	}
 	cert, err := b.auth.GetPemCertificate()
 	return cert, err
 }
diff --git a/pkg/vpn/bonafide/bonafide_integration_test.go b/pkg/vpn/bonafide/bonafide_integration_test.go
index bea00fecd7724a160e945bb8f9bfef578f0c3b4a..166b2a99a51ee6f5449234a6ad0e6d5d60bf6e7c 100644
--- a/pkg/vpn/bonafide/bonafide_integration_test.go
+++ b/pkg/vpn/bonafide/bonafide_integration_test.go
@@ -32,7 +32,7 @@ var (
 
 func TestIntegrationGetCert(t *testing.T) {
 	b := New()
-	cert, err := b.GetCertPem()
+	cert, err := b.GetPemCertificate()
 	if err != nil {
 		t.Fatal("getCert returned an error: ", err)
 	}
diff --git a/pkg/vpn/bonafide/bonafide_sip_integration_test.go b/pkg/vpn/bonafide/bonafide_sip_integration_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..e5a516cbbc06671f19cdf6e0e7021fe4c0c7d0d0
--- /dev/null
+++ b/pkg/vpn/bonafide/bonafide_sip_integration_test.go
@@ -0,0 +1,70 @@
+// +build integration
+// Copyright (C) 2018 LEAP
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+package bonafide
+
+import (
+	"bytes"
+	"os"
+	"testing"
+)
+
+type SIPCreds struct {
+	userOk, passOk string
+}
+
+func getFromEnv(name, defaultVar string) string {
+	val, ok := os.LookupEnv(name)
+	if !ok {
+		return defaultVar
+	}
+	return val
+}
+
+func getSIPCreds() SIPCreds {
+	userOk := getFromEnv("SIP_USER_OK", "test_user_ok")
+	passOk := getFromEnv("SIP_PASS_OK", "test_pass_ok")
+	creds := SIPCreds{
+		userOk: userOk,
+		passOk: passOk,
+	}
+	return creds
+}
+
+func TestSIPIntegrationGetCert(t *testing.T) {
+	creds := getSIPCreds()
+
+	b := New()
+	b.auth = &SipAuthentication{b}
+	b.SetCredentials(creds.userOk, creds.passOk)
+	b.apiURL = "http://localhost:8000/"
+
+	cert, err := b.GetPemCertificate()
+	if err != nil {
+		t.Fatal("getCert returned an error: ", err)
+	}
+
+	if !bytes.Contains(cert, privateKeyHeader) {
+		t.Errorf("No private key present: \n%q", cert)
+	}
+
+	if !bytes.Contains(cert, certHeader) {
+		t.Errorf("No cert present: \n%q", cert)
+	}
+
+	/* TODO -- check we receive 401 for bad credentials */
+	/* TODO -- check we receive 4xx for no credentials */
+}
diff --git a/pkg/vpn/bonafide/bonafide_test.go b/pkg/vpn/bonafide/bonafide_test.go
index 8fb7f72fbb2841f7d5c4638cbd5c6c819ef0330a..0e463e0be253cde65ab1154bebd309275e56904e 100644
--- a/pkg/vpn/bonafide/bonafide_test.go
+++ b/pkg/vpn/bonafide/bonafide_test.go
@@ -27,9 +27,10 @@ import (
 )
 
 const (
-	certPath = "testdata/cert"
-	eip1Path = "testdata/eip-service.json"
-	eipPath  = "testdata/eip-service3.json"
+	certPath   = "testdata/cert"
+	eip1Path   = "testdata/eip-service.json"
+	eipPath    = "testdata/eip-service3.json"
+	eipPathSip = "testdata/eip-service3-sip.json"
 )
 
 type client struct {
@@ -44,9 +45,18 @@ func (c client) Post(url, contentType string, body io.Reader) (resp *http.Respon
 	}, err
 }
 
-func TestGetCert(t *testing.T) {
+func (c client) Do(req *http.Request) (*http.Response, error) {
+	f, err := os.Open(c.path)
+	return &http.Response{
+		Body:       f,
+		StatusCode: 200,
+	}, err
+}
+
+func TestAnonGetCert(t *testing.T) {
 	b := Bonafide{client: client{certPath}}
-	cert, err := b.GetCertPem()
+	b.auth = &AnonymousAuthentication{&b}
+	cert, err := b.GetPemCertificate()
 	if err != nil {
 		t.Fatal("getCert returned an error: ", err)
 	}
@@ -182,6 +192,8 @@ func TestObfs4Gateways(t *testing.T) {
 	}
 }
 
+/* TODO -- failClient instead? */
+
 type fallClient struct {
 	path string
 }
@@ -198,6 +210,14 @@ func (c fallClient) Post(url, contentType string, body io.Reader) (resp *http.Re
 	}, err
 }
 
+func (c fallClient) Do(req *http.Request) (*http.Response, error) {
+	f, err := os.Open(c.path)
+	return &http.Response{
+		Body:       f,
+		StatusCode: 401,
+	}, err
+}
+
 func TestEipServiceV1Fallback(t *testing.T) {
 	b := Bonafide{
 		client: fallClient{eip1Path},
diff --git a/pkg/vpn/openvpn.go b/pkg/vpn/openvpn.go
index 984aa09c8778e11ec2744ec0fd58db04ba5e3230..31f873836f9a343482971417e61dae59ff75f1c3 100644
--- a/pkg/vpn/openvpn.go
+++ b/pkg/vpn/openvpn.go
@@ -150,7 +150,7 @@ func (b *Bitmask) getCert() (certPath string, err error) {
 	certPath = b.getCertPemPath()
 
 	if _, err := os.Stat(certPath); os.IsNotExist(err) {
-		cert, err := b.bonafide.GetCertPem()
+		cert, err := b.bonafide.GetPemCertificate()
 		if err != nil {
 			return "", err
 		}