diff --git a/ca/bootstrap.go b/ca/bootstrap.go
index 880d4652c39f377fb5a3effe8eb70f662821d5c8..b8e519414f0227e5e5ffa2654ee6e016a62a2471 100644
--- a/ca/bootstrap.go
+++ b/ca/bootstrap.go
@@ -43,12 +43,22 @@ func Bootstrap(token string) (*Client, error) {
 // certificate will automatically rotate if necessary.
 //
 // Usage:
-//   srv, err := ca.BootstrapServer(":443", token, handler)
+//   // make sure to cancel the rotation goroutine
+//   ctx, cancel := context.WithCancel(context.Background())
+//   defer cancel()
+//   srv, err := ca.BootstrapServer(ctx, token, &http.Server{
+//       Addr: ":443",
+//       Handler: handler,
+//   })
 //   if err != nil {
 //       return err
 //   }
 //   srv.ListenAndServeTLS("", "")
-func BootstrapServer(addr, token string, handler http.Handler) (*http.Server, error) {
+func BootstrapServer(ctx context.Context, token string, base *http.Server) (*http.Server, error) {
+	if base.TLSConfig != nil {
+		return nil, errors.New("server TLSConfig is already set")
+	}
+
 	client, err := Bootstrap(token)
 	if err != nil {
 		return nil, err
@@ -64,16 +74,13 @@ func BootstrapServer(addr, token string, handler http.Handler) (*http.Server, er
 		return nil, err
 	}
 
-	tlsConfig, err := client.GetServerTLSConfig(context.Background(), sign, pk)
+	tlsConfig, err := client.GetServerTLSConfig(ctx, sign, pk)
 	if err != nil {
 		return nil, err
 	}
 
-	return &http.Server{
-		Addr:      addr,
-		Handler:   handler,
-		TLSConfig: tlsConfig,
-	}, nil
+	base.TLSConfig = tlsConfig
+	return base, nil
 }
 
 // BootstrapClient is a helper function that using the given bootstrap token
@@ -82,12 +89,15 @@ func BootstrapServer(addr, token string, handler http.Handler) (*http.Server, er
 // authority. The certificate will automatically rotate if necessary.
 //
 // Usage:
-//   client, err := ca.BootstrapClient(token)
+//   // make sure to cancel the rotation goroutine
+//   ctx, cancel := context.WithCancel(context.Background())
+//   defer cancel()
+//   client, err := ca.BootstrapClient(ctx, token)
 //   if err != nil {
 //     return err
 //   }
 //   resp, err := client.Get("https://internal.smallstep.com")
-func BootstrapClient(token string) (*http.Client, error) {
+func BootstrapClient(ctx context.Context, token string) (*http.Client, error) {
 	client, err := Bootstrap(token)
 	if err != nil {
 		return nil, err
@@ -103,7 +113,7 @@ func BootstrapClient(token string) (*http.Client, error) {
 		return nil, err
 	}
 
-	transport, err := client.Transport(context.Background(), sign, pk)
+	transport, err := client.Transport(ctx, sign, pk)
 	if err != nil {
 		return nil, err
 	}
diff --git a/ca/bootstrap_test.go b/ca/bootstrap_test.go
index 821b82a0749c352e7c1449431fe4314c17f0224c..3d1863eb22fd2cb5a1d723b1079e4915acb4e165 100644
--- a/ca/bootstrap_test.go
+++ b/ca/bootstrap_test.go
@@ -1,6 +1,8 @@
 package ca
 
 import (
+	"context"
+	"crypto/tls"
 	"net/http"
 	"net/http/httptest"
 	"reflect"
@@ -128,25 +130,23 @@ func TestBootstrapServer(t *testing.T) {
 	token := func() string {
 		return generateBootstrapToken(srv.URL, "subject", "ef742f95dc0d8aa82d3cca4017af6dac3fce84290344159891952d18c53eefe7")
 	}
-	handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-		w.Write([]byte("ok"))
-	})
 	type args struct {
-		addr    string
-		token   string
-		handler http.Handler
+		ctx   context.Context
+		token string
+		base  *http.Server
 	}
 	tests := []struct {
 		name    string
 		args    args
 		wantErr bool
 	}{
-		{"ok", args{":0", token(), handler}, false},
-		{"fail", args{":0", "bad-token", handler}, true},
+		{"ok", args{context.Background(), token(), &http.Server{}}, false},
+		{"fail", args{context.Background(), "bad-token", &http.Server{}}, true},
+		{"fail with TLSConfig", args{context.Background(), token(), &http.Server{TLSConfig: &tls.Config{}}}, true},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			got, err := BootstrapServer(tt.args.addr, tt.args.token, tt.args.handler)
+			got, err := BootstrapServer(tt.args.ctx, tt.args.token, tt.args.base)
 			if (err != nil) != tt.wantErr {
 				t.Errorf("BootstrapServer() error = %v, wantErr %v", err, tt.wantErr)
 				return
@@ -156,8 +156,11 @@ func TestBootstrapServer(t *testing.T) {
 					t.Errorf("BootstrapServer() = %v, want nil", got)
 				}
 			} else {
-				if !reflect.DeepEqual(got.Addr, tt.args.addr) {
-					t.Errorf("BootstrapServer() Addr = %v, want %v", got.Addr, tt.args.addr)
+				expected := &http.Server{
+					TLSConfig: got.TLSConfig,
+				}
+				if !reflect.DeepEqual(got, expected) {
+					t.Errorf("BootstrapServer() = %v, want %v", got, expected)
 				}
 				if got.TLSConfig == nil || got.TLSConfig.ClientCAs == nil || got.TLSConfig.RootCAs == nil || got.TLSConfig.GetCertificate == nil || got.TLSConfig.GetClientCertificate == nil {
 					t.Errorf("BootstrapServer() invalid TLSConfig = %#v", got.TLSConfig)
@@ -174,6 +177,7 @@ func TestBootstrapClient(t *testing.T) {
 		return generateBootstrapToken(srv.URL, "subject", "ef742f95dc0d8aa82d3cca4017af6dac3fce84290344159891952d18c53eefe7")
 	}
 	type args struct {
+		ctx   context.Context
 		token string
 	}
 	tests := []struct {
@@ -181,12 +185,12 @@ func TestBootstrapClient(t *testing.T) {
 		args    args
 		wantErr bool
 	}{
-		{"ok", args{token()}, false},
-		{"fail", args{"bad-token"}, true},
+		{"ok", args{context.Background(), token()}, false},
+		{"fail", args{context.Background(), "bad-token"}, true},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			got, err := BootstrapClient(tt.args.token)
+			got, err := BootstrapClient(tt.args.ctx, tt.args.token)
 			if (err != nil) != tt.wantErr {
 				t.Errorf("BootstrapClient() error = %v, wantErr %v", err, tt.wantErr)
 				return
diff --git a/examples/README.md b/examples/README.md
index 54c28acde5fa54898c0c286b28875e3678550f73..2c0f0e3a4079b29f166ed79f9f47c0f8e572fe04 100644
--- a/examples/README.md
+++ b/examples/README.md
@@ -119,13 +119,13 @@ tr, err := client.Transport(ctx, sign, pk)
 
 To run the example you need to start the certificate authority:
 
-```
+```sh
 certificates $ bin/step-ca examples/pki/config/ca.json
 2018/11/02 18:29:25 Serving HTTPS on :9000 ...
 ```
 
 And just run the client.go with a new token:
-```
+```sh
 certificates $ export STEPPATH=examples/pki
 certificates $ export STEP_CA_URL=https://localhost:9000
 certificates $ go run examples/basic-client/client.go $(step ca new-token client.smallstep.com)
@@ -140,15 +140,46 @@ server.
 The examples directory already contains a sample pki configuration with the
 password `password` hardcoded, but you can create your own using `step ca init`.
 
-First we will start the certificate authority:
+These examples show the use of other helper methods, they are simple ways to
+create TLS configured http.Server and http.Client objects. The methods are
+`BootstrapServer` and `BootstrapClient` and they are used like:
+
+```go
+// Get a cancelable context to stop the renewal goroutines and timers.
+ctx, cancel := context.WithCancel(context.Background())
+defer cancel()
+// Create an http.Server
+srv, err := ca.BootstrapServer(ctx, token, &http.Server{
+    Addr: ":8443",
+    Handler: handler,
+})
+if err != nil {
+    panic(err)
+}
+srv.ListenAndServeTLS("", "")
 ```
+
+```go
+// Get a cancelable context to stop the renewal goroutines and timers.
+ctx, cancel := context.WithCancel(context.Background())
+defer cancel()
+// Create an http.Client
+client, err := ca.BootstrapClient(ctx, token)
+if err != nil {
+    panic(err)
+}
+resp, err := client.Get("https://localhost:8443")
+```
+
+To run the example first we will start the certificate authority:
+```sh
 certificates $ bin/step-ca examples/pki/config/ca.json
 2018/11/02 18:29:25 Serving HTTPS on :9000 ...
 ```
 
 We will start the server and we will type `password` when step asks for the
 provisioner password:
-```
+```sh
 certificates $ export STEPPATH=examples/pki
 certificates $ export STEP_CA_URL=https://localhost:9000
 certificates $ go run examples/bootstrap-server/server.go $(step ca new-token localhost)
@@ -177,7 +208,7 @@ HTTPS-proxy has similar options --proxy-cacert and --proxy-insecure.
 ```
 
 But if we use the root certificate it will properly work:
-```
+```sh
 certificates $ curl --cacert examples/pki/secrets/root_ca.crt https://localhost:8443
 Hello nobody at 2018-11-03 01:49:25.66912 +0000 UTC!!!
 ```
@@ -186,7 +217,7 @@ Notice that in the response we see `nobody`, this is because the server didn't
 detected a TLS client configuration.
 
 But if we the client with the certificate name Mike we'll see:
-```
+```sh
 certificates $ export STEPPATH=examples/pki
 certificates $ export STEP_CA_URL=https://localhost:9000
 certificates $ go run examples/bootstrap-client/client.go $(step ca new-token Mike)
@@ -206,7 +237,7 @@ this provisioner is configured with a default certificate duration of 2 minutes.
 If we run the server, and inspect the used certificate, we can verify how it
 rotates after approximately two thirds of the duration has passed.
 
-```
+```sh
 certificates $ export STEPPATH=examples/pki
 certificates $ export STEP_CA_URL=https://localhost:9000
 certificates $ go run examples/bootstrap-server/server.go $(step ca new-token localhost))
@@ -222,6 +253,6 @@ number between 0 and 6.
 We can use the following command to check the certificate expiration and to make
 sure the certificate  changes after 74-80 seconds.
 
-```
+```sh
 certificates $ step certificate inspect --insecure https://localhost:8443
 ```
diff --git a/examples/bootstrap-client/client.go b/examples/bootstrap-client/client.go
index 869484bdb2370f17148dbb3a6ed486df462e28aa..109336be21cd8441fc2a66526b30c7c0a9190398 100644
--- a/examples/bootstrap-client/client.go
+++ b/examples/bootstrap-client/client.go
@@ -1,6 +1,7 @@
 package main
 
 import (
+	"context"
 	"fmt"
 	"io/ioutil"
 	"os"
@@ -17,7 +18,11 @@ func main() {
 
 	token := os.Args[1]
 
-	client, err := ca.BootstrapClient(token)
+	// make sure to cancel the renew goroutine
+	ctx, cancel := context.WithCancel(context.Background())
+	defer cancel()
+
+	client, err := ca.BootstrapClient(ctx, token)
 	if err != nil {
 		panic(err)
 	}
diff --git a/examples/bootstrap-server/server.go b/examples/bootstrap-server/server.go
index c48ca776c8af61cae16181f7dc190468e1a42bdb..1f9c09017a3b298422161096269d74dd44e7de12 100644
--- a/examples/bootstrap-server/server.go
+++ b/examples/bootstrap-server/server.go
@@ -1,6 +1,7 @@
 package main
 
 import (
+	"context"
 	"fmt"
 	"net/http"
 	"os"
@@ -17,13 +18,20 @@ func main() {
 
 	token := os.Args[1]
 
-	srv, err := ca.BootstrapServer(":8443", token, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-		name := "nobody"
-		if r.TLS != nil && len(r.TLS.PeerCertificates) > 0 {
-			name = r.TLS.PeerCertificates[0].Subject.CommonName
-		}
-		w.Write([]byte(fmt.Sprintf("Hello %s at %s!!!", name, time.Now().UTC())))
-	}))
+	// make sure to cancel the renew goroutine
+	ctx, cancel := context.WithCancel(context.Background())
+	defer cancel()
+
+	srv, err := ca.BootstrapServer(ctx, token, &http.Server{
+		Addr: ":8443",
+		Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+			name := "nobody"
+			if r.TLS != nil && len(r.TLS.PeerCertificates) > 0 {
+				name = r.TLS.PeerCertificates[0].Subject.CommonName
+			}
+			w.Write([]byte(fmt.Sprintf("Hello %s at %s!!!", name, time.Now().UTC())))
+		}),
+	})
 	if err != nil {
 		panic(err)
 	}