diff --git a/applications/gui/src/config_window.cpp b/applications/gui/src/config_window.cpp
index 4832454ad3020f4337def5809bd2f05e2ed83d7e..322f817ae264386ab3a54bfddc72c7d5f588fc36 100644
--- a/applications/gui/src/config_window.cpp
+++ b/applications/gui/src/config_window.cpp
@@ -55,6 +55,7 @@ void ConfigWindow::_addElements(nanogui::FormHelper *form, const std::string &su
 	Configurable *configurable = ftl::config::find(suri);
 	ftl::config::json_t data;
 	if (configurable) {
+		configurable->refresh();
 		data = configurable->getConfig();
 	}
 
diff --git a/components/common/cpp/include/ftl/configurable.hpp b/components/common/cpp/include/ftl/configurable.hpp
index 219bd171edf4b7997cc35f97fa7787a0c4bb4559..61dca8ea3b883e97f2e26c2f1a5126c92f8aa520 100644
--- a/components/common/cpp/include/ftl/configurable.hpp
+++ b/components/common/cpp/include/ftl/configurable.hpp
@@ -101,6 +101,12 @@ class Configurable {
 
 	void patchPtr(nlohmann::json &newcfg) { config_ = &newcfg; }
 
+	/**
+	 * Allow configurables to refresh their internal state, perhaps from a
+	 * remote source.
+	 */
+	virtual void refresh();
+
 	protected:
 	nlohmann::json *config_;
 
diff --git a/components/common/cpp/src/configurable.cpp b/components/common/cpp/src/configurable.cpp
index 5116292adab92672da3adb239ecb2ed3f4630011..8186713b11025f1799afbf26ca8f56532f1deb3f 100644
--- a/components/common/cpp/src/configurable.cpp
+++ b/components/common/cpp/src/configurable.cpp
@@ -59,4 +59,8 @@ void Configurable::on(const string &prop, function<void(const ftl::config::Event
 	} else {
 		(*ix).second.push_back(f);
 	}
-}
\ No newline at end of file
+}
+
+void Configurable::refresh() {
+	// Do nothing by default
+}
diff --git a/components/net/cpp/include/ftl/net_configurable.hpp b/components/net/cpp/include/ftl/net_configurable.hpp
index d9fd6e5288758de51de91bce65a1afd86831f19e..2c6495410321c03b62e18a83f214d00b807bccdb 100644
--- a/components/net/cpp/include/ftl/net_configurable.hpp
+++ b/components/net/cpp/include/ftl/net_configurable.hpp
@@ -12,6 +12,8 @@ namespace ftl {
 	NetConfigurable(ftl::UUID peer, const std::string &suri, ftl::ctrl::Master &ctrl, ftl::config::json_t &config);
 	~NetConfigurable();
 
+	void refresh() override;
+
 	protected:
 	void inject(const std::string &name, nlohmann::json &value);
 
diff --git a/components/net/cpp/src/net_configurable.cpp b/components/net/cpp/src/net_configurable.cpp
index be98cf7edbb221c61e9732a9e59d8546f1185644..cf597c5c77eec05205b6bf0de3f360c7fac178b2 100644
--- a/components/net/cpp/src/net_configurable.cpp
+++ b/components/net/cpp/src/net_configurable.cpp
@@ -10,3 +10,7 @@ ftl::NetConfigurable::~NetConfigurable(){}
 void ftl::NetConfigurable::inject(const std::string &name, nlohmann::json &value) {
     ctrl.set(peer, suri + std::string("/") + name, value);
 }
+
+void ftl::NetConfigurable::refresh() {
+    (*config_) = ctrl.get(peer, suri);
+}