diff --git a/api.proto b/api.proto
index 886ddac..1fe4ef2 100644
--- a/api.proto
+++ b/api.proto
@@ -85,7 +85,8 @@ service Listener {
   // StatusUpdates opens a stream to listen to connection status updates
   // a client has to subscribe and continuously
   // listen to the broadcasted updates
-  rpc StatusUpdates(StatusUpdatesRequest) returns (stream ConnectionStatusUpdate);
+  rpc StatusUpdates(StatusUpdatesRequest)
+      returns (stream ConnectionStatusUpdate);
 }
 
 message ListenerUpdateRequest {
@@ -211,10 +212,18 @@ message ClientCertFromStore {
   optional string subject_filter = 2;
 }
 
+enum Protocol {
+  UNKNOWN = 0;
+  TCP = 1;
+  UDP = 2;
+}
+
 // Connection
 message Connection {
   // name is a user friendly connection name that a user may define
   optional string name = 1;
+  // the protocol to use for the connection
+  optional Protocol protocol = 10;
   // remote_addr is a remote pomerium host:port
   string remote_addr = 2;
   // listen_address, if not provided, will assign a random port each time
diff --git a/package.json b/package.json
index 1d4b316..d200e8d 100644
--- a/package.json
+++ b/package.json
@@ -311,7 +311,8 @@
         }
       }
     ],
