diff --git a/shared/grpc_clients/build.rs b/shared/grpc_clients/build.rs
--- a/shared/grpc_clients/build.rs
+++ b/shared/grpc_clients/build.rs
@@ -5,6 +5,7 @@
       &[
         "../protos/identity_client.proto",
         "../protos/identity_authenticated.proto",
+        "../protos/tunnelbroker.proto",
       ],
       &["../protos"],
     )
diff --git a/shared/grpc_clients/src/identity/authenticated.rs b/shared/grpc_clients/src/identity/authenticated.rs
--- a/shared/grpc_clients/src/identity/authenticated.rs
+++ b/shared/grpc_clients/src/identity/authenticated.rs
@@ -46,9 +46,9 @@
   device_id: String,
   access_token: String,
 ) -> Result<AuthClient<InterceptedService<Channel, AuthLayer>>, Error> {
-  use super::get_identity_service_channel;
+  use crate::get_grpc_service_channel;
 
-  let channel = get_identity_service_channel(url).await?;
+  let channel = get_grpc_service_channel(url).await?;
 
   let interceptor = AuthLayer {
     user_id,
diff --git a/shared/grpc_clients/src/identity/mod.rs b/shared/grpc_clients/src/identity/mod.rs
--- a/shared/grpc_clients/src/identity/mod.rs
+++ b/shared/grpc_clients/src/identity/mod.rs
@@ -13,28 +13,5 @@
   }
 }
 
-use crate::error::Error;
-use tonic::transport::Channel;
-use tonic::transport::{Certificate, ClientTlsConfig};
-use tracing::{self, info};
-
 pub use authenticated::get_auth_client;
 pub use unauthenticated::get_unauthenticated_client;
-
-pub(crate) async fn get_identity_service_channel(
-  url: &str,
-) -> Result<Channel, Error> {
-  let ca_cert = crate::get_ca_cert_contents().expect("Unable to get CA bundle");
-
-  info!("Connecting to identity service at {}", url);
-  let mut channel = Channel::from_shared(url.to_string())?;
-
-  // tls_config will fail if the underlying URI is only http://
-  if url.starts_with("https:") {
-    channel = channel.tls_config(
-      ClientTlsConfig::new().ca_certificate(Certificate::from_pem(&ca_cert)),
-    )?
-  }
-
-  Ok(channel.connect().await?)
-}
diff --git a/shared/grpc_clients/src/identity/unauthenticated.rs b/shared/grpc_clients/src/identity/unauthenticated.rs
--- a/shared/grpc_clients/src/identity/unauthenticated.rs
+++ b/shared/grpc_clients/src/identity/unauthenticated.rs
@@ -6,6 +6,6 @@
 pub async fn get_unauthenticated_client(
   url: &str,
 ) -> Result<IdentityClientServiceClient<Channel>, Error> {
-  let channel = super::get_identity_service_channel(url).await?;
+  let channel = crate::get_grpc_service_channel(url).await?;
   Ok(IdentityClientServiceClient::new(channel))
 }
diff --git a/shared/grpc_clients/src/lib.rs b/shared/grpc_clients/src/lib.rs
--- a/shared/grpc_clients/src/lib.rs
+++ b/shared/grpc_clients/src/lib.rs
@@ -1,7 +1,11 @@
 pub mod error;
 pub mod identity;
+pub mod tunnelbroker;
 
+use error::Error;
 use std::path::Path;
+use tonic::transport::{Certificate, Channel, ClientTlsConfig};
+use tracing::info;
 
 const CERT_PATHS: &'static [&'static str] = &[
   // MacOS and newer Ubuntu
@@ -19,3 +23,20 @@
     .filter_map(|f| std::fs::read_to_string(f).ok())
     .next()
 }
+pub(crate) async fn get_grpc_service_channel(
+  url: &str,
+) -> Result<Channel, Error> {
+  let ca_cert = crate::get_ca_cert_contents().expect("Unable to get CA bundle");
+
+  info!("Connecting to gRPC service at {}", url);
+  let mut channel = Channel::from_shared(url.to_string())?;
+
+  // tls_config will fail if the underlying URI is only http://
+  if url.starts_with("https:") {
+    channel = channel.tls_config(
+      ClientTlsConfig::new().ca_certificate(Certificate::from_pem(&ca_cert)),
+    )?
+  }
+
+  Ok(channel.connect().await?)
+}
diff --git a/shared/grpc_clients/src/tunnelbroker/mod.rs b/shared/grpc_clients/src/tunnelbroker/mod.rs
new file mode 100644
--- /dev/null
+++ b/shared/grpc_clients/src/tunnelbroker/mod.rs
@@ -0,0 +1,14 @@
+pub mod protos {
+  tonic::include_proto!("tunnelbroker");
+}
+use protos::tunnelbroker_service_client::TunnelbrokerServiceClient;
+use tonic::transport::Channel;
+
+use crate::error::Error;
+
+pub async fn create_tunnelbroker_client(
+  url: &str,
+) -> Result<TunnelbrokerServiceClient<Channel>, Error> {
+  let channel = crate::get_grpc_service_channel(url).await?;
+  Ok(TunnelbrokerServiceClient::new(channel))
+}