diff --git a/frontend/src/.dockerignore b/frontend/src/.dockerignore
new file mode 100644
index 0000000..3c3629e
--- /dev/null
+++ b/frontend/src/.dockerignore
@@ -0,0 +1 @@
+node_modules
diff --git a/frontend/src/App.vue b/frontend/src/App.vue
new file mode 100644
index 0000000..dc4ddc1
--- /dev/null
+++ b/frontend/src/App.vue
@@ -0,0 +1,88 @@
+<script>
+import {mapGetters} from 'vuex';
+
+import config from './config.json5';
+import GsiButton from './GsiButton.vue';
+
+export default {
+  data() {
+    return {
+      isDrawerOpen: false,
+      mainMenuOpen: false,
+    };
+  },
+  components: {
+    GsiButton,
+  },
+  computed: {
+    ...mapGetters([
+      'isSignedIn',
+    ]),
+  },
+  methods: {
+    onSignIn(response) {
+      this.$store.commit('setJwtToken', response.credential);
+    },
+    onSignOut() {
+      this.$store.commit('setJwtToken', null);
+    },
+    onSelectMainMenu(e) {
+      switch (e.item.getAttribute('data-entry')) {
+        case 'sign-out':
+          this.onSignOut();
+          break;
+
+        default:
+          console.error('Unknown menu entry.');
+      }
+    },
+  },
+  created() {
+    this.$store.dispatch('connectClient', config.grpcWebHost);
+  },
+};
+</script>
+
+<template>
+  <mcw-drawer
+      ref="drawer"
+      v-model="isDrawerOpen"
+      dismissible
+      class="primary-drawer">
+    <template #header>
+      <div class="mdc-drawer__header"></div>
+    </template>
+
+    <mcw-list-item icon="home" to="/" tabindex="0">Home</mcw-list-item>
+    <mcw-list-item icon="emergency" to="/kill-switches">Kill switches</mcw-list-item>
+    <template v-if="isSignedIn">
+      <mcw-list-item icon="person" to="/authorized-users">Authorized users</mcw-list-item>
+    </template>
+  </mcw-drawer>
+  <div ref="app-content" class="mdc-drawer-app-content">
+    <mcw-top-app-bar class="main-toolbar">
+      <div class="mdc-top-app-bar__row">
+        <section class="mdc-top-app-bar__section mdc-top-app-bar__section--align-start">
+          <button @click="isDrawerOpen = !isDrawerOpen" class="material-icons mdc-top-app-bar__navigation-icon mdc-icon-button" aria-label="Open navigation menu">menu</button>
+          <span class="mdc-top-app-bar__title">{{ $route.meta.title }}</span>
+        </section>
+        <section class="mdc-top-app-bar__section mdc-top-app-bar__section--align-end" role="toolbar">
+          <template v-if="isSignedIn">
+            <mcw-menu-anchor>
+              <button @click="mainMenuOpen = true" class="material-icons mdc-top-app-bar__action-item mdc-icon-button" aria-label="Options">more_vert</button>
+              <mcw-menu v-model="mainMenuOpen" @select="onSelectMainMenu">
+                <mcw-list-item data-entry="sign-out">Sign out</mcw-list-item>
+              </mcw-menu>
+            </mcw-menu-anchor>
+          </template>
+          <template v-else>
+            <gsi-button @on-signin="onSignIn"></gsi-button>
+          </template>
+        </section>
+      </div>
+    </mcw-top-app-bar>
+    <main class="mdc-top-app-bar--fixed-adjust">
+      <router-view />
+    </main>
+  </div>
+</template>
diff --git a/frontend/src/GsiButton.vue b/frontend/src/GsiButton.vue
new file mode 100644
index 0000000..01cd924
--- /dev/null
+++ b/frontend/src/GsiButton.vue
@@ -0,0 +1,31 @@
+<script>
+import config from './config.json5';
+
+export default {
+  mounted() {
+    if (document.readyState == 'complete')
+      this.init();
+    else
+      window.addEventListener('load', () => this.init());
+  },
+  methods: {
+    init() {
+      window.google.accounts.id.initialize({
+        client_id: config.google.clientId,
+        callback: this.onSignIn,
+      });
+      window.google.accounts.id.renderButton(document.getElementById('gsi-button'), {
+        theme: 'outline',
+        size: 'large',
+      });
+    },
+    onSignIn(response) {
+      this.$emit('on-signin', response);
+    },
+  },
+};
+</script>
+
+<template>
+  <div id="gsi-button"></div>
+</template>
diff --git a/frontend/src/api_proto/common_pb.js b/frontend/src/api_proto/common_pb.js
new file mode 100644
index 0000000..6bc5cd4
--- /dev/null
+++ b/frontend/src/api_proto/common_pb.js
@@ -0,0 +1,250 @@
+// source: api_proto/common.proto
+/**
+ * @fileoverview
+ * @enhanceable
+ * @suppress {missingRequire} reports error on implicit type usages.
+ * @suppress {messageConventions} JS Compiler reports an error if a variable or
+ *     field starts with 'MSG_' and isn't a translatable message.
+ * @public
+ */
+// GENERATED CODE -- DO NOT EDIT!
+/* eslint-disable */
+// @ts-nocheck
+
+var jspb = require('google-protobuf');
+var goog = jspb;
+var global = Function('return this')();
+
+goog.exportSymbol('proto.Environment', null, global);
+goog.exportSymbol('proto.Environment.Browser', null, global);
+goog.exportSymbol('proto.Environment.VersionChannel', null, global);
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.Environment = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.Environment, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.Environment.displayName = 'proto.Environment';
+}
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.Environment.prototype.toObject = function(opt_includeInstance) {
+  return proto.Environment.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.Environment} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.Environment.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    browser: jspb.Message.getFieldWithDefault(msg, 1, 0),
+    version: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    versionChannel: jspb.Message.getFieldWithDefault(msg, 3, 0)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.Environment}
+ */
+proto.Environment.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.Environment;
+  return proto.Environment.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.Environment} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.Environment}
+ */
+proto.Environment.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {!proto.Environment.Browser} */ (reader.readEnum());
+      msg.setBrowser(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setVersion(value);
+      break;
+    case 3:
+      var value = /** @type {!proto.Environment.VersionChannel} */ (reader.readEnum());
+      msg.setVersionChannel(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.Environment.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.Environment.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.Environment} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.Environment.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getBrowser();
+  if (f !== 0.0) {
+    writer.writeEnum(
+      1,
+      f
+    );
+  }
+  f = message.getVersion();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getVersionChannel();
+  if (f !== 0.0) {
+    writer.writeEnum(
+      3,
+      f
+    );
+  }
+};
+
+
+/**
+ * @enum {number}
+ */
+proto.Environment.Browser = {
+  BROWSER_UNKNOWN: 0,
+  BROWSER_CHROMIUM: 1,
+  BROWSER_GECKO: 2
+};
+
+/**
+ * @enum {number}
+ */
+proto.Environment.VersionChannel = {
+  CHANNEL_UNKNOWN: 0,
+  CHANNEL_STABLE: 1,
+  CHANNEL_BETA: 2
+};
+
+/**
+ * optional Browser browser = 1;
+ * @return {!proto.Environment.Browser}
+ */
+proto.Environment.prototype.getBrowser = function() {
+  return /** @type {!proto.Environment.Browser} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {!proto.Environment.Browser} value
+ * @return {!proto.Environment} returns this
+ */
+proto.Environment.prototype.setBrowser = function(value) {
+  return jspb.Message.setProto3EnumField(this, 1, value);
+};
+
+
+/**
+ * optional string version = 2;
+ * @return {string}
+ */
+proto.Environment.prototype.getVersion = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.Environment} returns this
+ */
+proto.Environment.prototype.setVersion = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional VersionChannel version_channel = 3;
+ * @return {!proto.Environment.VersionChannel}
+ */
+proto.Environment.prototype.getVersionChannel = function() {
+  return /** @type {!proto.Environment.VersionChannel} */ (jspb.Message.getFieldWithDefault(this, 3, 0));
+};
+
+
+/**
+ * @param {!proto.Environment.VersionChannel} value
+ * @return {!proto.Environment} returns this
+ */
+proto.Environment.prototype.setVersionChannel = function(value) {
+  return jspb.Message.setProto3EnumField(this, 3, value);
+};
+
+
+goog.object.extend(exports, proto);
diff --git a/frontend/src/api_proto/kill_switch_grpc_web_pb.js b/frontend/src/api_proto/kill_switch_grpc_web_pb.js
new file mode 100644
index 0000000..0c5f28a
--- /dev/null
+++ b/frontend/src/api_proto/kill_switch_grpc_web_pb.js
@@ -0,0 +1,877 @@
+/**
+ * @fileoverview gRPC-Web generated client stub for 
+ * @enhanceable
+ * @public
+ */
+
+// GENERATED CODE -- DO NOT EDIT!
+
+
+/* eslint-disable */
+// @ts-nocheck
+
+
+
+const grpc = {};
+grpc.web = require('grpc-web');
+
+
+var api_proto_common_pb = require('../api_proto/common_pb.js')
+
+var api_proto_kill_switch_objects_pb = require('../api_proto/kill_switch_objects_pb.js')
+const proto = require('./kill_switch_pb.js');
+
+/**
+ * @param {string} hostname
+ * @param {?Object} credentials
+ * @param {?Object} options
+ * @constructor
+ * @struct
+ * @final
+ */
+proto.KillSwitchServiceClient =
+    function(hostname, credentials, options) {
+  if (!options) options = {};
+  options['format'] = 'text';
+
+  /**
+   * @private @const {!grpc.web.GrpcWebClientBase} The client
+   */
+  this.client_ = new grpc.web.GrpcWebClientBase(options);
+
+  /**
+   * @private @const {string} The hostname
+   */
+  this.hostname_ = hostname;
+
+};
+
+
+/**
+ * @param {string} hostname
+ * @param {?Object} credentials
+ * @param {?Object} options
+ * @constructor
+ * @struct
+ * @final
+ */
+proto.KillSwitchServicePromiseClient =
+    function(hostname, credentials, options) {
+  if (!options) options = {};
+  options['format'] = 'text';
+
+  /**
+   * @private @const {!grpc.web.GrpcWebClientBase} The client
+   */
+  this.client_ = new grpc.web.GrpcWebClientBase(options);
+
+  /**
+   * @private @const {string} The hostname
+   */
+  this.hostname_ = hostname;
+
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.GetKillSwitchStatusRequest,
+ *   !proto.GetKillSwitchStatusResponse>}
+ */
+const methodDescriptor_KillSwitchService_GetKillSwitchStatus = new grpc.web.MethodDescriptor(
+  '/KillSwitchService/GetKillSwitchStatus',
+  grpc.web.MethodType.UNARY,
+  proto.GetKillSwitchStatusRequest,
+  proto.GetKillSwitchStatusResponse,
+  /**
+   * @param {!proto.GetKillSwitchStatusRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  proto.GetKillSwitchStatusResponse.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.GetKillSwitchStatusRequest,
+ *   !proto.GetKillSwitchStatusResponse>}
+ */
+const methodInfo_KillSwitchService_GetKillSwitchStatus = new grpc.web.AbstractClientBase.MethodInfo(
+  proto.GetKillSwitchStatusResponse,
+  /**
+   * @param {!proto.GetKillSwitchStatusRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  proto.GetKillSwitchStatusResponse.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.GetKillSwitchStatusRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.GetKillSwitchStatusResponse)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.GetKillSwitchStatusResponse>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.KillSwitchServiceClient.prototype.getKillSwitchStatus =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/KillSwitchService/GetKillSwitchStatus',
+      request,
+      metadata || {},
+      methodDescriptor_KillSwitchService_GetKillSwitchStatus,
+      callback);
+};
+
+
+/**
+ * @param {!proto.GetKillSwitchStatusRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.GetKillSwitchStatusResponse>}
+ *     Promise that resolves to the response
+ */
+proto.KillSwitchServicePromiseClient.prototype.getKillSwitchStatus =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/KillSwitchService/GetKillSwitchStatus',
+      request,
+      metadata || {},
+      methodDescriptor_KillSwitchService_GetKillSwitchStatus);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.GetKillSwitchOverviewRequest,
+ *   !proto.GetKillSwitchOverviewResponse>}
+ */
+const methodDescriptor_KillSwitchService_GetKillSwitchOverview = new grpc.web.MethodDescriptor(
+  '/KillSwitchService/GetKillSwitchOverview',
+  grpc.web.MethodType.UNARY,
+  proto.GetKillSwitchOverviewRequest,
+  proto.GetKillSwitchOverviewResponse,
+  /**
+   * @param {!proto.GetKillSwitchOverviewRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  proto.GetKillSwitchOverviewResponse.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.GetKillSwitchOverviewRequest,
+ *   !proto.GetKillSwitchOverviewResponse>}
+ */
+const methodInfo_KillSwitchService_GetKillSwitchOverview = new grpc.web.AbstractClientBase.MethodInfo(
+  proto.GetKillSwitchOverviewResponse,
+  /**
+   * @param {!proto.GetKillSwitchOverviewRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  proto.GetKillSwitchOverviewResponse.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.GetKillSwitchOverviewRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.GetKillSwitchOverviewResponse)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.GetKillSwitchOverviewResponse>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.KillSwitchServiceClient.prototype.getKillSwitchOverview =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/KillSwitchService/GetKillSwitchOverview',
+      request,
+      metadata || {},
+      methodDescriptor_KillSwitchService_GetKillSwitchOverview,
+      callback);
+};
+
+
+/**
+ * @param {!proto.GetKillSwitchOverviewRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.GetKillSwitchOverviewResponse>}
+ *     Promise that resolves to the response
+ */
+proto.KillSwitchServicePromiseClient.prototype.getKillSwitchOverview =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/KillSwitchService/GetKillSwitchOverview',
+      request,
+      metadata || {},
+      methodDescriptor_KillSwitchService_GetKillSwitchOverview);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.ListFeaturesRequest,
+ *   !proto.ListFeaturesResponse>}
+ */
+const methodDescriptor_KillSwitchService_ListFeatures = new grpc.web.MethodDescriptor(
+  '/KillSwitchService/ListFeatures',
+  grpc.web.MethodType.UNARY,
+  proto.ListFeaturesRequest,
+  proto.ListFeaturesResponse,
+  /**
+   * @param {!proto.ListFeaturesRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  proto.ListFeaturesResponse.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.ListFeaturesRequest,
+ *   !proto.ListFeaturesResponse>}
+ */
+const methodInfo_KillSwitchService_ListFeatures = new grpc.web.AbstractClientBase.MethodInfo(
+  proto.ListFeaturesResponse,
+  /**
+   * @param {!proto.ListFeaturesRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  proto.ListFeaturesResponse.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.ListFeaturesRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.ListFeaturesResponse)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.ListFeaturesResponse>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.KillSwitchServiceClient.prototype.listFeatures =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/KillSwitchService/ListFeatures',
+      request,
+      metadata || {},
+      methodDescriptor_KillSwitchService_ListFeatures,
+      callback);
+};
+
+
+/**
+ * @param {!proto.ListFeaturesRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.ListFeaturesResponse>}
+ *     Promise that resolves to the response
+ */
+proto.KillSwitchServicePromiseClient.prototype.listFeatures =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/KillSwitchService/ListFeatures',
+      request,
+      metadata || {},
+      methodDescriptor_KillSwitchService_ListFeatures);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.SyncFeaturesRequest,
+ *   !proto.SyncFeaturesResponse>}
+ */
+const methodDescriptor_KillSwitchService_SyncFeatures = new grpc.web.MethodDescriptor(
+  '/KillSwitchService/SyncFeatures',
+  grpc.web.MethodType.UNARY,
+  proto.SyncFeaturesRequest,
+  proto.SyncFeaturesResponse,
+  /**
+   * @param {!proto.SyncFeaturesRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  proto.SyncFeaturesResponse.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.SyncFeaturesRequest,
+ *   !proto.SyncFeaturesResponse>}
+ */
+const methodInfo_KillSwitchService_SyncFeatures = new grpc.web.AbstractClientBase.MethodInfo(
+  proto.SyncFeaturesResponse,
+  /**
+   * @param {!proto.SyncFeaturesRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  proto.SyncFeaturesResponse.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.SyncFeaturesRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.SyncFeaturesResponse)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.SyncFeaturesResponse>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.KillSwitchServiceClient.prototype.syncFeatures =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/KillSwitchService/SyncFeatures',
+      request,
+      metadata || {},
+      methodDescriptor_KillSwitchService_SyncFeatures,
+      callback);
+};
+
+
+/**
+ * @param {!proto.SyncFeaturesRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.SyncFeaturesResponse>}
+ *     Promise that resolves to the response
+ */
+proto.KillSwitchServicePromiseClient.prototype.syncFeatures =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/KillSwitchService/SyncFeatures',
+      request,
+      metadata || {},
+      methodDescriptor_KillSwitchService_SyncFeatures);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.EnableKillSwitchRequest,
+ *   !proto.EnableKillSwitchResponse>}
+ */
+const methodDescriptor_KillSwitchService_EnableKillSwitch = new grpc.web.MethodDescriptor(
+  '/KillSwitchService/EnableKillSwitch',
+  grpc.web.MethodType.UNARY,
+  proto.EnableKillSwitchRequest,
+  proto.EnableKillSwitchResponse,
+  /**
+   * @param {!proto.EnableKillSwitchRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  proto.EnableKillSwitchResponse.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.EnableKillSwitchRequest,
+ *   !proto.EnableKillSwitchResponse>}
+ */
+const methodInfo_KillSwitchService_EnableKillSwitch = new grpc.web.AbstractClientBase.MethodInfo(
+  proto.EnableKillSwitchResponse,
+  /**
+   * @param {!proto.EnableKillSwitchRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  proto.EnableKillSwitchResponse.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.EnableKillSwitchRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.EnableKillSwitchResponse)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.EnableKillSwitchResponse>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.KillSwitchServiceClient.prototype.enableKillSwitch =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/KillSwitchService/EnableKillSwitch',
+      request,
+      metadata || {},
+      methodDescriptor_KillSwitchService_EnableKillSwitch,
+      callback);
+};
+
+
+/**
+ * @param {!proto.EnableKillSwitchRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.EnableKillSwitchResponse>}
+ *     Promise that resolves to the response
+ */
+proto.KillSwitchServicePromiseClient.prototype.enableKillSwitch =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/KillSwitchService/EnableKillSwitch',
+      request,
+      metadata || {},
+      methodDescriptor_KillSwitchService_EnableKillSwitch);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.DisableKillSwitchRequest,
+ *   !proto.DisableKillSwitchResponse>}
+ */
+const methodDescriptor_KillSwitchService_DisableKillSwitch = new grpc.web.MethodDescriptor(
+  '/KillSwitchService/DisableKillSwitch',
+  grpc.web.MethodType.UNARY,
+  proto.DisableKillSwitchRequest,
+  proto.DisableKillSwitchResponse,
+  /**
+   * @param {!proto.DisableKillSwitchRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  proto.DisableKillSwitchResponse.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.DisableKillSwitchRequest,
+ *   !proto.DisableKillSwitchResponse>}
+ */
+const methodInfo_KillSwitchService_DisableKillSwitch = new grpc.web.AbstractClientBase.MethodInfo(
+  proto.DisableKillSwitchResponse,
+  /**
+   * @param {!proto.DisableKillSwitchRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  proto.DisableKillSwitchResponse.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.DisableKillSwitchRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.DisableKillSwitchResponse)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.DisableKillSwitchResponse>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.KillSwitchServiceClient.prototype.disableKillSwitch =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/KillSwitchService/DisableKillSwitch',
+      request,
+      metadata || {},
+      methodDescriptor_KillSwitchService_DisableKillSwitch,
+      callback);
+};
+
+
+/**
+ * @param {!proto.DisableKillSwitchRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.DisableKillSwitchResponse>}
+ *     Promise that resolves to the response
+ */
+proto.KillSwitchServicePromiseClient.prototype.disableKillSwitch =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/KillSwitchService/DisableKillSwitch',
+      request,
+      metadata || {},
+      methodDescriptor_KillSwitchService_DisableKillSwitch);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.ListAuthorizedUsersRequest,
+ *   !proto.ListAuthorizedUsersResponse>}
+ */
+const methodDescriptor_KillSwitchService_ListAuthorizedUsers = new grpc.web.MethodDescriptor(
+  '/KillSwitchService/ListAuthorizedUsers',
+  grpc.web.MethodType.UNARY,
+  proto.ListAuthorizedUsersRequest,
+  proto.ListAuthorizedUsersResponse,
+  /**
+   * @param {!proto.ListAuthorizedUsersRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  proto.ListAuthorizedUsersResponse.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.ListAuthorizedUsersRequest,
+ *   !proto.ListAuthorizedUsersResponse>}
+ */
+const methodInfo_KillSwitchService_ListAuthorizedUsers = new grpc.web.AbstractClientBase.MethodInfo(
+  proto.ListAuthorizedUsersResponse,
+  /**
+   * @param {!proto.ListAuthorizedUsersRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  proto.ListAuthorizedUsersResponse.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.ListAuthorizedUsersRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.ListAuthorizedUsersResponse)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.ListAuthorizedUsersResponse>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.KillSwitchServiceClient.prototype.listAuthorizedUsers =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/KillSwitchService/ListAuthorizedUsers',
+      request,
+      metadata || {},
+      methodDescriptor_KillSwitchService_ListAuthorizedUsers,
+      callback);
+};
+
+
+/**
+ * @param {!proto.ListAuthorizedUsersRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.ListAuthorizedUsersResponse>}
+ *     Promise that resolves to the response
+ */
+proto.KillSwitchServicePromiseClient.prototype.listAuthorizedUsers =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/KillSwitchService/ListAuthorizedUsers',
+      request,
+      metadata || {},
+      methodDescriptor_KillSwitchService_ListAuthorizedUsers);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.AddAuthorizedUserRequest,
+ *   !proto.AddAuthorizedUserResponse>}
+ */
+const methodDescriptor_KillSwitchService_AddAuthorizedUser = new grpc.web.MethodDescriptor(
+  '/KillSwitchService/AddAuthorizedUser',
+  grpc.web.MethodType.UNARY,
+  proto.AddAuthorizedUserRequest,
+  proto.AddAuthorizedUserResponse,
+  /**
+   * @param {!proto.AddAuthorizedUserRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  proto.AddAuthorizedUserResponse.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.AddAuthorizedUserRequest,
+ *   !proto.AddAuthorizedUserResponse>}
+ */
+const methodInfo_KillSwitchService_AddAuthorizedUser = new grpc.web.AbstractClientBase.MethodInfo(
+  proto.AddAuthorizedUserResponse,
+  /**
+   * @param {!proto.AddAuthorizedUserRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  proto.AddAuthorizedUserResponse.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.AddAuthorizedUserRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.AddAuthorizedUserResponse)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.AddAuthorizedUserResponse>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.KillSwitchServiceClient.prototype.addAuthorizedUser =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/KillSwitchService/AddAuthorizedUser',
+      request,
+      metadata || {},
+      methodDescriptor_KillSwitchService_AddAuthorizedUser,
+      callback);
+};
+
+
+/**
+ * @param {!proto.AddAuthorizedUserRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.AddAuthorizedUserResponse>}
+ *     Promise that resolves to the response
+ */
+proto.KillSwitchServicePromiseClient.prototype.addAuthorizedUser =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/KillSwitchService/AddAuthorizedUser',
+      request,
+      metadata || {},
+      methodDescriptor_KillSwitchService_AddAuthorizedUser);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.UpdateAuthorizedUserRequest,
+ *   !proto.UpdateAuthorizedUserResponse>}
+ */
+const methodDescriptor_KillSwitchService_UpdateAuthorizedUser = new grpc.web.MethodDescriptor(
+  '/KillSwitchService/UpdateAuthorizedUser',
+  grpc.web.MethodType.UNARY,
+  proto.UpdateAuthorizedUserRequest,
+  proto.UpdateAuthorizedUserResponse,
+  /**
+   * @param {!proto.UpdateAuthorizedUserRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  proto.UpdateAuthorizedUserResponse.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.UpdateAuthorizedUserRequest,
+ *   !proto.UpdateAuthorizedUserResponse>}
+ */
+const methodInfo_KillSwitchService_UpdateAuthorizedUser = new grpc.web.AbstractClientBase.MethodInfo(
+  proto.UpdateAuthorizedUserResponse,
+  /**
+   * @param {!proto.UpdateAuthorizedUserRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  proto.UpdateAuthorizedUserResponse.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.UpdateAuthorizedUserRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.UpdateAuthorizedUserResponse)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.UpdateAuthorizedUserResponse>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.KillSwitchServiceClient.prototype.updateAuthorizedUser =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/KillSwitchService/UpdateAuthorizedUser',
+      request,
+      metadata || {},
+      methodDescriptor_KillSwitchService_UpdateAuthorizedUser,
+      callback);
+};
+
+
+/**
+ * @param {!proto.UpdateAuthorizedUserRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.UpdateAuthorizedUserResponse>}
+ *     Promise that resolves to the response
+ */
+proto.KillSwitchServicePromiseClient.prototype.updateAuthorizedUser =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/KillSwitchService/UpdateAuthorizedUser',
+      request,
+      metadata || {},
+      methodDescriptor_KillSwitchService_UpdateAuthorizedUser);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.DeleteAuthorizedUserRequest,
+ *   !proto.DeleteAuthorizedUserResponse>}
+ */
+const methodDescriptor_KillSwitchService_DeleteAuthorizedUser = new grpc.web.MethodDescriptor(
+  '/KillSwitchService/DeleteAuthorizedUser',
+  grpc.web.MethodType.UNARY,
+  proto.DeleteAuthorizedUserRequest,
+  proto.DeleteAuthorizedUserResponse,
+  /**
+   * @param {!proto.DeleteAuthorizedUserRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  proto.DeleteAuthorizedUserResponse.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.DeleteAuthorizedUserRequest,
+ *   !proto.DeleteAuthorizedUserResponse>}
+ */
+const methodInfo_KillSwitchService_DeleteAuthorizedUser = new grpc.web.AbstractClientBase.MethodInfo(
+  proto.DeleteAuthorizedUserResponse,
+  /**
+   * @param {!proto.DeleteAuthorizedUserRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  proto.DeleteAuthorizedUserResponse.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.DeleteAuthorizedUserRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.DeleteAuthorizedUserResponse)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.DeleteAuthorizedUserResponse>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.KillSwitchServiceClient.prototype.deleteAuthorizedUser =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/KillSwitchService/DeleteAuthorizedUser',
+      request,
+      metadata || {},
+      methodDescriptor_KillSwitchService_DeleteAuthorizedUser,
+      callback);
+};
+
+
+/**
+ * @param {!proto.DeleteAuthorizedUserRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.DeleteAuthorizedUserResponse>}
+ *     Promise that resolves to the response
+ */
+proto.KillSwitchServicePromiseClient.prototype.deleteAuthorizedUser =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/KillSwitchService/DeleteAuthorizedUser',
+      request,
+      metadata || {},
+      methodDescriptor_KillSwitchService_DeleteAuthorizedUser);
+};
+
+
+module.exports = proto;
+
diff --git a/frontend/src/api_proto/kill_switch_objects_pb.js b/frontend/src/api_proto/kill_switch_objects_pb.js
new file mode 100644
index 0000000..fede3a9
--- /dev/null
+++ b/frontend/src/api_proto/kill_switch_objects_pb.js
@@ -0,0 +1,2670 @@
+// source: api_proto/kill_switch_objects.proto
+/**
+ * @fileoverview
+ * @enhanceable
+ * @suppress {missingRequire} reports error on implicit type usages.
+ * @suppress {messageConventions} JS Compiler reports an error if a variable or
+ *     field starts with 'MSG_' and isn't a translatable message.
+ * @public
+ */
+// GENERATED CODE -- DO NOT EDIT!
+/* eslint-disable */
+// @ts-nocheck
+
+var jspb = require('google-protobuf');
+var goog = jspb;
+var global = Function('return this')();
+
+var api_proto_common_pb = require('../api_proto/common_pb.js');
+goog.object.extend(proto, api_proto_common_pb);
+var google_protobuf_timestamp_pb = require('google-protobuf/google/protobuf/timestamp_pb.js');
+goog.object.extend(proto, google_protobuf_timestamp_pb);
+goog.exportSymbol('proto.AuthorizedUserTransformation', null, global);
+goog.exportSymbol('proto.Feature', null, global);
+goog.exportSymbol('proto.Feature.Type', null, global);
+goog.exportSymbol('proto.KillSwitch', null, global);
+goog.exportSymbol('proto.KillSwitchAuditLogEntry', null, global);
+goog.exportSymbol('proto.KillSwitchAuditLogEntry.AuthorizedUserAdded', null, global);
+goog.exportSymbol('proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted', null, global);
+goog.exportSymbol('proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated', null, global);
+goog.exportSymbol('proto.KillSwitchAuditLogEntry.DescriptionCase', null, global);
+goog.exportSymbol('proto.KillSwitchAuditLogEntry.KillSwitchDisabled', null, global);
+goog.exportSymbol('proto.KillSwitchAuditLogEntry.KillSwitchEnabled', null, global);
+goog.exportSymbol('proto.KillSwitchAuthorizedUser', null, global);
+goog.exportSymbol('proto.KillSwitchAuthorizedUser.AccessLevel', null, global);
+goog.exportSymbol('proto.KillSwitchTransformation', null, global);
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.Feature = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.Feature, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.Feature.displayName = 'proto.Feature';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.KillSwitch = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.KillSwitch.repeatedFields_, null);
+};
+goog.inherits(proto.KillSwitch, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.KillSwitch.displayName = 'proto.KillSwitch';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.KillSwitchAuthorizedUser = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.KillSwitchAuthorizedUser, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.KillSwitchAuthorizedUser.displayName = 'proto.KillSwitchAuthorizedUser';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.KillSwitchTransformation = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.KillSwitchTransformation, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.KillSwitchTransformation.displayName = 'proto.KillSwitchTransformation';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.AuthorizedUserTransformation = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.AuthorizedUserTransformation, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.AuthorizedUserTransformation.displayName = 'proto.AuthorizedUserTransformation';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.KillSwitchAuditLogEntry = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, proto.KillSwitchAuditLogEntry.oneofGroups_);
+};
+goog.inherits(proto.KillSwitchAuditLogEntry, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.KillSwitchAuditLogEntry.displayName = 'proto.KillSwitchAuditLogEntry';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.KillSwitchAuditLogEntry.KillSwitchEnabled = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.KillSwitchAuditLogEntry.KillSwitchEnabled, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.KillSwitchAuditLogEntry.KillSwitchEnabled.displayName = 'proto.KillSwitchAuditLogEntry.KillSwitchEnabled';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.KillSwitchAuditLogEntry.KillSwitchDisabled = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.KillSwitchAuditLogEntry.KillSwitchDisabled, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.KillSwitchAuditLogEntry.KillSwitchDisabled.displayName = 'proto.KillSwitchAuditLogEntry.KillSwitchDisabled';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.KillSwitchAuditLogEntry.AuthorizedUserAdded = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.KillSwitchAuditLogEntry.AuthorizedUserAdded, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.KillSwitchAuditLogEntry.AuthorizedUserAdded.displayName = 'proto.KillSwitchAuditLogEntry.AuthorizedUserAdded';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated.displayName = 'proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted.displayName = 'proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted';
+}
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.Feature.prototype.toObject = function(opt_includeInstance) {
+  return proto.Feature.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.Feature} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.Feature.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    id: jspb.Message.getFieldWithDefault(msg, 1, 0),
+    codename: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    type: jspb.Message.getFieldWithDefault(msg, 3, 0)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.Feature}
+ */
+proto.Feature.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.Feature;
+  return proto.Feature.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.Feature} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.Feature}
+ */
+proto.Feature.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt32());
+      msg.setId(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setCodename(value);
+      break;
+    case 3:
+      var value = /** @type {!proto.Feature.Type} */ (reader.readEnum());
+      msg.setType(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.Feature.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.Feature.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.Feature} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.Feature.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getId();
+  if (f !== 0) {
+    writer.writeInt32(
+      1,
+      f
+    );
+  }
+  f = message.getCodename();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getType();
+  if (f !== 0.0) {
+    writer.writeEnum(
+      3,
+      f
+    );
+  }
+};
+
+
+/**
+ * @enum {number}
+ */
+proto.Feature.Type = {
+  TYPE_UNKNOWN: 0,
+  TYPE_EXPERIMENT: 1,
+  TYPE_OPTION: 2,
+  TYPE_DEPRECATED: 10
+};
+
+/**
+ * optional int32 id = 1;
+ * @return {number}
+ */
+proto.Feature.prototype.getId = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.Feature} returns this
+ */
+proto.Feature.prototype.setId = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+/**
+ * optional string codename = 2;
+ * @return {string}
+ */
+proto.Feature.prototype.getCodename = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.Feature} returns this
+ */
+proto.Feature.prototype.setCodename = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional Type type = 3;
+ * @return {!proto.Feature.Type}
+ */
+proto.Feature.prototype.getType = function() {
+  return /** @type {!proto.Feature.Type} */ (jspb.Message.getFieldWithDefault(this, 3, 0));
+};
+
+
+/**
+ * @param {!proto.Feature.Type} value
+ * @return {!proto.Feature} returns this
+ */
+proto.Feature.prototype.setType = function(value) {
+  return jspb.Message.setProto3EnumField(this, 3, value);
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.KillSwitch.repeatedFields_ = [5];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.KillSwitch.prototype.toObject = function(opt_includeInstance) {
+  return proto.KillSwitch.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.KillSwitch} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.KillSwitch.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    id: jspb.Message.getFieldWithDefault(msg, 1, 0),
+    feature: (f = msg.getFeature()) && proto.Feature.toObject(includeInstance, f),
+    minVersion: jspb.Message.getFieldWithDefault(msg, 3, ""),
+    maxVersion: jspb.Message.getFieldWithDefault(msg, 4, ""),
+    browsersList: (f = jspb.Message.getRepeatedField(msg, 5)) == null ? undefined : f,
+    active: jspb.Message.getBooleanFieldWithDefault(msg, 6, false)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.KillSwitch}
+ */
+proto.KillSwitch.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.KillSwitch;
+  return proto.KillSwitch.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.KillSwitch} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.KillSwitch}
+ */
+proto.KillSwitch.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt32());
+      msg.setId(value);
+      break;
+    case 2:
+      var value = new proto.Feature;
+      reader.readMessage(value,proto.Feature.deserializeBinaryFromReader);
+      msg.setFeature(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setMinVersion(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setMaxVersion(value);
+      break;
+    case 5:
+      var values = /** @type {!Array<!proto.Environment.Browser>} */ (reader.isDelimited() ? reader.readPackedEnum() : [reader.readEnum()]);
+      for (var i = 0; i < values.length; i++) {
+        msg.addBrowsers(values[i]);
+      }
+      break;
+    case 6:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setActive(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.KillSwitch.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.KillSwitch.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.KillSwitch} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.KillSwitch.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getId();
+  if (f !== 0) {
+    writer.writeInt32(
+      1,
+      f
+    );
+  }
+  f = message.getFeature();
+  if (f != null) {
+    writer.writeMessage(
+      2,
+      f,
+      proto.Feature.serializeBinaryToWriter
+    );
+  }
+  f = message.getMinVersion();
+  if (f.length > 0) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+  f = message.getMaxVersion();
+  if (f.length > 0) {
+    writer.writeString(
+      4,
+      f
+    );
+  }
+  f = message.getBrowsersList();
+  if (f.length > 0) {
+    writer.writePackedEnum(
+      5,
+      f
+    );
+  }
+  f = message.getActive();
+  if (f) {
+    writer.writeBool(
+      6,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional int32 id = 1;
+ * @return {number}
+ */
+proto.KillSwitch.prototype.getId = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.KillSwitch} returns this
+ */
+proto.KillSwitch.prototype.setId = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+/**
+ * optional Feature feature = 2;
+ * @return {?proto.Feature}
+ */
+proto.KillSwitch.prototype.getFeature = function() {
+  return /** @type{?proto.Feature} */ (
+    jspb.Message.getWrapperField(this, proto.Feature, 2));
+};
+
+
+/**
+ * @param {?proto.Feature|undefined} value
+ * @return {!proto.KillSwitch} returns this
+*/
+proto.KillSwitch.prototype.setFeature = function(value) {
+  return jspb.Message.setWrapperField(this, 2, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.KillSwitch} returns this
+ */
+proto.KillSwitch.prototype.clearFeature = function() {
+  return this.setFeature(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.KillSwitch.prototype.hasFeature = function() {
+  return jspb.Message.getField(this, 2) != null;
+};
+
+
+/**
+ * optional string min_version = 3;
+ * @return {string}
+ */
+proto.KillSwitch.prototype.getMinVersion = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.KillSwitch} returns this
+ */
+proto.KillSwitch.prototype.setMinVersion = function(value) {
+  return jspb.Message.setProto3StringField(this, 3, value);
+};
+
+
+/**
+ * optional string max_version = 4;
+ * @return {string}
+ */
+proto.KillSwitch.prototype.getMaxVersion = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.KillSwitch} returns this
+ */
+proto.KillSwitch.prototype.setMaxVersion = function(value) {
+  return jspb.Message.setProto3StringField(this, 4, value);
+};
+
+
+/**
+ * repeated Environment.Browser browsers = 5;
+ * @return {!Array<!proto.Environment.Browser>}
+ */
+proto.KillSwitch.prototype.getBrowsersList = function() {
+  return /** @type {!Array<!proto.Environment.Browser>} */ (jspb.Message.getRepeatedField(this, 5));
+};
+
+
+/**
+ * @param {!Array<!proto.Environment.Browser>} value
+ * @return {!proto.KillSwitch} returns this
+ */
+proto.KillSwitch.prototype.setBrowsersList = function(value) {
+  return jspb.Message.setField(this, 5, value || []);
+};
+
+
+/**
+ * @param {!proto.Environment.Browser} value
+ * @param {number=} opt_index
+ * @return {!proto.KillSwitch} returns this
+ */
+proto.KillSwitch.prototype.addBrowsers = function(value, opt_index) {
+  return jspb.Message.addToRepeatedField(this, 5, value, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.KillSwitch} returns this
+ */
+proto.KillSwitch.prototype.clearBrowsersList = function() {
+  return this.setBrowsersList([]);
+};
+
+
+/**
+ * optional bool active = 6;
+ * @return {boolean}
+ */
+proto.KillSwitch.prototype.getActive = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 6, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.KillSwitch} returns this
+ */
+proto.KillSwitch.prototype.setActive = function(value) {
+  return jspb.Message.setProto3BooleanField(this, 6, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.KillSwitchAuthorizedUser.prototype.toObject = function(opt_includeInstance) {
+  return proto.KillSwitchAuthorizedUser.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.KillSwitchAuthorizedUser} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.KillSwitchAuthorizedUser.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    id: jspb.Message.getFieldWithDefault(msg, 1, 0),
+    googleUid: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    email: jspb.Message.getFieldWithDefault(msg, 3, ""),
+    accessLevel: jspb.Message.getFieldWithDefault(msg, 4, 0)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.KillSwitchAuthorizedUser}
+ */
+proto.KillSwitchAuthorizedUser.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.KillSwitchAuthorizedUser;
+  return proto.KillSwitchAuthorizedUser.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.KillSwitchAuthorizedUser} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.KillSwitchAuthorizedUser}
+ */
+proto.KillSwitchAuthorizedUser.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt32());
+      msg.setId(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setGoogleUid(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setEmail(value);
+      break;
+    case 4:
+      var value = /** @type {!proto.KillSwitchAuthorizedUser.AccessLevel} */ (reader.readEnum());
+      msg.setAccessLevel(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.KillSwitchAuthorizedUser.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.KillSwitchAuthorizedUser.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.KillSwitchAuthorizedUser} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.KillSwitchAuthorizedUser.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getId();
+  if (f !== 0) {
+    writer.writeInt32(
+      1,
+      f
+    );
+  }
+  f = message.getGoogleUid();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getEmail();
+  if (f.length > 0) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+  f = message.getAccessLevel();
+  if (f !== 0.0) {
+    writer.writeEnum(
+      4,
+      f
+    );
+  }
+};
+
+
+/**
+ * @enum {number}
+ */
+proto.KillSwitchAuthorizedUser.AccessLevel = {
+  ACCESS_LEVEL_NONE: 0,
+  ACCESS_LEVEL_ACTIVATOR: 5,
+  ACCESS_LEVEL_ADMIN: 10
+};
+
+/**
+ * optional int32 id = 1;
+ * @return {number}
+ */
+proto.KillSwitchAuthorizedUser.prototype.getId = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.KillSwitchAuthorizedUser} returns this
+ */
+proto.KillSwitchAuthorizedUser.prototype.setId = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+/**
+ * optional string google_uid = 2;
+ * @return {string}
+ */
+proto.KillSwitchAuthorizedUser.prototype.getGoogleUid = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.KillSwitchAuthorizedUser} returns this
+ */
+proto.KillSwitchAuthorizedUser.prototype.setGoogleUid = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional string email = 3;
+ * @return {string}
+ */
+proto.KillSwitchAuthorizedUser.prototype.getEmail = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.KillSwitchAuthorizedUser} returns this
+ */
+proto.KillSwitchAuthorizedUser.prototype.setEmail = function(value) {
+  return jspb.Message.setProto3StringField(this, 3, value);
+};
+
+
+/**
+ * optional AccessLevel access_level = 4;
+ * @return {!proto.KillSwitchAuthorizedUser.AccessLevel}
+ */
+proto.KillSwitchAuthorizedUser.prototype.getAccessLevel = function() {
+  return /** @type {!proto.KillSwitchAuthorizedUser.AccessLevel} */ (jspb.Message.getFieldWithDefault(this, 4, 0));
+};
+
+
+/**
+ * @param {!proto.KillSwitchAuthorizedUser.AccessLevel} value
+ * @return {!proto.KillSwitchAuthorizedUser} returns this
+ */
+proto.KillSwitchAuthorizedUser.prototype.setAccessLevel = function(value) {
+  return jspb.Message.setProto3EnumField(this, 4, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.KillSwitchTransformation.prototype.toObject = function(opt_includeInstance) {
+  return proto.KillSwitchTransformation.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.KillSwitchTransformation} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.KillSwitchTransformation.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    old: (f = msg.getOld()) && proto.KillSwitch.toObject(includeInstance, f),
+    pb_new: (f = msg.getNew()) && proto.KillSwitch.toObject(includeInstance, f)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.KillSwitchTransformation}
+ */
+proto.KillSwitchTransformation.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.KillSwitchTransformation;
+  return proto.KillSwitchTransformation.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.KillSwitchTransformation} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.KillSwitchTransformation}
+ */
+proto.KillSwitchTransformation.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new proto.KillSwitch;
+      reader.readMessage(value,proto.KillSwitch.deserializeBinaryFromReader);
+      msg.setOld(value);
+      break;
+    case 2:
+      var value = new proto.KillSwitch;
+      reader.readMessage(value,proto.KillSwitch.deserializeBinaryFromReader);
+      msg.setNew(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.KillSwitchTransformation.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.KillSwitchTransformation.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.KillSwitchTransformation} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.KillSwitchTransformation.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getOld();
+  if (f != null) {
+    writer.writeMessage(
+      1,
+      f,
+      proto.KillSwitch.serializeBinaryToWriter
+    );
+  }
+  f = message.getNew();
+  if (f != null) {
+    writer.writeMessage(
+      2,
+      f,
+      proto.KillSwitch.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * optional KillSwitch old = 1;
+ * @return {?proto.KillSwitch}
+ */
+proto.KillSwitchTransformation.prototype.getOld = function() {
+  return /** @type{?proto.KillSwitch} */ (
+    jspb.Message.getWrapperField(this, proto.KillSwitch, 1));
+};
+
+
+/**
+ * @param {?proto.KillSwitch|undefined} value
+ * @return {!proto.KillSwitchTransformation} returns this
+*/
+proto.KillSwitchTransformation.prototype.setOld = function(value) {
+  return jspb.Message.setWrapperField(this, 1, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.KillSwitchTransformation} returns this
+ */
+proto.KillSwitchTransformation.prototype.clearOld = function() {
+  return this.setOld(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.KillSwitchTransformation.prototype.hasOld = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+/**
+ * optional KillSwitch new = 2;
+ * @return {?proto.KillSwitch}
+ */
+proto.KillSwitchTransformation.prototype.getNew = function() {
+  return /** @type{?proto.KillSwitch} */ (
+    jspb.Message.getWrapperField(this, proto.KillSwitch, 2));
+};
+
+
+/**
+ * @param {?proto.KillSwitch|undefined} value
+ * @return {!proto.KillSwitchTransformation} returns this
+*/
+proto.KillSwitchTransformation.prototype.setNew = function(value) {
+  return jspb.Message.setWrapperField(this, 2, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.KillSwitchTransformation} returns this
+ */
+proto.KillSwitchTransformation.prototype.clearNew = function() {
+  return this.setNew(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.KillSwitchTransformation.prototype.hasNew = function() {
+  return jspb.Message.getField(this, 2) != null;
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.AuthorizedUserTransformation.prototype.toObject = function(opt_includeInstance) {
+  return proto.AuthorizedUserTransformation.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.AuthorizedUserTransformation} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.AuthorizedUserTransformation.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    old: (f = msg.getOld()) && proto.KillSwitchAuthorizedUser.toObject(includeInstance, f),
+    pb_new: (f = msg.getNew()) && proto.KillSwitchAuthorizedUser.toObject(includeInstance, f)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.AuthorizedUserTransformation}
+ */
+proto.AuthorizedUserTransformation.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.AuthorizedUserTransformation;
+  return proto.AuthorizedUserTransformation.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.AuthorizedUserTransformation} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.AuthorizedUserTransformation}
+ */
+proto.AuthorizedUserTransformation.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new proto.KillSwitchAuthorizedUser;
+      reader.readMessage(value,proto.KillSwitchAuthorizedUser.deserializeBinaryFromReader);
+      msg.setOld(value);
+      break;
+    case 2:
+      var value = new proto.KillSwitchAuthorizedUser;
+      reader.readMessage(value,proto.KillSwitchAuthorizedUser.deserializeBinaryFromReader);
+      msg.setNew(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.AuthorizedUserTransformation.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.AuthorizedUserTransformation.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.AuthorizedUserTransformation} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.AuthorizedUserTransformation.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getOld();
+  if (f != null) {
+    writer.writeMessage(
+      1,
+      f,
+      proto.KillSwitchAuthorizedUser.serializeBinaryToWriter
+    );
+  }
+  f = message.getNew();
+  if (f != null) {
+    writer.writeMessage(
+      2,
+      f,
+      proto.KillSwitchAuthorizedUser.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * optional KillSwitchAuthorizedUser old = 1;
+ * @return {?proto.KillSwitchAuthorizedUser}
+ */
+proto.AuthorizedUserTransformation.prototype.getOld = function() {
+  return /** @type{?proto.KillSwitchAuthorizedUser} */ (
+    jspb.Message.getWrapperField(this, proto.KillSwitchAuthorizedUser, 1));
+};
+
+
+/**
+ * @param {?proto.KillSwitchAuthorizedUser|undefined} value
+ * @return {!proto.AuthorizedUserTransformation} returns this
+*/
+proto.AuthorizedUserTransformation.prototype.setOld = function(value) {
+  return jspb.Message.setWrapperField(this, 1, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.AuthorizedUserTransformation} returns this
+ */
+proto.AuthorizedUserTransformation.prototype.clearOld = function() {
+  return this.setOld(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.AuthorizedUserTransformation.prototype.hasOld = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+/**
+ * optional KillSwitchAuthorizedUser new = 2;
+ * @return {?proto.KillSwitchAuthorizedUser}
+ */
+proto.AuthorizedUserTransformation.prototype.getNew = function() {
+  return /** @type{?proto.KillSwitchAuthorizedUser} */ (
+    jspb.Message.getWrapperField(this, proto.KillSwitchAuthorizedUser, 2));
+};
+
+
+/**
+ * @param {?proto.KillSwitchAuthorizedUser|undefined} value
+ * @return {!proto.AuthorizedUserTransformation} returns this
+*/
+proto.AuthorizedUserTransformation.prototype.setNew = function(value) {
+  return jspb.Message.setWrapperField(this, 2, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.AuthorizedUserTransformation} returns this
+ */
+proto.AuthorizedUserTransformation.prototype.clearNew = function() {
+  return this.setNew(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.AuthorizedUserTransformation.prototype.hasNew = function() {
+  return jspb.Message.getField(this, 2) != null;
+};
+
+
+
+/**
+ * Oneof group definitions for this message. Each group defines the field
+ * numbers belonging to that group. When of these fields' value is set, all
+ * other fields in the group are cleared. During deserialization, if multiple
+ * fields are encountered for a group, only the last value seen will be kept.
+ * @private {!Array<!Array<number>>}
+ * @const
+ */
+proto.KillSwitchAuditLogEntry.oneofGroups_ = [[3,4,5,6,7]];
+
+/**
+ * @enum {number}
+ */
+proto.KillSwitchAuditLogEntry.DescriptionCase = {
+  DESCRIPTION_NOT_SET: 0,
+  KILL_SWITCH_ENABLED: 3,
+  KILL_SWITCH_DISABLED: 4,
+  AUTHORIZED_USER_ADDED: 5,
+  AUTHORIZED_USER_UPDATED: 6,
+  AUTHORIZED_USER_DELETED: 7
+};
+
+/**
+ * @return {proto.KillSwitchAuditLogEntry.DescriptionCase}
+ */
+proto.KillSwitchAuditLogEntry.prototype.getDescriptionCase = function() {
+  return /** @type {proto.KillSwitchAuditLogEntry.DescriptionCase} */(jspb.Message.computeOneofCase(this, proto.KillSwitchAuditLogEntry.oneofGroups_[0]));
+};
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.KillSwitchAuditLogEntry.prototype.toObject = function(opt_includeInstance) {
+  return proto.KillSwitchAuditLogEntry.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.KillSwitchAuditLogEntry} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.KillSwitchAuditLogEntry.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    timestamp: (f = msg.getTimestamp()) && google_protobuf_timestamp_pb.Timestamp.toObject(includeInstance, f),
+    user: (f = msg.getUser()) && proto.KillSwitchAuthorizedUser.toObject(includeInstance, f),
+    killSwitchEnabled: (f = msg.getKillSwitchEnabled()) && proto.KillSwitchAuditLogEntry.KillSwitchEnabled.toObject(includeInstance, f),
+    killSwitchDisabled: (f = msg.getKillSwitchDisabled()) && proto.KillSwitchAuditLogEntry.KillSwitchDisabled.toObject(includeInstance, f),
+    authorizedUserAdded: (f = msg.getAuthorizedUserAdded()) && proto.KillSwitchAuditLogEntry.AuthorizedUserAdded.toObject(includeInstance, f),
+    authorizedUserUpdated: (f = msg.getAuthorizedUserUpdated()) && proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated.toObject(includeInstance, f),
+    authorizedUserDeleted: (f = msg.getAuthorizedUserDeleted()) && proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted.toObject(includeInstance, f)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.KillSwitchAuditLogEntry}
+ */
+proto.KillSwitchAuditLogEntry.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.KillSwitchAuditLogEntry;
+  return proto.KillSwitchAuditLogEntry.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.KillSwitchAuditLogEntry} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.KillSwitchAuditLogEntry}
+ */
+proto.KillSwitchAuditLogEntry.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new google_protobuf_timestamp_pb.Timestamp;
+      reader.readMessage(value,google_protobuf_timestamp_pb.Timestamp.deserializeBinaryFromReader);
+      msg.setTimestamp(value);
+      break;
+    case 2:
+      var value = new proto.KillSwitchAuthorizedUser;
+      reader.readMessage(value,proto.KillSwitchAuthorizedUser.deserializeBinaryFromReader);
+      msg.setUser(value);
+      break;
+    case 3:
+      var value = new proto.KillSwitchAuditLogEntry.KillSwitchEnabled;
+      reader.readMessage(value,proto.KillSwitchAuditLogEntry.KillSwitchEnabled.deserializeBinaryFromReader);
+      msg.setKillSwitchEnabled(value);
+      break;
+    case 4:
+      var value = new proto.KillSwitchAuditLogEntry.KillSwitchDisabled;
+      reader.readMessage(value,proto.KillSwitchAuditLogEntry.KillSwitchDisabled.deserializeBinaryFromReader);
+      msg.setKillSwitchDisabled(value);
+      break;
+    case 5:
+      var value = new proto.KillSwitchAuditLogEntry.AuthorizedUserAdded;
+      reader.readMessage(value,proto.KillSwitchAuditLogEntry.AuthorizedUserAdded.deserializeBinaryFromReader);
+      msg.setAuthorizedUserAdded(value);
+      break;
+    case 6:
+      var value = new proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated;
+      reader.readMessage(value,proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated.deserializeBinaryFromReader);
+      msg.setAuthorizedUserUpdated(value);
+      break;
+    case 7:
+      var value = new proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted;
+      reader.readMessage(value,proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted.deserializeBinaryFromReader);
+      msg.setAuthorizedUserDeleted(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.KillSwitchAuditLogEntry.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.KillSwitchAuditLogEntry.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.KillSwitchAuditLogEntry} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.KillSwitchAuditLogEntry.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getTimestamp();
+  if (f != null) {
+    writer.writeMessage(
+      1,
+      f,
+      google_protobuf_timestamp_pb.Timestamp.serializeBinaryToWriter
+    );
+  }
+  f = message.getUser();
+  if (f != null) {
+    writer.writeMessage(
+      2,
+      f,
+      proto.KillSwitchAuthorizedUser.serializeBinaryToWriter
+    );
+  }
+  f = message.getKillSwitchEnabled();
+  if (f != null) {
+    writer.writeMessage(
+      3,
+      f,
+      proto.KillSwitchAuditLogEntry.KillSwitchEnabled.serializeBinaryToWriter
+    );
+  }
+  f = message.getKillSwitchDisabled();
+  if (f != null) {
+    writer.writeMessage(
+      4,
+      f,
+      proto.KillSwitchAuditLogEntry.KillSwitchDisabled.serializeBinaryToWriter
+    );
+  }
+  f = message.getAuthorizedUserAdded();
+  if (f != null) {
+    writer.writeMessage(
+      5,
+      f,
+      proto.KillSwitchAuditLogEntry.AuthorizedUserAdded.serializeBinaryToWriter
+    );
+  }
+  f = message.getAuthorizedUserUpdated();
+  if (f != null) {
+    writer.writeMessage(
+      6,
+      f,
+      proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated.serializeBinaryToWriter
+    );
+  }
+  f = message.getAuthorizedUserDeleted();
+  if (f != null) {
+    writer.writeMessage(
+      7,
+      f,
+      proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted.serializeBinaryToWriter
+    );
+  }
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.KillSwitchAuditLogEntry.KillSwitchEnabled.prototype.toObject = function(opt_includeInstance) {
+  return proto.KillSwitchAuditLogEntry.KillSwitchEnabled.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.KillSwitchAuditLogEntry.KillSwitchEnabled} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.KillSwitchAuditLogEntry.KillSwitchEnabled.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    killSwitch: (f = msg.getKillSwitch()) && proto.KillSwitch.toObject(includeInstance, f)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.KillSwitchAuditLogEntry.KillSwitchEnabled}
+ */
+proto.KillSwitchAuditLogEntry.KillSwitchEnabled.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.KillSwitchAuditLogEntry.KillSwitchEnabled;
+  return proto.KillSwitchAuditLogEntry.KillSwitchEnabled.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.KillSwitchAuditLogEntry.KillSwitchEnabled} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.KillSwitchAuditLogEntry.KillSwitchEnabled}
+ */
+proto.KillSwitchAuditLogEntry.KillSwitchEnabled.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new proto.KillSwitch;
+      reader.readMessage(value,proto.KillSwitch.deserializeBinaryFromReader);
+      msg.setKillSwitch(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.KillSwitchAuditLogEntry.KillSwitchEnabled.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.KillSwitchAuditLogEntry.KillSwitchEnabled.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.KillSwitchAuditLogEntry.KillSwitchEnabled} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.KillSwitchAuditLogEntry.KillSwitchEnabled.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getKillSwitch();
+  if (f != null) {
+    writer.writeMessage(
+      1,
+      f,
+      proto.KillSwitch.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * optional KillSwitch kill_switch = 1;
+ * @return {?proto.KillSwitch}
+ */
+proto.KillSwitchAuditLogEntry.KillSwitchEnabled.prototype.getKillSwitch = function() {
+  return /** @type{?proto.KillSwitch} */ (
+    jspb.Message.getWrapperField(this, proto.KillSwitch, 1));
+};
+
+
+/**
+ * @param {?proto.KillSwitch|undefined} value
+ * @return {!proto.KillSwitchAuditLogEntry.KillSwitchEnabled} returns this
+*/
+proto.KillSwitchAuditLogEntry.KillSwitchEnabled.prototype.setKillSwitch = function(value) {
+  return jspb.Message.setWrapperField(this, 1, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.KillSwitchAuditLogEntry.KillSwitchEnabled} returns this
+ */
+proto.KillSwitchAuditLogEntry.KillSwitchEnabled.prototype.clearKillSwitch = function() {
+  return this.setKillSwitch(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.KillSwitchAuditLogEntry.KillSwitchEnabled.prototype.hasKillSwitch = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.KillSwitchAuditLogEntry.KillSwitchDisabled.prototype.toObject = function(opt_includeInstance) {
+  return proto.KillSwitchAuditLogEntry.KillSwitchDisabled.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.KillSwitchAuditLogEntry.KillSwitchDisabled} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.KillSwitchAuditLogEntry.KillSwitchDisabled.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    transformation: (f = msg.getTransformation()) && proto.KillSwitchTransformation.toObject(includeInstance, f)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.KillSwitchAuditLogEntry.KillSwitchDisabled}
+ */
+proto.KillSwitchAuditLogEntry.KillSwitchDisabled.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.KillSwitchAuditLogEntry.KillSwitchDisabled;
+  return proto.KillSwitchAuditLogEntry.KillSwitchDisabled.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.KillSwitchAuditLogEntry.KillSwitchDisabled} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.KillSwitchAuditLogEntry.KillSwitchDisabled}
+ */
+proto.KillSwitchAuditLogEntry.KillSwitchDisabled.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new proto.KillSwitchTransformation;
+      reader.readMessage(value,proto.KillSwitchTransformation.deserializeBinaryFromReader);
+      msg.setTransformation(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.KillSwitchAuditLogEntry.KillSwitchDisabled.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.KillSwitchAuditLogEntry.KillSwitchDisabled.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.KillSwitchAuditLogEntry.KillSwitchDisabled} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.KillSwitchAuditLogEntry.KillSwitchDisabled.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getTransformation();
+  if (f != null) {
+    writer.writeMessage(
+      1,
+      f,
+      proto.KillSwitchTransformation.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * optional KillSwitchTransformation transformation = 1;
+ * @return {?proto.KillSwitchTransformation}
+ */
+proto.KillSwitchAuditLogEntry.KillSwitchDisabled.prototype.getTransformation = function() {
+  return /** @type{?proto.KillSwitchTransformation} */ (
+    jspb.Message.getWrapperField(this, proto.KillSwitchTransformation, 1));
+};
+
+
+/**
+ * @param {?proto.KillSwitchTransformation|undefined} value
+ * @return {!proto.KillSwitchAuditLogEntry.KillSwitchDisabled} returns this
+*/
+proto.KillSwitchAuditLogEntry.KillSwitchDisabled.prototype.setTransformation = function(value) {
+  return jspb.Message.setWrapperField(this, 1, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.KillSwitchAuditLogEntry.KillSwitchDisabled} returns this
+ */
+proto.KillSwitchAuditLogEntry.KillSwitchDisabled.prototype.clearTransformation = function() {
+  return this.setTransformation(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.KillSwitchAuditLogEntry.KillSwitchDisabled.prototype.hasTransformation = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.KillSwitchAuditLogEntry.AuthorizedUserAdded.prototype.toObject = function(opt_includeInstance) {
+  return proto.KillSwitchAuditLogEntry.AuthorizedUserAdded.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.KillSwitchAuditLogEntry.AuthorizedUserAdded} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.KillSwitchAuditLogEntry.AuthorizedUserAdded.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    user: (f = msg.getUser()) && proto.KillSwitchAuthorizedUser.toObject(includeInstance, f)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.KillSwitchAuditLogEntry.AuthorizedUserAdded}
+ */
+proto.KillSwitchAuditLogEntry.AuthorizedUserAdded.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.KillSwitchAuditLogEntry.AuthorizedUserAdded;
+  return proto.KillSwitchAuditLogEntry.AuthorizedUserAdded.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.KillSwitchAuditLogEntry.AuthorizedUserAdded} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.KillSwitchAuditLogEntry.AuthorizedUserAdded}
+ */
+proto.KillSwitchAuditLogEntry.AuthorizedUserAdded.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new proto.KillSwitchAuthorizedUser;
+      reader.readMessage(value,proto.KillSwitchAuthorizedUser.deserializeBinaryFromReader);
+      msg.setUser(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.KillSwitchAuditLogEntry.AuthorizedUserAdded.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.KillSwitchAuditLogEntry.AuthorizedUserAdded.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.KillSwitchAuditLogEntry.AuthorizedUserAdded} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.KillSwitchAuditLogEntry.AuthorizedUserAdded.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getUser();
+  if (f != null) {
+    writer.writeMessage(
+      1,
+      f,
+      proto.KillSwitchAuthorizedUser.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * optional KillSwitchAuthorizedUser user = 1;
+ * @return {?proto.KillSwitchAuthorizedUser}
+ */
+proto.KillSwitchAuditLogEntry.AuthorizedUserAdded.prototype.getUser = function() {
+  return /** @type{?proto.KillSwitchAuthorizedUser} */ (
+    jspb.Message.getWrapperField(this, proto.KillSwitchAuthorizedUser, 1));
+};
+
+
+/**
+ * @param {?proto.KillSwitchAuthorizedUser|undefined} value
+ * @return {!proto.KillSwitchAuditLogEntry.AuthorizedUserAdded} returns this
+*/
+proto.KillSwitchAuditLogEntry.AuthorizedUserAdded.prototype.setUser = function(value) {
+  return jspb.Message.setWrapperField(this, 1, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.KillSwitchAuditLogEntry.AuthorizedUserAdded} returns this
+ */
+proto.KillSwitchAuditLogEntry.AuthorizedUserAdded.prototype.clearUser = function() {
+  return this.setUser(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.KillSwitchAuditLogEntry.AuthorizedUserAdded.prototype.hasUser = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated.prototype.toObject = function(opt_includeInstance) {
+  return proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    transformation: (f = msg.getTransformation()) && proto.AuthorizedUserTransformation.toObject(includeInstance, f)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated}
+ */
+proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated;
+  return proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated}
+ */
+proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new proto.AuthorizedUserTransformation;
+      reader.readMessage(value,proto.AuthorizedUserTransformation.deserializeBinaryFromReader);
+      msg.setTransformation(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getTransformation();
+  if (f != null) {
+    writer.writeMessage(
+      1,
+      f,
+      proto.AuthorizedUserTransformation.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * optional AuthorizedUserTransformation transformation = 1;
+ * @return {?proto.AuthorizedUserTransformation}
+ */
+proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated.prototype.getTransformation = function() {
+  return /** @type{?proto.AuthorizedUserTransformation} */ (
+    jspb.Message.getWrapperField(this, proto.AuthorizedUserTransformation, 1));
+};
+
+
+/**
+ * @param {?proto.AuthorizedUserTransformation|undefined} value
+ * @return {!proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated} returns this
+*/
+proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated.prototype.setTransformation = function(value) {
+  return jspb.Message.setWrapperField(this, 1, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated} returns this
+ */
+proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated.prototype.clearTransformation = function() {
+  return this.setTransformation(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated.prototype.hasTransformation = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted.prototype.toObject = function(opt_includeInstance) {
+  return proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    oldUser: (f = msg.getOldUser()) && proto.KillSwitchAuthorizedUser.toObject(includeInstance, f)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted}
+ */
+proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted;
+  return proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted}
+ */
+proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new proto.KillSwitchAuthorizedUser;
+      reader.readMessage(value,proto.KillSwitchAuthorizedUser.deserializeBinaryFromReader);
+      msg.setOldUser(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getOldUser();
+  if (f != null) {
+    writer.writeMessage(
+      1,
+      f,
+      proto.KillSwitchAuthorizedUser.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * optional KillSwitchAuthorizedUser old_user = 1;
+ * @return {?proto.KillSwitchAuthorizedUser}
+ */
+proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted.prototype.getOldUser = function() {
+  return /** @type{?proto.KillSwitchAuthorizedUser} */ (
+    jspb.Message.getWrapperField(this, proto.KillSwitchAuthorizedUser, 1));
+};
+
+
+/**
+ * @param {?proto.KillSwitchAuthorizedUser|undefined} value
+ * @return {!proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted} returns this
+*/
+proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted.prototype.setOldUser = function(value) {
+  return jspb.Message.setWrapperField(this, 1, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted} returns this
+ */
+proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted.prototype.clearOldUser = function() {
+  return this.setOldUser(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted.prototype.hasOldUser = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+/**
+ * optional google.protobuf.Timestamp timestamp = 1;
+ * @return {?proto.google.protobuf.Timestamp}
+ */
+proto.KillSwitchAuditLogEntry.prototype.getTimestamp = function() {
+  return /** @type{?proto.google.protobuf.Timestamp} */ (
+    jspb.Message.getWrapperField(this, google_protobuf_timestamp_pb.Timestamp, 1));
+};
+
+
+/**
+ * @param {?proto.google.protobuf.Timestamp|undefined} value
+ * @return {!proto.KillSwitchAuditLogEntry} returns this
+*/
+proto.KillSwitchAuditLogEntry.prototype.setTimestamp = function(value) {
+  return jspb.Message.setWrapperField(this, 1, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.KillSwitchAuditLogEntry} returns this
+ */
+proto.KillSwitchAuditLogEntry.prototype.clearTimestamp = function() {
+  return this.setTimestamp(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.KillSwitchAuditLogEntry.prototype.hasTimestamp = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+/**
+ * optional KillSwitchAuthorizedUser user = 2;
+ * @return {?proto.KillSwitchAuthorizedUser}
+ */
+proto.KillSwitchAuditLogEntry.prototype.getUser = function() {
+  return /** @type{?proto.KillSwitchAuthorizedUser} */ (
+    jspb.Message.getWrapperField(this, proto.KillSwitchAuthorizedUser, 2));
+};
+
+
+/**
+ * @param {?proto.KillSwitchAuthorizedUser|undefined} value
+ * @return {!proto.KillSwitchAuditLogEntry} returns this
+*/
+proto.KillSwitchAuditLogEntry.prototype.setUser = function(value) {
+  return jspb.Message.setWrapperField(this, 2, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.KillSwitchAuditLogEntry} returns this
+ */
+proto.KillSwitchAuditLogEntry.prototype.clearUser = function() {
+  return this.setUser(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.KillSwitchAuditLogEntry.prototype.hasUser = function() {
+  return jspb.Message.getField(this, 2) != null;
+};
+
+
+/**
+ * optional KillSwitchEnabled kill_switch_enabled = 3;
+ * @return {?proto.KillSwitchAuditLogEntry.KillSwitchEnabled}
+ */
+proto.KillSwitchAuditLogEntry.prototype.getKillSwitchEnabled = function() {
+  return /** @type{?proto.KillSwitchAuditLogEntry.KillSwitchEnabled} */ (
+    jspb.Message.getWrapperField(this, proto.KillSwitchAuditLogEntry.KillSwitchEnabled, 3));
+};
+
+
+/**
+ * @param {?proto.KillSwitchAuditLogEntry.KillSwitchEnabled|undefined} value
+ * @return {!proto.KillSwitchAuditLogEntry} returns this
+*/
+proto.KillSwitchAuditLogEntry.prototype.setKillSwitchEnabled = function(value) {
+  return jspb.Message.setOneofWrapperField(this, 3, proto.KillSwitchAuditLogEntry.oneofGroups_[0], value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.KillSwitchAuditLogEntry} returns this
+ */
+proto.KillSwitchAuditLogEntry.prototype.clearKillSwitchEnabled = function() {
+  return this.setKillSwitchEnabled(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.KillSwitchAuditLogEntry.prototype.hasKillSwitchEnabled = function() {
+  return jspb.Message.getField(this, 3) != null;
+};
+
+
+/**
+ * optional KillSwitchDisabled kill_switch_disabled = 4;
+ * @return {?proto.KillSwitchAuditLogEntry.KillSwitchDisabled}
+ */
+proto.KillSwitchAuditLogEntry.prototype.getKillSwitchDisabled = function() {
+  return /** @type{?proto.KillSwitchAuditLogEntry.KillSwitchDisabled} */ (
+    jspb.Message.getWrapperField(this, proto.KillSwitchAuditLogEntry.KillSwitchDisabled, 4));
+};
+
+
+/**
+ * @param {?proto.KillSwitchAuditLogEntry.KillSwitchDisabled|undefined} value
+ * @return {!proto.KillSwitchAuditLogEntry} returns this
+*/
+proto.KillSwitchAuditLogEntry.prototype.setKillSwitchDisabled = function(value) {
+  return jspb.Message.setOneofWrapperField(this, 4, proto.KillSwitchAuditLogEntry.oneofGroups_[0], value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.KillSwitchAuditLogEntry} returns this
+ */
+proto.KillSwitchAuditLogEntry.prototype.clearKillSwitchDisabled = function() {
+  return this.setKillSwitchDisabled(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.KillSwitchAuditLogEntry.prototype.hasKillSwitchDisabled = function() {
+  return jspb.Message.getField(this, 4) != null;
+};
+
+
+/**
+ * optional AuthorizedUserAdded authorized_user_added = 5;
+ * @return {?proto.KillSwitchAuditLogEntry.AuthorizedUserAdded}
+ */
+proto.KillSwitchAuditLogEntry.prototype.getAuthorizedUserAdded = function() {
+  return /** @type{?proto.KillSwitchAuditLogEntry.AuthorizedUserAdded} */ (
+    jspb.Message.getWrapperField(this, proto.KillSwitchAuditLogEntry.AuthorizedUserAdded, 5));
+};
+
+
+/**
+ * @param {?proto.KillSwitchAuditLogEntry.AuthorizedUserAdded|undefined} value
+ * @return {!proto.KillSwitchAuditLogEntry} returns this
+*/
+proto.KillSwitchAuditLogEntry.prototype.setAuthorizedUserAdded = function(value) {
+  return jspb.Message.setOneofWrapperField(this, 5, proto.KillSwitchAuditLogEntry.oneofGroups_[0], value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.KillSwitchAuditLogEntry} returns this
+ */
+proto.KillSwitchAuditLogEntry.prototype.clearAuthorizedUserAdded = function() {
+  return this.setAuthorizedUserAdded(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.KillSwitchAuditLogEntry.prototype.hasAuthorizedUserAdded = function() {
+  return jspb.Message.getField(this, 5) != null;
+};
+
+
+/**
+ * optional AuthorizedUserUpdated authorized_user_updated = 6;
+ * @return {?proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated}
+ */
+proto.KillSwitchAuditLogEntry.prototype.getAuthorizedUserUpdated = function() {
+  return /** @type{?proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated} */ (
+    jspb.Message.getWrapperField(this, proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated, 6));
+};
+
+
+/**
+ * @param {?proto.KillSwitchAuditLogEntry.AuthorizedUserUpdated|undefined} value
+ * @return {!proto.KillSwitchAuditLogEntry} returns this
+*/
+proto.KillSwitchAuditLogEntry.prototype.setAuthorizedUserUpdated = function(value) {
+  return jspb.Message.setOneofWrapperField(this, 6, proto.KillSwitchAuditLogEntry.oneofGroups_[0], value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.KillSwitchAuditLogEntry} returns this
+ */
+proto.KillSwitchAuditLogEntry.prototype.clearAuthorizedUserUpdated = function() {
+  return this.setAuthorizedUserUpdated(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.KillSwitchAuditLogEntry.prototype.hasAuthorizedUserUpdated = function() {
+  return jspb.Message.getField(this, 6) != null;
+};
+
+
+/**
+ * optional AuthorizedUserDeleted authorized_user_deleted = 7;
+ * @return {?proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted}
+ */
+proto.KillSwitchAuditLogEntry.prototype.getAuthorizedUserDeleted = function() {
+  return /** @type{?proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted} */ (
+    jspb.Message.getWrapperField(this, proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted, 7));
+};
+
+
+/**
+ * @param {?proto.KillSwitchAuditLogEntry.AuthorizedUserDeleted|undefined} value
+ * @return {!proto.KillSwitchAuditLogEntry} returns this
+*/
+proto.KillSwitchAuditLogEntry.prototype.setAuthorizedUserDeleted = function(value) {
+  return jspb.Message.setOneofWrapperField(this, 7, proto.KillSwitchAuditLogEntry.oneofGroups_[0], value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.KillSwitchAuditLogEntry} returns this
+ */
+proto.KillSwitchAuditLogEntry.prototype.clearAuthorizedUserDeleted = function() {
+  return this.setAuthorizedUserDeleted(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.KillSwitchAuditLogEntry.prototype.hasAuthorizedUserDeleted = function() {
+  return jspb.Message.getField(this, 7) != null;
+};
+
+
+goog.object.extend(exports, proto);
diff --git a/frontend/src/api_proto/kill_switch_pb.js b/frontend/src/api_proto/kill_switch_pb.js
new file mode 100644
index 0000000..d9f9b6b
--- /dev/null
+++ b/frontend/src/api_proto/kill_switch_pb.js
@@ -0,0 +1,3094 @@
+// source: api_proto/kill_switch.proto
+/**
+ * @fileoverview
+ * @enhanceable
+ * @suppress {missingRequire} reports error on implicit type usages.
+ * @suppress {messageConventions} JS Compiler reports an error if a variable or
+ *     field starts with 'MSG_' and isn't a translatable message.
+ * @public
+ */
+// GENERATED CODE -- DO NOT EDIT!
+/* eslint-disable */
+// @ts-nocheck
+
+var jspb = require('google-protobuf');
+var goog = jspb;
+var global = Function('return this')();
+
+var api_proto_common_pb = require('../api_proto/common_pb.js');
+goog.object.extend(proto, api_proto_common_pb);
+var api_proto_kill_switch_objects_pb = require('../api_proto/kill_switch_objects_pb.js');
+goog.object.extend(proto, api_proto_kill_switch_objects_pb);
+goog.exportSymbol('proto.AddAuthorizedUserRequest', null, global);
+goog.exportSymbol('proto.AddAuthorizedUserResponse', null, global);
+goog.exportSymbol('proto.DeleteAuthorizedUserRequest', null, global);
+goog.exportSymbol('proto.DeleteAuthorizedUserResponse', null, global);
+goog.exportSymbol('proto.DisableKillSwitchRequest', null, global);
+goog.exportSymbol('proto.DisableKillSwitchResponse', null, global);
+goog.exportSymbol('proto.EnableKillSwitchRequest', null, global);
+goog.exportSymbol('proto.EnableKillSwitchResponse', null, global);
+goog.exportSymbol('proto.GetKillSwitchOverviewRequest', null, global);
+goog.exportSymbol('proto.GetKillSwitchOverviewResponse', null, global);
+goog.exportSymbol('proto.GetKillSwitchStatusRequest', null, global);
+goog.exportSymbol('proto.GetKillSwitchStatusResponse', null, global);
+goog.exportSymbol('proto.ListAuthorizedUsersRequest', null, global);
+goog.exportSymbol('proto.ListAuthorizedUsersResponse', null, global);
+goog.exportSymbol('proto.ListFeaturesRequest', null, global);
+goog.exportSymbol('proto.ListFeaturesResponse', null, global);
+goog.exportSymbol('proto.SyncFeaturesRequest', null, global);
+goog.exportSymbol('proto.SyncFeaturesResponse', null, global);
+goog.exportSymbol('proto.UpdateAuthorizedUserRequest', null, global);
+goog.exportSymbol('proto.UpdateAuthorizedUserResponse', null, global);
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.GetKillSwitchStatusRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.GetKillSwitchStatusRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.GetKillSwitchStatusRequest.displayName = 'proto.GetKillSwitchStatusRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.GetKillSwitchStatusResponse = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.GetKillSwitchStatusResponse.repeatedFields_, null);
+};
+goog.inherits(proto.GetKillSwitchStatusResponse, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.GetKillSwitchStatusResponse.displayName = 'proto.GetKillSwitchStatusResponse';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.GetKillSwitchOverviewRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.GetKillSwitchOverviewRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.GetKillSwitchOverviewRequest.displayName = 'proto.GetKillSwitchOverviewRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.GetKillSwitchOverviewResponse = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.GetKillSwitchOverviewResponse.repeatedFields_, null);
+};
+goog.inherits(proto.GetKillSwitchOverviewResponse, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.GetKillSwitchOverviewResponse.displayName = 'proto.GetKillSwitchOverviewResponse';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.ListFeaturesRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.ListFeaturesRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.ListFeaturesRequest.displayName = 'proto.ListFeaturesRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.ListFeaturesResponse = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.ListFeaturesResponse.repeatedFields_, null);
+};
+goog.inherits(proto.ListFeaturesResponse, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.ListFeaturesResponse.displayName = 'proto.ListFeaturesResponse';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.SyncFeaturesRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.SyncFeaturesRequest.repeatedFields_, null);
+};
+goog.inherits(proto.SyncFeaturesRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.SyncFeaturesRequest.displayName = 'proto.SyncFeaturesRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.SyncFeaturesResponse = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.SyncFeaturesResponse, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.SyncFeaturesResponse.displayName = 'proto.SyncFeaturesResponse';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.EnableKillSwitchRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.EnableKillSwitchRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.EnableKillSwitchRequest.displayName = 'proto.EnableKillSwitchRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.EnableKillSwitchResponse = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.EnableKillSwitchResponse, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.EnableKillSwitchResponse.displayName = 'proto.EnableKillSwitchResponse';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.DisableKillSwitchRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.DisableKillSwitchRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.DisableKillSwitchRequest.displayName = 'proto.DisableKillSwitchRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.DisableKillSwitchResponse = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.DisableKillSwitchResponse, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.DisableKillSwitchResponse.displayName = 'proto.DisableKillSwitchResponse';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.ListAuthorizedUsersRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.ListAuthorizedUsersRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.ListAuthorizedUsersRequest.displayName = 'proto.ListAuthorizedUsersRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.ListAuthorizedUsersResponse = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.ListAuthorizedUsersResponse.repeatedFields_, null);
+};
+goog.inherits(proto.ListAuthorizedUsersResponse, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.ListAuthorizedUsersResponse.displayName = 'proto.ListAuthorizedUsersResponse';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.AddAuthorizedUserRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.AddAuthorizedUserRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.AddAuthorizedUserRequest.displayName = 'proto.AddAuthorizedUserRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.AddAuthorizedUserResponse = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.AddAuthorizedUserResponse, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.AddAuthorizedUserResponse.displayName = 'proto.AddAuthorizedUserResponse';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.UpdateAuthorizedUserRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.UpdateAuthorizedUserRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.UpdateAuthorizedUserRequest.displayName = 'proto.UpdateAuthorizedUserRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.UpdateAuthorizedUserResponse = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.UpdateAuthorizedUserResponse, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.UpdateAuthorizedUserResponse.displayName = 'proto.UpdateAuthorizedUserResponse';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.DeleteAuthorizedUserRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.DeleteAuthorizedUserRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.DeleteAuthorizedUserRequest.displayName = 'proto.DeleteAuthorizedUserRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.DeleteAuthorizedUserResponse = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.DeleteAuthorizedUserResponse, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.DeleteAuthorizedUserResponse.displayName = 'proto.DeleteAuthorizedUserResponse';
+}
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.GetKillSwitchStatusRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.GetKillSwitchStatusRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.GetKillSwitchStatusRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.GetKillSwitchStatusRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    environment: (f = msg.getEnvironment()) && api_proto_common_pb.Environment.toObject(includeInstance, f)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.GetKillSwitchStatusRequest}
+ */
+proto.GetKillSwitchStatusRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.GetKillSwitchStatusRequest;
+  return proto.GetKillSwitchStatusRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.GetKillSwitchStatusRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.GetKillSwitchStatusRequest}
+ */
+proto.GetKillSwitchStatusRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new api_proto_common_pb.Environment;
+      reader.readMessage(value,api_proto_common_pb.Environment.deserializeBinaryFromReader);
+      msg.setEnvironment(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.GetKillSwitchStatusRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.GetKillSwitchStatusRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.GetKillSwitchStatusRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.GetKillSwitchStatusRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getEnvironment();
+  if (f != null) {
+    writer.writeMessage(
+      1,
+      f,
+      api_proto_common_pb.Environment.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * optional Environment environment = 1;
+ * @return {?proto.Environment}
+ */
+proto.GetKillSwitchStatusRequest.prototype.getEnvironment = function() {
+  return /** @type{?proto.Environment} */ (
+    jspb.Message.getWrapperField(this, api_proto_common_pb.Environment, 1));
+};
+
+
+/**
+ * @param {?proto.Environment|undefined} value
+ * @return {!proto.GetKillSwitchStatusRequest} returns this
+*/
+proto.GetKillSwitchStatusRequest.prototype.setEnvironment = function(value) {
+  return jspb.Message.setWrapperField(this, 1, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.GetKillSwitchStatusRequest} returns this
+ */
+proto.GetKillSwitchStatusRequest.prototype.clearEnvironment = function() {
+  return this.setEnvironment(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.GetKillSwitchStatusRequest.prototype.hasEnvironment = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.GetKillSwitchStatusResponse.repeatedFields_ = [1];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.GetKillSwitchStatusResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.GetKillSwitchStatusResponse.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.GetKillSwitchStatusResponse} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.GetKillSwitchStatusResponse.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    killSwitchesList: jspb.Message.toObjectList(msg.getKillSwitchesList(),
+    api_proto_kill_switch_objects_pb.KillSwitch.toObject, includeInstance)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.GetKillSwitchStatusResponse}
+ */
+proto.GetKillSwitchStatusResponse.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.GetKillSwitchStatusResponse;
+  return proto.GetKillSwitchStatusResponse.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.GetKillSwitchStatusResponse} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.GetKillSwitchStatusResponse}
+ */
+proto.GetKillSwitchStatusResponse.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new api_proto_kill_switch_objects_pb.KillSwitch;
+      reader.readMessage(value,api_proto_kill_switch_objects_pb.KillSwitch.deserializeBinaryFromReader);
+      msg.addKillSwitches(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.GetKillSwitchStatusResponse.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.GetKillSwitchStatusResponse.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.GetKillSwitchStatusResponse} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.GetKillSwitchStatusResponse.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getKillSwitchesList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      1,
+      f,
+      api_proto_kill_switch_objects_pb.KillSwitch.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * repeated KillSwitch kill_switches = 1;
+ * @return {!Array<!proto.KillSwitch>}
+ */
+proto.GetKillSwitchStatusResponse.prototype.getKillSwitchesList = function() {
+  return /** @type{!Array<!proto.KillSwitch>} */ (
+    jspb.Message.getRepeatedWrapperField(this, api_proto_kill_switch_objects_pb.KillSwitch, 1));
+};
+
+
+/**
+ * @param {!Array<!proto.KillSwitch>} value
+ * @return {!proto.GetKillSwitchStatusResponse} returns this
+*/
+proto.GetKillSwitchStatusResponse.prototype.setKillSwitchesList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 1, value);
+};
+
+
+/**
+ * @param {!proto.KillSwitch=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.KillSwitch}
+ */
+proto.GetKillSwitchStatusResponse.prototype.addKillSwitches = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 1, opt_value, proto.KillSwitch, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.GetKillSwitchStatusResponse} returns this
+ */
+proto.GetKillSwitchStatusResponse.prototype.clearKillSwitchesList = function() {
+  return this.setKillSwitchesList([]);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.GetKillSwitchOverviewRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.GetKillSwitchOverviewRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.GetKillSwitchOverviewRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.GetKillSwitchOverviewRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.GetKillSwitchOverviewRequest}
+ */
+proto.GetKillSwitchOverviewRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.GetKillSwitchOverviewRequest;
+  return proto.GetKillSwitchOverviewRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.GetKillSwitchOverviewRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.GetKillSwitchOverviewRequest}
+ */
+proto.GetKillSwitchOverviewRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.GetKillSwitchOverviewRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.GetKillSwitchOverviewRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.GetKillSwitchOverviewRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.GetKillSwitchOverviewRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.GetKillSwitchOverviewResponse.repeatedFields_ = [1];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.GetKillSwitchOverviewResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.GetKillSwitchOverviewResponse.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.GetKillSwitchOverviewResponse} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.GetKillSwitchOverviewResponse.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    killSwitchesList: jspb.Message.toObjectList(msg.getKillSwitchesList(),
+    api_proto_kill_switch_objects_pb.KillSwitch.toObject, includeInstance)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.GetKillSwitchOverviewResponse}
+ */
+proto.GetKillSwitchOverviewResponse.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.GetKillSwitchOverviewResponse;
+  return proto.GetKillSwitchOverviewResponse.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.GetKillSwitchOverviewResponse} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.GetKillSwitchOverviewResponse}
+ */
+proto.GetKillSwitchOverviewResponse.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new api_proto_kill_switch_objects_pb.KillSwitch;
+      reader.readMessage(value,api_proto_kill_switch_objects_pb.KillSwitch.deserializeBinaryFromReader);
+      msg.addKillSwitches(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.GetKillSwitchOverviewResponse.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.GetKillSwitchOverviewResponse.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.GetKillSwitchOverviewResponse} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.GetKillSwitchOverviewResponse.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getKillSwitchesList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      1,
+      f,
+      api_proto_kill_switch_objects_pb.KillSwitch.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * repeated KillSwitch kill_switches = 1;
+ * @return {!Array<!proto.KillSwitch>}
+ */
+proto.GetKillSwitchOverviewResponse.prototype.getKillSwitchesList = function() {
+  return /** @type{!Array<!proto.KillSwitch>} */ (
+    jspb.Message.getRepeatedWrapperField(this, api_proto_kill_switch_objects_pb.KillSwitch, 1));
+};
+
+
+/**
+ * @param {!Array<!proto.KillSwitch>} value
+ * @return {!proto.GetKillSwitchOverviewResponse} returns this
+*/
+proto.GetKillSwitchOverviewResponse.prototype.setKillSwitchesList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 1, value);
+};
+
+
+/**
+ * @param {!proto.KillSwitch=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.KillSwitch}
+ */
+proto.GetKillSwitchOverviewResponse.prototype.addKillSwitches = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 1, opt_value, proto.KillSwitch, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.GetKillSwitchOverviewResponse} returns this
+ */
+proto.GetKillSwitchOverviewResponse.prototype.clearKillSwitchesList = function() {
+  return this.setKillSwitchesList([]);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.ListFeaturesRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.ListFeaturesRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.ListFeaturesRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.ListFeaturesRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    withDeprecatedFeatures: jspb.Message.getBooleanFieldWithDefault(msg, 1, false)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.ListFeaturesRequest}
+ */
+proto.ListFeaturesRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.ListFeaturesRequest;
+  return proto.ListFeaturesRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.ListFeaturesRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.ListFeaturesRequest}
+ */
+proto.ListFeaturesRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setWithDeprecatedFeatures(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.ListFeaturesRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.ListFeaturesRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.ListFeaturesRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.ListFeaturesRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getWithDeprecatedFeatures();
+  if (f) {
+    writer.writeBool(
+      1,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional bool with_deprecated_features = 1;
+ * @return {boolean}
+ */
+proto.ListFeaturesRequest.prototype.getWithDeprecatedFeatures = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 1, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.ListFeaturesRequest} returns this
+ */
+proto.ListFeaturesRequest.prototype.setWithDeprecatedFeatures = function(value) {
+  return jspb.Message.setProto3BooleanField(this, 1, value);
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.ListFeaturesResponse.repeatedFields_ = [1];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.ListFeaturesResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.ListFeaturesResponse.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.ListFeaturesResponse} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.ListFeaturesResponse.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    featuresList: jspb.Message.toObjectList(msg.getFeaturesList(),
+    api_proto_kill_switch_objects_pb.Feature.toObject, includeInstance)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.ListFeaturesResponse}
+ */
+proto.ListFeaturesResponse.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.ListFeaturesResponse;
+  return proto.ListFeaturesResponse.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.ListFeaturesResponse} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.ListFeaturesResponse}
+ */
+proto.ListFeaturesResponse.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new api_proto_kill_switch_objects_pb.Feature;
+      reader.readMessage(value,api_proto_kill_switch_objects_pb.Feature.deserializeBinaryFromReader);
+      msg.addFeatures(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.ListFeaturesResponse.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.ListFeaturesResponse.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.ListFeaturesResponse} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.ListFeaturesResponse.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getFeaturesList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      1,
+      f,
+      api_proto_kill_switch_objects_pb.Feature.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * repeated Feature features = 1;
+ * @return {!Array<!proto.Feature>}
+ */
+proto.ListFeaturesResponse.prototype.getFeaturesList = function() {
+  return /** @type{!Array<!proto.Feature>} */ (
+    jspb.Message.getRepeatedWrapperField(this, api_proto_kill_switch_objects_pb.Feature, 1));
+};
+
+
+/**
+ * @param {!Array<!proto.Feature>} value
+ * @return {!proto.ListFeaturesResponse} returns this
+*/
+proto.ListFeaturesResponse.prototype.setFeaturesList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 1, value);
+};
+
+
+/**
+ * @param {!proto.Feature=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.Feature}
+ */
+proto.ListFeaturesResponse.prototype.addFeatures = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 1, opt_value, proto.Feature, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.ListFeaturesResponse} returns this
+ */
+proto.ListFeaturesResponse.prototype.clearFeaturesList = function() {
+  return this.setFeaturesList([]);
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.SyncFeaturesRequest.repeatedFields_ = [1];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.SyncFeaturesRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.SyncFeaturesRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.SyncFeaturesRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.SyncFeaturesRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    featuresList: jspb.Message.toObjectList(msg.getFeaturesList(),
+    api_proto_kill_switch_objects_pb.Feature.toObject, includeInstance)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.SyncFeaturesRequest}
+ */
+proto.SyncFeaturesRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.SyncFeaturesRequest;
+  return proto.SyncFeaturesRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.SyncFeaturesRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.SyncFeaturesRequest}
+ */
+proto.SyncFeaturesRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new api_proto_kill_switch_objects_pb.Feature;
+      reader.readMessage(value,api_proto_kill_switch_objects_pb.Feature.deserializeBinaryFromReader);
+      msg.addFeatures(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.SyncFeaturesRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.SyncFeaturesRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.SyncFeaturesRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.SyncFeaturesRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getFeaturesList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      1,
+      f,
+      api_proto_kill_switch_objects_pb.Feature.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * repeated Feature features = 1;
+ * @return {!Array<!proto.Feature>}
+ */
+proto.SyncFeaturesRequest.prototype.getFeaturesList = function() {
+  return /** @type{!Array<!proto.Feature>} */ (
+    jspb.Message.getRepeatedWrapperField(this, api_proto_kill_switch_objects_pb.Feature, 1));
+};
+
+
+/**
+ * @param {!Array<!proto.Feature>} value
+ * @return {!proto.SyncFeaturesRequest} returns this
+*/
+proto.SyncFeaturesRequest.prototype.setFeaturesList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 1, value);
+};
+
+
+/**
+ * @param {!proto.Feature=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.Feature}
+ */
+proto.SyncFeaturesRequest.prototype.addFeatures = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 1, opt_value, proto.Feature, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.SyncFeaturesRequest} returns this
+ */
+proto.SyncFeaturesRequest.prototype.clearFeaturesList = function() {
+  return this.setFeaturesList([]);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.SyncFeaturesResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.SyncFeaturesResponse.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.SyncFeaturesResponse} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.SyncFeaturesResponse.toObject = function(includeInstance, msg) {
+  var f, obj = {
+
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.SyncFeaturesResponse}
+ */
+proto.SyncFeaturesResponse.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.SyncFeaturesResponse;
+  return proto.SyncFeaturesResponse.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.SyncFeaturesResponse} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.SyncFeaturesResponse}
+ */
+proto.SyncFeaturesResponse.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.SyncFeaturesResponse.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.SyncFeaturesResponse.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.SyncFeaturesResponse} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.SyncFeaturesResponse.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.EnableKillSwitchRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.EnableKillSwitchRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.EnableKillSwitchRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.EnableKillSwitchRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    killSwitch: (f = msg.getKillSwitch()) && api_proto_kill_switch_objects_pb.KillSwitch.toObject(includeInstance, f)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.EnableKillSwitchRequest}
+ */
+proto.EnableKillSwitchRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.EnableKillSwitchRequest;
+  return proto.EnableKillSwitchRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.EnableKillSwitchRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.EnableKillSwitchRequest}
+ */
+proto.EnableKillSwitchRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new api_proto_kill_switch_objects_pb.KillSwitch;
+      reader.readMessage(value,api_proto_kill_switch_objects_pb.KillSwitch.deserializeBinaryFromReader);
+      msg.setKillSwitch(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.EnableKillSwitchRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.EnableKillSwitchRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.EnableKillSwitchRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.EnableKillSwitchRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getKillSwitch();
+  if (f != null) {
+    writer.writeMessage(
+      1,
+      f,
+      api_proto_kill_switch_objects_pb.KillSwitch.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * optional KillSwitch kill_switch = 1;
+ * @return {?proto.KillSwitch}
+ */
+proto.EnableKillSwitchRequest.prototype.getKillSwitch = function() {
+  return /** @type{?proto.KillSwitch} */ (
+    jspb.Message.getWrapperField(this, api_proto_kill_switch_objects_pb.KillSwitch, 1));
+};
+
+
+/**
+ * @param {?proto.KillSwitch|undefined} value
+ * @return {!proto.EnableKillSwitchRequest} returns this
+*/
+proto.EnableKillSwitchRequest.prototype.setKillSwitch = function(value) {
+  return jspb.Message.setWrapperField(this, 1, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.EnableKillSwitchRequest} returns this
+ */
+proto.EnableKillSwitchRequest.prototype.clearKillSwitch = function() {
+  return this.setKillSwitch(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.EnableKillSwitchRequest.prototype.hasKillSwitch = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.EnableKillSwitchResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.EnableKillSwitchResponse.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.EnableKillSwitchResponse} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.EnableKillSwitchResponse.toObject = function(includeInstance, msg) {
+  var f, obj = {
+
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.EnableKillSwitchResponse}
+ */
+proto.EnableKillSwitchResponse.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.EnableKillSwitchResponse;
+  return proto.EnableKillSwitchResponse.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.EnableKillSwitchResponse} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.EnableKillSwitchResponse}
+ */
+proto.EnableKillSwitchResponse.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.EnableKillSwitchResponse.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.EnableKillSwitchResponse.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.EnableKillSwitchResponse} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.EnableKillSwitchResponse.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.DisableKillSwitchRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.DisableKillSwitchRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.DisableKillSwitchRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.DisableKillSwitchRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    killSwitchId: jspb.Message.getFieldWithDefault(msg, 1, 0)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.DisableKillSwitchRequest}
+ */
+proto.DisableKillSwitchRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.DisableKillSwitchRequest;
+  return proto.DisableKillSwitchRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.DisableKillSwitchRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.DisableKillSwitchRequest}
+ */
+proto.DisableKillSwitchRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt32());
+      msg.setKillSwitchId(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.DisableKillSwitchRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.DisableKillSwitchRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.DisableKillSwitchRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.DisableKillSwitchRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getKillSwitchId();
+  if (f !== 0) {
+    writer.writeInt32(
+      1,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional int32 kill_switch_id = 1;
+ * @return {number}
+ */
+proto.DisableKillSwitchRequest.prototype.getKillSwitchId = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.DisableKillSwitchRequest} returns this
+ */
+proto.DisableKillSwitchRequest.prototype.setKillSwitchId = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.DisableKillSwitchResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.DisableKillSwitchResponse.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.DisableKillSwitchResponse} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.DisableKillSwitchResponse.toObject = function(includeInstance, msg) {
+  var f, obj = {
+
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.DisableKillSwitchResponse}
+ */
+proto.DisableKillSwitchResponse.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.DisableKillSwitchResponse;
+  return proto.DisableKillSwitchResponse.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.DisableKillSwitchResponse} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.DisableKillSwitchResponse}
+ */
+proto.DisableKillSwitchResponse.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.DisableKillSwitchResponse.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.DisableKillSwitchResponse.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.DisableKillSwitchResponse} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.DisableKillSwitchResponse.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.ListAuthorizedUsersRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.ListAuthorizedUsersRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.ListAuthorizedUsersRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.ListAuthorizedUsersRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.ListAuthorizedUsersRequest}
+ */
+proto.ListAuthorizedUsersRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.ListAuthorizedUsersRequest;
+  return proto.ListAuthorizedUsersRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.ListAuthorizedUsersRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.ListAuthorizedUsersRequest}
+ */
+proto.ListAuthorizedUsersRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.ListAuthorizedUsersRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.ListAuthorizedUsersRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.ListAuthorizedUsersRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.ListAuthorizedUsersRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.ListAuthorizedUsersResponse.repeatedFields_ = [1];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.ListAuthorizedUsersResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.ListAuthorizedUsersResponse.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.ListAuthorizedUsersResponse} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.ListAuthorizedUsersResponse.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    usersList: jspb.Message.toObjectList(msg.getUsersList(),
+    api_proto_kill_switch_objects_pb.KillSwitchAuthorizedUser.toObject, includeInstance)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.ListAuthorizedUsersResponse}
+ */
+proto.ListAuthorizedUsersResponse.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.ListAuthorizedUsersResponse;
+  return proto.ListAuthorizedUsersResponse.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.ListAuthorizedUsersResponse} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.ListAuthorizedUsersResponse}
+ */
+proto.ListAuthorizedUsersResponse.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new api_proto_kill_switch_objects_pb.KillSwitchAuthorizedUser;
+      reader.readMessage(value,api_proto_kill_switch_objects_pb.KillSwitchAuthorizedUser.deserializeBinaryFromReader);
+      msg.addUsers(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.ListAuthorizedUsersResponse.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.ListAuthorizedUsersResponse.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.ListAuthorizedUsersResponse} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.ListAuthorizedUsersResponse.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getUsersList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      1,
+      f,
+      api_proto_kill_switch_objects_pb.KillSwitchAuthorizedUser.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * repeated KillSwitchAuthorizedUser users = 1;
+ * @return {!Array<!proto.KillSwitchAuthorizedUser>}
+ */
+proto.ListAuthorizedUsersResponse.prototype.getUsersList = function() {
+  return /** @type{!Array<!proto.KillSwitchAuthorizedUser>} */ (
+    jspb.Message.getRepeatedWrapperField(this, api_proto_kill_switch_objects_pb.KillSwitchAuthorizedUser, 1));
+};
+
+
+/**
+ * @param {!Array<!proto.KillSwitchAuthorizedUser>} value
+ * @return {!proto.ListAuthorizedUsersResponse} returns this
+*/
+proto.ListAuthorizedUsersResponse.prototype.setUsersList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 1, value);
+};
+
+
+/**
+ * @param {!proto.KillSwitchAuthorizedUser=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.KillSwitchAuthorizedUser}
+ */
+proto.ListAuthorizedUsersResponse.prototype.addUsers = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 1, opt_value, proto.KillSwitchAuthorizedUser, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.ListAuthorizedUsersResponse} returns this
+ */
+proto.ListAuthorizedUsersResponse.prototype.clearUsersList = function() {
+  return this.setUsersList([]);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.AddAuthorizedUserRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.AddAuthorizedUserRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.AddAuthorizedUserRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.AddAuthorizedUserRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    user: (f = msg.getUser()) && api_proto_kill_switch_objects_pb.KillSwitchAuthorizedUser.toObject(includeInstance, f)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.AddAuthorizedUserRequest}
+ */
+proto.AddAuthorizedUserRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.AddAuthorizedUserRequest;
+  return proto.AddAuthorizedUserRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.AddAuthorizedUserRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.AddAuthorizedUserRequest}
+ */
+proto.AddAuthorizedUserRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new api_proto_kill_switch_objects_pb.KillSwitchAuthorizedUser;
+      reader.readMessage(value,api_proto_kill_switch_objects_pb.KillSwitchAuthorizedUser.deserializeBinaryFromReader);
+      msg.setUser(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.AddAuthorizedUserRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.AddAuthorizedUserRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.AddAuthorizedUserRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.AddAuthorizedUserRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getUser();
+  if (f != null) {
+    writer.writeMessage(
+      1,
+      f,
+      api_proto_kill_switch_objects_pb.KillSwitchAuthorizedUser.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * optional KillSwitchAuthorizedUser user = 1;
+ * @return {?proto.KillSwitchAuthorizedUser}
+ */
+proto.AddAuthorizedUserRequest.prototype.getUser = function() {
+  return /** @type{?proto.KillSwitchAuthorizedUser} */ (
+    jspb.Message.getWrapperField(this, api_proto_kill_switch_objects_pb.KillSwitchAuthorizedUser, 1));
+};
+
+
+/**
+ * @param {?proto.KillSwitchAuthorizedUser|undefined} value
+ * @return {!proto.AddAuthorizedUserRequest} returns this
+*/
+proto.AddAuthorizedUserRequest.prototype.setUser = function(value) {
+  return jspb.Message.setWrapperField(this, 1, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.AddAuthorizedUserRequest} returns this
+ */
+proto.AddAuthorizedUserRequest.prototype.clearUser = function() {
+  return this.setUser(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.AddAuthorizedUserRequest.prototype.hasUser = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.AddAuthorizedUserResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.AddAuthorizedUserResponse.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.AddAuthorizedUserResponse} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.AddAuthorizedUserResponse.toObject = function(includeInstance, msg) {
+  var f, obj = {
+
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.AddAuthorizedUserResponse}
+ */
+proto.AddAuthorizedUserResponse.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.AddAuthorizedUserResponse;
+  return proto.AddAuthorizedUserResponse.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.AddAuthorizedUserResponse} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.AddAuthorizedUserResponse}
+ */
+proto.AddAuthorizedUserResponse.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.AddAuthorizedUserResponse.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.AddAuthorizedUserResponse.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.AddAuthorizedUserResponse} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.AddAuthorizedUserResponse.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.UpdateAuthorizedUserRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.UpdateAuthorizedUserRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.UpdateAuthorizedUserRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.UpdateAuthorizedUserRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    userId: jspb.Message.getFieldWithDefault(msg, 1, 0),
+    user: (f = msg.getUser()) && api_proto_kill_switch_objects_pb.KillSwitchAuthorizedUser.toObject(includeInstance, f)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.UpdateAuthorizedUserRequest}
+ */
+proto.UpdateAuthorizedUserRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.UpdateAuthorizedUserRequest;
+  return proto.UpdateAuthorizedUserRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.UpdateAuthorizedUserRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.UpdateAuthorizedUserRequest}
+ */
+proto.UpdateAuthorizedUserRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt32());
+      msg.setUserId(value);
+      break;
+    case 2:
+      var value = new api_proto_kill_switch_objects_pb.KillSwitchAuthorizedUser;
+      reader.readMessage(value,api_proto_kill_switch_objects_pb.KillSwitchAuthorizedUser.deserializeBinaryFromReader);
+      msg.setUser(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.UpdateAuthorizedUserRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.UpdateAuthorizedUserRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.UpdateAuthorizedUserRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.UpdateAuthorizedUserRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getUserId();
+  if (f !== 0) {
+    writer.writeInt32(
+      1,
+      f
+    );
+  }
+  f = message.getUser();
+  if (f != null) {
+    writer.writeMessage(
+      2,
+      f,
+      api_proto_kill_switch_objects_pb.KillSwitchAuthorizedUser.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * optional int32 user_id = 1;
+ * @return {number}
+ */
+proto.UpdateAuthorizedUserRequest.prototype.getUserId = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.UpdateAuthorizedUserRequest} returns this
+ */
+proto.UpdateAuthorizedUserRequest.prototype.setUserId = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+/**
+ * optional KillSwitchAuthorizedUser user = 2;
+ * @return {?proto.KillSwitchAuthorizedUser}
+ */
+proto.UpdateAuthorizedUserRequest.prototype.getUser = function() {
+  return /** @type{?proto.KillSwitchAuthorizedUser} */ (
+    jspb.Message.getWrapperField(this, api_proto_kill_switch_objects_pb.KillSwitchAuthorizedUser, 2));
+};
+
+
+/**
+ * @param {?proto.KillSwitchAuthorizedUser|undefined} value
+ * @return {!proto.UpdateAuthorizedUserRequest} returns this
+*/
+proto.UpdateAuthorizedUserRequest.prototype.setUser = function(value) {
+  return jspb.Message.setWrapperField(this, 2, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.UpdateAuthorizedUserRequest} returns this
+ */
+proto.UpdateAuthorizedUserRequest.prototype.clearUser = function() {
+  return this.setUser(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.UpdateAuthorizedUserRequest.prototype.hasUser = function() {
+  return jspb.Message.getField(this, 2) != null;
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.UpdateAuthorizedUserResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.UpdateAuthorizedUserResponse.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.UpdateAuthorizedUserResponse} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.UpdateAuthorizedUserResponse.toObject = function(includeInstance, msg) {
+  var f, obj = {
+
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.UpdateAuthorizedUserResponse}
+ */
+proto.UpdateAuthorizedUserResponse.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.UpdateAuthorizedUserResponse;
+  return proto.UpdateAuthorizedUserResponse.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.UpdateAuthorizedUserResponse} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.UpdateAuthorizedUserResponse}
+ */
+proto.UpdateAuthorizedUserResponse.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.UpdateAuthorizedUserResponse.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.UpdateAuthorizedUserResponse.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.UpdateAuthorizedUserResponse} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.UpdateAuthorizedUserResponse.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.DeleteAuthorizedUserRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.DeleteAuthorizedUserRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.DeleteAuthorizedUserRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.DeleteAuthorizedUserRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    userId: jspb.Message.getFieldWithDefault(msg, 1, 0)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.DeleteAuthorizedUserRequest}
+ */
+proto.DeleteAuthorizedUserRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.DeleteAuthorizedUserRequest;
+  return proto.DeleteAuthorizedUserRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.DeleteAuthorizedUserRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.DeleteAuthorizedUserRequest}
+ */
+proto.DeleteAuthorizedUserRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt32());
+      msg.setUserId(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.DeleteAuthorizedUserRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.DeleteAuthorizedUserRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.DeleteAuthorizedUserRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.DeleteAuthorizedUserRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getUserId();
+  if (f !== 0) {
+    writer.writeInt32(
+      1,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional int32 user_id = 1;
+ * @return {number}
+ */
+proto.DeleteAuthorizedUserRequest.prototype.getUserId = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.DeleteAuthorizedUserRequest} returns this
+ */
+proto.DeleteAuthorizedUserRequest.prototype.setUserId = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.DeleteAuthorizedUserResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.DeleteAuthorizedUserResponse.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.DeleteAuthorizedUserResponse} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.DeleteAuthorizedUserResponse.toObject = function(includeInstance, msg) {
+  var f, obj = {
+
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.DeleteAuthorizedUserResponse}
+ */
+proto.DeleteAuthorizedUserResponse.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.DeleteAuthorizedUserResponse;
+  return proto.DeleteAuthorizedUserResponse.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.DeleteAuthorizedUserResponse} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.DeleteAuthorizedUserResponse}
+ */
+proto.DeleteAuthorizedUserResponse.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.DeleteAuthorizedUserResponse.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.DeleteAuthorizedUserResponse.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.DeleteAuthorizedUserResponse} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.DeleteAuthorizedUserResponse.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+};
+
+
+goog.object.extend(exports, proto);
diff --git a/frontend/src/components/AuthorizedUserDialog.vue b/frontend/src/components/AuthorizedUserDialog.vue
new file mode 100644
index 0000000..4f68e1a
--- /dev/null
+++ b/frontend/src/components/AuthorizedUserDialog.vue
@@ -0,0 +1,121 @@
+<script>
+import {accessLevels} from '../consts.js';
+import * as ksObjectsPb from '../api_proto/kill_switch_objects_pb.js';
+import * as ksPb from '../api_proto/kill_switch_pb.js';
+
+export default {
+  props: {
+    modelValue: Boolean, // If the dialog is open
+    isUpdate: Boolean,
+    user: {
+      type: Object,
+      default: function() {
+        return new ksObjectsPb.KillSwitchAuthorizedUser()
+      },
+    },
+  },
+  emits: [
+    'update:modelValue',
+    'userAdded',
+    'userUpdated',
+  ],
+  data() {
+    return {
+      accessLevels,
+      userM: this.user.cloneMessage(), // User mutable
+    };
+  },
+  watch: {
+    user(newUser, oldUser) {
+      this.$data.userM = this.user.cloneMessage();
+    }
+  },
+  computed: {
+    accessLevel: {
+      get() {
+        return this.$data.userM.getAccessLevel().toString();
+      },
+      set(level) {
+        this.$data.userM.setAccessLevel(parseInt(level));
+      },
+    },
+    googleUid: {
+      get() {
+        return this.$data.userM.getGoogleUid();
+      },
+      set(uid) {
+        this.$data.userM.setGoogleUid(uid);
+      },
+    },
+    email: {
+      get() {
+        return this.$data.userM.getEmail();
+      },
+      set(email) {
+        this.$data.userM.setEmail(email);
+      },
+    },
+  },
+  methods: {
+    onSubmit() {
+      if (this.isUpdate)
+        this.doUpdate();
+      else
+        this.doAdd();
+    },
+    doUpdate() {
+      let request = new ksPb.UpdateAuthorizedUserRequest();
+      request.setUserId(this.userM.getId());
+      request.setUser(this.userM);
+
+      this.$store.state.client.updateAuthorizedUser(
+        request, {authorization: this.$store.state.jwtToken})
+          .then(res => {
+            this.$emit('userUpdated');
+          })
+          .catch(err => console.error(err));
+    },
+    doAdd() {
+      let request = new ksPb.AddAuthorizedUserRequest();
+      request.setUser(this.userM);
+
+      this.$store.state.client.addAuthorizedUser(
+        request, {authorization: this.$store.state.jwtToken})
+          .then(res => {
+            this.$emit('userAdded');
+            this.$data.userM = this.user.cloneMessage();
+          })
+          .catch(err => console.error(err));
+    },
+    onCancel() {
+      this.$data.userM = this.user.cloneMessage();
+    },
+  },
+};
+</script>
+
+<template>
+  <mcw-dialog
+      v-model="modelValue"
+      @update:modelValue="$emit('update:modelValue', $event)"
+      escape-key-action="close"
+      scrim-click-action="close"
+      :auto-stack-buttons="true">
+    <mcw-dialog-title>{{ isUpdate ? 'Update user ' + userM.getId() : 'Add new user' }}</mcw-dialog-title>
+    <mcw-dialog-content>
+      <div>
+        <p><mcw-select v-model="accessLevel" label="Access level" required>
+          <mcw-list-item v-for="(al, i) in accessLevels" :data-value="i" role="option">
+            {{ al }}
+          </mcw-list-item>
+        </mcw-select></p>
+        <p><mcw-textfield v-model="googleUid" label="Google UID" /></p>
+        <p><mcw-textfield v-model="email" type="email" label="E-mail address" /></p>
+      </div>
+    </mcw-dialog-content>
+    <mcw-dialog-footer>
+      <mcw-dialog-button @click="onCancel" action="dismiss">Cancel</mcw-dialog-button>
+      <mcw-dialog-button @click="onSubmit" action="accept">{{ isUpdate ? 'Update' : 'Add' }}</mcw-dialog-button>
+    </mcw-dialog-footer>
+  </mcw-dialog>
+</template>
diff --git a/frontend/src/config.json5 b/frontend/src/config.json5
new file mode 100644
index 0000000..07bff27
--- /dev/null
+++ b/frontend/src/config.json5
@@ -0,0 +1,8 @@
+{
+  // Details for the Sign In with Google functionality
+  google: {
+    clientId: '223047594100-ha7istt4csc0mlq11heogk7bqvmpbqo0.apps.googleusercontent.com',
+  },
+  // URL of the GRPC host
+  grpcWebHost: 'http://localhost:8081'
+}
diff --git a/frontend/src/consts.js b/frontend/src/consts.js
new file mode 100644
index 0000000..e570b66
--- /dev/null
+++ b/frontend/src/consts.js
@@ -0,0 +1,5 @@
+export const accessLevels = Object.freeze({
+  0: "None",
+  5: "Kill Switch Activator",
+  10: "Admin",
+});
diff --git a/frontend/src/main.js b/frontend/src/main.js
new file mode 100644
index 0000000..54f944d
--- /dev/null
+++ b/frontend/src/main.js
@@ -0,0 +1,38 @@
+import './theme.scss';
+
+import {createApp} from 'vue';
+import * as VueRouter from 'vue-router';
+
+import App from './App.vue';
+import AuthorizedUsers from './pages/AuthorizedUsers.vue';
+import Home from './pages/Home.vue';
+import KillSwitches from './pages/KillSwitches.vue';
+import {store} from './store/index.js';
+import VueMaterialAdapter from './vma.js';
+
+const routes = [
+  {
+    path: '/',
+    component: Home,
+    meta: {title: 'Home'},
+  },
+  {
+    path: '/kill-switches',
+    component: KillSwitches,
+    meta: {title: 'Kill Switches'},
+  },
+  {
+    path: '/authorized-users',
+    component: AuthorizedUsers,
+    meta: {title: 'Authorized Users'},
+  },
+];
+
+const router =
+    VueRouter.createRouter({history: VueRouter.createWebHashHistory(), routes});
+
+const app = createApp(App);
+app.use(store);
+app.use(router);
+app.use(VueMaterialAdapter);
+app.mount('app');
diff --git a/frontend/src/pages/AuthorizedUsers.vue b/frontend/src/pages/AuthorizedUsers.vue
new file mode 100644
index 0000000..2f2b326
--- /dev/null
+++ b/frontend/src/pages/AuthorizedUsers.vue
@@ -0,0 +1,170 @@
+<script>
+import NotAuthorized from './NotAuthorized.vue';
+import Page from './utils/Page.vue';
+import AuthorizedUserDialog from '../components/AuthorizedUserDialog.vue';
+
+//import * as grpcWeb from "grpc-web";
+import * as ksObjectsPb from '../api_proto/kill_switch_objects_pb.js';
+import * as ksPb from '../api_proto/kill_switch_pb.js';
+import {accessLevels} from '../consts.js';
+
+export default {
+  data() {
+    let emptyUser = new ksObjectsPb.KillSwitchAuthorizedUser();
+
+    return {
+      users: [],
+      currentUpdateUser: emptyUser, // Current user being updated
+      currentDeleteUser: emptyUser, // Current user being confirmed deletion
+      addDialogOpen: false,
+      updateDialogOpen: false,
+      deleteDialogOpen: false,
+      accessLevels,
+    };
+  },
+  components: {
+    NotAuthorized,
+    Page,
+    AuthorizedUserDialog,
+  },
+  mounted() {
+    this.loadData();
+  },
+  methods: {
+    loadData() {
+      if (!this.isSignedIn) return;
+
+      let request = new ksPb.ListAuthorizedUsersRequest();
+
+      this.$store.state.client.listAuthorizedUsers(
+          request, {authorization: this.$store.state.jwtToken})
+          .then(res => {
+            this.$data.users = res.getUsersList();
+          })
+          .catch(err => console.error(err));
+    },
+    showAddForm(user) {
+      this.$data.addDialogOpen = true;
+    },
+    showUpdateForm(user) {
+      this.currentUpdateUser = user;
+      this.$data.updateDialogOpen = true;
+    },
+    showDeleteDialog(user) {
+      this.$data.currentDeleteUser = user;
+      this.$data.deleteDialogOpen = true;
+    },
+    deleteUser(user) {
+      let request = new ksPb.DeleteAuthorizedUserRequest();
+      request.setUserId(user.getId());
+
+      this.$store.state.client.deleteAuthorizedUser(
+          request, {authorization: this.$store.state.jwtToken})
+          .then(res => {
+            this.loadData();
+          })
+          .catch(err => console.error(err));
+    },
+  },
+  computed: {
+    isSignedIn() {
+      return this.$store.state.jwtToken != null;
+    },
+  },
+};
+</script>
+
+<template>
+  <template v-if="isSignedIn">
+    <div class="container">
+      <mcw-data-table>
+        <table class="mdc-data-table__table" aria-label="Authorized users">
+          <thead>
+            <tr class="mdc-data-table__header-row">
+              <th
+                  class="mdc-data-table__header-cell"
+                  role="columnheader"
+                  scope="col">
+                ID
+              </th>
+              <th
+                  class="mdc-data-table__header-cell"
+                  role="columnheader"
+                  scope="col">
+                Google UID
+              </th>
+              <th
+                  class="mdc-data-table__header-cell"
+                  role="columnheader"
+                  scope="col">
+                E-mail address
+              </th>
+              <th
+                  class="mdc-data-table__header-cell"
+                  role="columnheader"
+                  scope="col">
+                Scope
+              </th>
+              <th
+                  class="mdc-data-table__header-cell"
+                  role="columnheader"
+                  scope="col">
+              </th>
+            </tr>
+          </thead>
+          <tbody class="mdc-data-table__content">
+            <tr class="mdc-data-table__row" v-for="user in users">
+              <td class="mdc-data-table__cell mdc-data-table__cell--numeric">{{ user.getId() }}</td>
+              <td class="mdc-data-table__cell">{{ user.getGoogleUid() || "-" }}</td>
+              <td class="mdc-data-table__cell">{{ user.getEmail() || "-" }}</td>
+              <td class="mdc-data-table__cell">{{ accessLevels[user.getAccessLevel()] }}</td>
+              <td class="mdc-data-table__cell">
+                <mcw-icon-button @click="(showUpdateForm(user))"><mcw-material-icon icon="edit" /></mcw-icon-button>
+                <mcw-icon-button @click="(showDeleteDialog(user))"><mcw-material-icon icon="delete" /></mcw-icon-button>
+              </td>
+            </tr>
+          </tbody>
+        </table>
+      </mcw-data-table>
+    </div>
+    <mcw-fab @click="showAddForm()" class="add-user" icon="add" />
+    <mcw-dialog
+        v-model="deleteDialogOpen"
+        escape-key-action="close"
+        scrim-click-action="close"
+        aria-labelledby="delete-title"
+        aria-describedby="delete-content"
+        :auto-stack-buttons="true">
+      <mcw-dialog-title id="delete-title">Delete authorized user?</mcw-dialog-title>
+      <mcw-dialog-content id="delete-content">
+        <div>User {{ currentDeleteUser.getId() }} will no longer have access to the TW Power Tools dashboard.</div>
+      </mcw-dialog-content>
+      <mcw-dialog-footer>
+        <mcw-dialog-button action="dismiss">Cancel</mcw-dialog-button>
+        <mcw-dialog-button @click="deleteUser(currentDeleteUser)" action="accept">Delete</mcw-dialog-button>
+      </mcw-dialog-footer>
+    </mcw-dialog>
+    <!-- Add user dialog -->
+    <authorized-user-dialog @user-added="loadData()" v-model="addDialogOpen" />
+    <!-- Update user dialog -->
+    <authorized-user-dialog @user-updated="loadData()" v-model="updateDialogOpen" is-update :user="currentUpdateUser" />
+  </template>
+  <template v-else>
+    <not-authorized>
+    </not-authorized>
+  </template>
+</template>
+
+<style scoped>
+.container {
+  margin-top: 16px;
+  display: flex;
+  justify-content: space-evenly;
+}
+
+.add-user {
+  position: fixed;
+  right: 16px;
+  bottom: 16px;
+}
+</style>
diff --git a/frontend/src/pages/Home.vue b/frontend/src/pages/Home.vue
new file mode 100644
index 0000000..da5ff77
--- /dev/null
+++ b/frontend/src/pages/Home.vue
@@ -0,0 +1,17 @@
+<script>
+import Page from './utils/Page.vue';
+
+export default {
+  components: {
+    Page,
+  },
+};
+</script>
+
+<template>
+  <page>
+    <h1>TW Power Tools server</h1>
+    <p>Welcome to the TW Power Tools server dashboard. Currently the server is only used to manage <a href="https://docs.google.com/document/d/1O5YV6_WcxwrUyz-lwHOSTfZ3oyIFWj2EQee0VuKkhaA/edit" rel="noreferrer noopener">kill switches</a>.</p>
+    <p>While you have to sign in to enable/disable kill switches, you can see what's their status anonymously. Only some allowlisted users are currently able to do this. If you wish to be added to the allowlist, please <a href="https://iavm.xyz/b/twpowertools/new" rel="noreferrer noopener">fill in a bug</a> explaining why you're requiring access.</p>
+  </page>
+</template>
diff --git a/frontend/src/pages/KillSwitches.vue b/frontend/src/pages/KillSwitches.vue
new file mode 100644
index 0000000..e4fd9f6
--- /dev/null
+++ b/frontend/src/pages/KillSwitches.vue
@@ -0,0 +1,7 @@
+<script>
+export default {};
+</script>
+
+<template>
+  Kill switches!
+</template>
diff --git a/frontend/src/pages/NotAuthorized.vue b/frontend/src/pages/NotAuthorized.vue
new file mode 100644
index 0000000..f0b0a49
--- /dev/null
+++ b/frontend/src/pages/NotAuthorized.vue
@@ -0,0 +1,38 @@
+<script>
+import Page from './utils/Page.vue';
+
+export default {
+  components: {
+    Page,
+  },
+};
+</script>
+
+<template>
+  <page mini>
+    <div class="layout">
+      <mcw-material-icon class="main-icon" icon="no_accounts" />
+      <span class="label">You're not signed in.</span>
+    </div>
+  </page>
+</template>
+
+<style lang="scss" scoped>
+@use "@material/theme/color-palette" as palette;
+
+.layout {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  margin: 16px 0;
+}
+
+.main-icon {
+  font-size: 75px;
+  color: palette.$grey-800;
+}
+
+.label {
+  margin-top: 14px;
+}
+</style>
diff --git a/frontend/src/pages/utils/Page.vue b/frontend/src/pages/utils/Page.vue
new file mode 100644
index 0000000..16f0933
--- /dev/null
+++ b/frontend/src/pages/utils/Page.vue
@@ -0,0 +1,33 @@
+<script>
+export default {
+  props: {
+    'mini': Boolean,
+  },
+};
+</script>
+
+<template>
+  <div class="page-content">
+    <div class="main mdc-elevation--z4" :class="{'main--mini': mini}">
+      <slot></slot>
+    </div>
+  </div>
+</template>
+
+<style scoped>
+.main {
+  position: relative;
+  display: block;
+  width: Calc(100% - 64px);
+  max-width: 1024px;
+  margin: 20px auto;
+  padding: 16px 16px 16px 16px;
+  border-radius: 2px;
+  background: #FFFFFF;
+  font-family: "Roboto", "Helvetica", "Arial", sans-serif;
+}
+
+.main.main--mini {
+  max-width: 400px;
+}
+</style>
diff --git a/frontend/src/store/index.js b/frontend/src/store/index.js
new file mode 100644
index 0000000..9dbf288
--- /dev/null
+++ b/frontend/src/store/index.js
@@ -0,0 +1,35 @@
+import {createStore} from 'vuex';
+
+import {KillSwitchServicePromiseClient} from '../api_proto/kill_switch_grpc_web_pb.js';
+
+export const store = createStore({
+  state() {
+    return {
+      jwtToken: localStorage.getItem('jwtToken'),
+      client: null,
+    };
+  },
+  mutations: {
+    setJwtToken(state, token) {
+      if (token == null)
+        localStorage.removeItem('jwtToken');
+      else
+        localStorage.jwtToken = token;
+
+      state.jwtToken = token;
+    },
+  },
+  getters: {
+    getJwtToken(state) {
+      return state.jwtToken;
+    },
+    isSignedIn(state) {
+      return state.jwtToken != null;
+    },
+  },
+  actions: {
+    connectClient(store, host) {
+      store.state.client = new KillSwitchServicePromiseClient(host, null, null);
+    },
+  },
+});
diff --git a/frontend/src/theme.scss b/frontend/src/theme.scss
new file mode 100644
index 0000000..0c4e5a8
--- /dev/null
+++ b/frontend/src/theme.scss
@@ -0,0 +1,43 @@
+@use '@material/theme' with (
+  $primary: #2979FF,
+);
+
+@use "@material/icon-button";
+@use "@material/top-app-bar/mdc-top-app-bar";
+@use "@material/list/mdc-list";
+@use "@material/menu-surface/mdc-menu-surface";
+@use "@material/menu/mdc-menu";
+@use "@material/drawer";
+@use "@material/list";
+@use "@material/elevation/mdc-elevation";
+@use "@material/checkbox";
+@use "@material/data-table/data-table";
+@use "@material/button/styles";
+@use "@material/dialog";
+@use "@material/fab";
+@use "@material/floating-label/mdc-floating-label";
+@use "@material/line-ripple/mdc-line-ripple";
+@use "@material/notched-outline/mdc-notched-outline";
+@use "@material/textfield";
+@use "@material/select/styles" as b-style; // https://github.com/sass/sass/issues/2778#issuecomment-558365532
+
+@include drawer.core-styles;
+@include drawer.dismissible-core-styles;
+@include drawer.modal-core-styles;
+@include list.core-styles;
+@include icon-button.core-styles;
+@include icon-button.core-styles;
+@include data-table.core-styles;
+@include data-table.theme-baseline;
+@include dialog.core-styles;
+@include fab.core-styles;
+@include textfield.core-styles;
+
+html {
+  height: 100%;
+}
+
+body {
+  min-height: 100%;
+  margin: 0;
+}
diff --git a/frontend/src/vma.js b/frontend/src/vma.js
new file mode 100644
index 0000000..07b0727
--- /dev/null
+++ b/frontend/src/vma.js
@@ -0,0 +1,19 @@
+// We just import the components needed.
+import {button, dataTable, dialog, drawer, fab, iconButton, list, materialIcon, menu, select, textfield, topAppBar} from 'vue-material-adapter';
+
+export default {
+  install(vm) {
+    vm.use(button);
+    vm.use(dataTable);
+    vm.use(dialog);
+    vm.use(drawer);
+    vm.use(fab);
+    vm.use(iconButton);
+    vm.use(list);
+    vm.use(materialIcon);
+    vm.use(menu);
+    vm.use(select);
+    vm.use(textfield);
+    vm.use(topAppBar);
+  },
+};