-    "singleQuote": true
+    "singleQuote": true,
+    "trailingComma": "all"
   },
   "renovate": {
     "extends": [
diff --git a/src/renderer/pages/ConnectForm.tsx b/src/renderer/pages/ConnectForm.tsx
index 5873b18..a6a2ff8 100644
--- a/src/renderer/pages/ConnectForm.tsx
+++ b/src/renderer/pages/ConnectForm.tsx
@@ -8,10 +8,15 @@ import {
   CardContent,
   Chip,
   Container,
+  FormControl,
   FormControlLabel,
   FormHelperText,
   Grid,
   IconButton,
+  InputLabel,
+  MenuItem,
+  Select,
+  SelectChangeEvent,
   styled,
   Switch,
   Typography,
@@ -38,6 +43,7 @@ import { formatTag } from '../../shared/validators';
 import {
   ClientCertFromStore,
   Connection,
+  Protocol,
   Record,
   Selector,
 } from '../../shared/pb/api';
@@ -115,6 +121,7 @@ interface Props {
 
 const initialConnData: Connection = {
   name: undefined,
+  protocol: Protocol.TCP,
   remoteAddr: '',
   listenAddr: undefined,
   pomeriumUrl: undefined,
@@ -310,6 +317,14 @@ const ConnectForm: FC<Props> = () => {
     setShowCertInput(true);
   };
 
+  const handleChangeProtocol = (evt: SelectChangeEvent) => {
+    setConnection((oldConnection) => {
+      oldConnection.protocol =
+        evt.target.value === 'UDP' ? Protocol.UDP : Protocol.TCP;
+      return oldConnection;
+    });
+  };
+
   const saveConnection = (): void => {
     const record = {
       tags,
@@ -552,6 +567,23 @@ const ConnectForm: FC<Props> = () => {
                   helperText="Name of the route."
                 />
               </Grid>
+              <Grid item xs={12}>
+                <FormControl fullWidth>
+                  <InputLabel id="protocol-label">Protocol</InputLabel>
+                  <Select
+                    labelId="protocol-label"
+                    id="demo-simple-select"
+                    value={
+                      connection?.protocol === Protocol.UDP ? 'UDP' : 'TCP'
+                    }
+                    label="Age"
+                    onChange={handleChangeProtocol}
+                  >
+                    <MenuItem value="TCP">TCP</MenuItem>
+                    <MenuItem value="UDP">UDP</MenuItem>
+                  </Select>
+                </FormControl>
+              </Grid>
               <Grid item xs={12}>
                 <TextField
                   fullWidth
diff --git a/src/shared/pb/api.ts b/src/shared/pb/api.ts
index 36e67ab..44d49e9 100644
--- a/src/shared/pb/api.ts
+++ b/src/shared/pb/api.ts
@@ -19,6 +19,45 @@ import * as _m0 from 'protobufjs/minimal';
 
 export const protobufPackage = 'pomerium.cli';
 
+export enum Protocol {
+  UNKNOWN = 0,
+  TCP = 1,
+  UDP = 2,
+  UNRECOGNIZED = -1,
+}
+
+export function protocolFromJSON(object: any): Protocol {
+  switch (object) {
+    case 0:
+    case 'UNKNOWN':
+      return Protocol.UNKNOWN;
+    case 1:
+    case 'TCP':
+      return Protocol.TCP;
+    case 2:
+    case 'UDP':
+      return Protocol.UDP;
+    case -1:
+    case 'UNRECOGNIZED':
+    default:
+      return Protocol.UNRECOGNIZED;
+  }
+}
+
+export function protocolToJSON(object: Protocol): string {
+  switch (object) {
+    case Protocol.UNKNOWN:
+      return 'UNKNOWN';
+    case Protocol.TCP:
+      return 'TCP';
+    case Protocol.UDP:
+      return 'UDP';
+    case Protocol.UNRECOGNIZED:
+    default:
+      return 'UNRECOGNIZED';
+  }
+}
+
 /** Record represents a single tunnel record in the configuration */
 export interface Record {
   /** if omitted, a new record would be created */
@@ -322,6 +361,8 @@ export interface ClientCertFromStore {
 export interface Connection {
   /** name is a user friendly connection name that a user may define */
   name?: string | undefined;
+  /** the protocol to use for the connection */
+  protocol?: Protocol | undefined;
   /** remote_addr is a remote pomerium host:port */
   remoteAddr: string;
   /** listen_address, if not provided, will assign a random port each time */
@@ -2332,6 +2373,7 @@ export const ClientCertFromStore = {
 function createBaseConnection(): Connection {
   return {
     name: undefined,
+    protocol: undefined,
     remoteAddr: '',
     listenAddr: undefined,
     pomeriumUrl: undefined,
@@ -2350,6 +2392,9 @@ export const Connection = {
     if (message.name !== undefined) {
       writer.uint32(10).string(message.name);
     }
+    if (message.protocol !== undefined) {
+      writer.uint32(80).int32(message.protocol);
+    }
     if (message.remoteAddr !== '') {
       writer.uint32(18).string(message.remoteAddr);
     }
@@ -2387,6 +2432,9 @@ export const Connection = {
         case 1:
           message.name = reader.string();
           break;
+        case 10:
+          message.protocol = reader.int32() as any;
+          break;
         case 2:
           message.remoteAddr = reader.string();
           break;
@@ -2422,6 +2470,9 @@ export const Connection = {
   fromJSON(object: any): Connection {
     return {
       name: isSet(object.name) ? String(object.name) : undefined,
+      protocol: isSet(object.protocol)
+        ? protocolFromJSON(object.protocol)
+        : undefined,
       remoteAddr: isSet(object.remoteAddr) ? String(object.remoteAddr) : '',
       listenAddr: isSet(object.listenAddr)
         ? String(object.listenAddr)
@@ -2445,6 +2496,11 @@ export const Connection = {
   toJSON(message: Connection): unknown {
     const obj: any = {};
     message.name !== undefined && (obj.name = message.name);
+    message.protocol !== undefined &&
+      (obj.protocol =
+        message.protocol !== undefined
+          ? protocolToJSON(message.protocol)
+          : undefined);
     message.remoteAddr !== undefined && (obj.remoteAddr = message.remoteAddr);
     message.listenAddr !== undefined && (obj.listenAddr = message.listenAddr);
     message.pomeriumUrl !== undefined &&
@@ -2472,6 +2528,7 @@ export const Connection = {
   ): Connection {
     const message = createBaseConnection();
     message.name = object.name ?? undefined;
+    message.protocol = object.protocol ?? undefined;
     message.remoteAddr = object.remoteAddr ?? '';
     message.listenAddr = object.listenAddr ?? undefined;
     message.pomeriumUrl = object.pomeriumUrl ?? undefined;