diff --git a/src/admin/debug/commands.rs b/src/admin/debug/commands.rs
index cf4ab31d..4e04c94a 100644
--- a/src/admin/debug/commands.rs
+++ b/src/admin/debug/commands.rs
@@ -229,8 +229,7 @@ pub(super) async fn get_remote_pdu(
 
 			debug!("Attempting to fetch homeserver signing keys for {server}");
 			self.services
-				.rooms
-				.event_handler
+				.server_keys
 				.fetch_required_signing_keys(parsed_pdu.iter().map(|(_event_id, event, _room_id)| event), &pub_key_map)
 				.await
 				.unwrap_or_else(|e| {
@@ -443,8 +442,7 @@ pub(super) async fn verify_json(&self) -> Result<RoomMessageEventContent> {
 			let pub_key_map = RwLock::new(BTreeMap::new());
 
 			self.services
-				.rooms
-				.event_handler
+				.server_keys
 				.fetch_required_signing_keys([&value], &pub_key_map)
 				.await?;
 
@@ -562,8 +560,7 @@ pub(super) async fn force_set_room_state_from_server(
 
 	info!("Fetching required signing keys for all the state events we got");
 	self.services
-		.rooms
-		.event_handler
+		.server_keys
 		.fetch_required_signing_keys(events.iter().map(|(_event_id, event, _room_id)| event), &pub_key_map)
 		.await?;
 
@@ -682,8 +679,7 @@ pub(super) async fn get_verify_keys(
 	let signature_ids: Vec<String> = Vec::new();
 	let keys = self
 		.services
-		.rooms
-		.event_handler
+		.server_keys
 		.fetch_signing_keys_for_server(&server_name, signature_ids)
 		.await?;
 
diff --git a/src/api/client/membership.rs b/src/api/client/membership.rs
index ca7e6b6f..f0d2848f 100644
--- a/src/api/client/membership.rs
+++ b/src/api/client/membership.rs
@@ -883,8 +883,7 @@ async fn join_room_by_id_helper_remote(
 
 	info!("Fetching join signing keys");
 	services
-		.rooms
-		.event_handler
+		.server_keys
 		.fetch_join_signing_keys(&send_join_response, &room_version_id, &pub_key_map)
 		.await?;
 
@@ -1230,8 +1229,7 @@ async fn join_room_by_id_helper_local(
 			drop(state_lock);
 			let pub_key_map = RwLock::new(BTreeMap::new());
 			services
-				.rooms
-				.event_handler
+				.server_keys
 				.fetch_required_signing_keys([&signed_value], &pub_key_map)
 				.await?;
 			services
@@ -1474,8 +1472,7 @@ pub(crate) async fn invite_helper(
 		.map_err(|_| Error::BadRequest(ErrorKind::InvalidParam, "Origin field is invalid."))?;
 
 		services
-			.rooms
-			.event_handler
+			.server_keys
 			.fetch_required_signing_keys([&value], &pub_key_map)
 			.await?;
 
diff --git a/src/api/router/auth.rs b/src/api/router/auth.rs
index 3f08ddba..838c5e79 100644
--- a/src/api/router/auth.rs
+++ b/src/api/router/auth.rs
@@ -250,8 +250,7 @@ async fn auth_server(
 	};
 
 	let keys_result = services
-		.rooms
-		.event_handler
+		.server_keys
 		.fetch_signing_keys_for_server(origin, vec![x_matrix.key.to_string()])
 		.await;
 
diff --git a/src/api/server/send.rs b/src/api/server/send.rs
index 394289a6..15f82faa 100644
--- a/src/api/server/send.rs
+++ b/src/api/server/send.rs
@@ -105,8 +105,7 @@ async fn handle_pdus(
 	let pub_key_map = RwLock::new(BTreeMap::new());
 	if !parsed_pdus.is_empty() {
 		services
-			.rooms
-			.event_handler
+			.server_keys
 			.fetch_required_signing_keys(parsed_pdus.iter().map(|(_event_id, event, _room_id)| event), &pub_key_map)
 			.await
 			.unwrap_or_else(|e| warn!("Could not fetch all signatures for PDUs from {origin}: {e:?}"));
diff --git a/src/api/server/send_join.rs b/src/api/server/send_join.rs
index 17f56383..c4d016f6 100644
--- a/src/api/server/send_join.rs
+++ b/src/api/server/send_join.rs
@@ -138,8 +138,7 @@ async fn create_join_event(
 	}
 
 	services
-		.rooms
-		.event_handler
+		.server_keys
 		.fetch_required_signing_keys([&value], &pub_key_map)
 		.await?;
 
diff --git a/src/api/server/send_leave.rs b/src/api/server/send_leave.rs
index ef4c8c45..e77c5d78 100644
--- a/src/api/server/send_leave.rs
+++ b/src/api/server/send_leave.rs
@@ -150,8 +150,7 @@ async fn create_leave_event(
 	.map_err(|_| Error::BadRequest(ErrorKind::InvalidParam, "origin is not a server name."))?;
 
 	services
-		.rooms
-		.event_handler
+		.server_keys
 		.fetch_required_signing_keys([&value], &pub_key_map)
 		.await?;
 
diff --git a/src/service/mod.rs b/src/service/mod.rs
index 084bfac8..f588a542 100644
--- a/src/service/mod.rs
+++ b/src/service/mod.rs
@@ -18,6 +18,7 @@ pub mod pusher;
 pub mod resolver;
 pub mod rooms;
 pub mod sending;
+pub mod server_keys;
 pub mod transaction_ids;
 pub mod uiaa;
 pub mod updates;
diff --git a/src/service/rooms/event_handler/mod.rs b/src/service/rooms/event_handler/mod.rs
index fd8e2185..bee986de 100644
--- a/src/service/rooms/event_handler/mod.rs
+++ b/src/service/rooms/event_handler/mod.rs
@@ -1,5 +1,4 @@
 mod parse_incoming_pdu;
-mod signing_keys;
 
 use std::{
 	collections::{hash_map, BTreeMap, HashMap, HashSet},
@@ -35,7 +34,7 @@ use ruma::{
 use tokio::sync::RwLock;
 
 use super::state_compressor::CompressedStateEvent;
-use crate::{globals, rooms, sending, Dep};
+use crate::{globals, rooms, sending, server_keys, Dep};
 
 pub struct Service {
 	services: Services,
@@ -50,6 +49,7 @@ struct Services {
 	metadata: Dep<rooms::metadata::Service>,
 	outlier: Dep<rooms::outlier::Service>,
 	pdu_metadata: Dep<rooms::pdu_metadata::Service>,
+	server_keys: Dep<server_keys::Service>,
 	short: Dep<rooms::short::Service>,
 	state: Dep<rooms::state::Service>,
 	state_accessor: Dep<rooms::state_accessor::Service>,
@@ -77,6 +77,7 @@ impl crate::Service for Service {
 				auth_chain: args.depend::<rooms::auth_chain::Service>("rooms::auth_chain"),
 				metadata: args.depend::<rooms::metadata::Service>("rooms::metadata"),
 				outlier: args.depend::<rooms::outlier::Service>("rooms::outlier"),
+				server_keys: args.depend::<server_keys::Service>("server_keys"),
 				pdu_metadata: args.depend::<rooms::pdu_metadata::Service>("rooms::pdu_metadata"),
 				short: args.depend::<rooms::short::Service>("rooms::short"),
 				state: args.depend::<rooms::state::Service>("rooms::state"),
@@ -1187,17 +1188,19 @@ impl Service {
 
 			// We go through all the signatures we see on the PDUs and their unresolved
 			// dependencies and fetch the corresponding signing keys
-			self.fetch_required_signing_keys(
-				events_with_auth_events
-					.iter()
-					.flat_map(|(_id, _local_pdu, events)| events)
-					.map(|(_event_id, event)| event),
-				pub_key_map,
-			)
-			.await
-			.unwrap_or_else(|e| {
-				warn!("Could not fetch all signatures for PDUs from {}: {:?}", origin, e);
-			});
+			self.services
+				.server_keys
+				.fetch_required_signing_keys(
+					events_with_auth_events
+						.iter()
+						.flat_map(|(_id, _local_pdu, events)| events)
+						.map(|(_event_id, event)| event),
+					pub_key_map,
+				)
+				.await
+				.unwrap_or_else(|e| {
+					warn!("Could not fetch all signatures for PDUs from {}: {:?}", origin, e);
+				});
 
 			let mut pdus = Vec::with_capacity(events_with_auth_events.len());
 			for (id, local_pdu, events_in_reverse_order) in events_with_auth_events {
diff --git a/src/service/rooms/timeline/mod.rs b/src/service/rooms/timeline/mod.rs
index 82b1cd0c..ac25b2a8 100644
--- a/src/service/rooms/timeline/mod.rs
+++ b/src/service/rooms/timeline/mod.rs
@@ -41,7 +41,7 @@ use tokio::sync::RwLock;
 use self::data::Data;
 use crate::{
 	account_data, admin, appservice, appservice::NamespaceRegex, globals, pusher, rooms,
-	rooms::state_compressor::CompressedStateEvent, sending, Dep,
+	rooms::state_compressor::CompressedStateEvent, sending, server_keys, Dep,
 };
 
 // Update Relationships
@@ -86,6 +86,7 @@ struct Services {
 	pdu_metadata: Dep<rooms::pdu_metadata::Service>,
 	read_receipt: Dep<rooms::read_receipt::Service>,
 	sending: Dep<sending::Service>,
+	server_keys: Dep<server_keys::Service>,
 	user: Dep<rooms::user::Service>,
 	pusher: Dep<pusher::Service>,
 	threads: Dep<rooms::threads::Service>,
@@ -114,6 +115,7 @@ impl crate::Service for Service {
 				pdu_metadata: args.depend::<rooms::pdu_metadata::Service>("rooms::pdu_metadata"),
 				read_receipt: args.depend::<rooms::read_receipt::Service>("rooms::read_receipt"),
 				sending: args.depend::<sending::Service>("sending"),
+				server_keys: args.depend::<server_keys::Service>("server_keys"),
 				user: args.depend::<rooms::user::Service>("rooms::user"),
 				pusher: args.depend::<pusher::Service>("pusher"),
 				threads: args.depend::<rooms::threads::Service>("rooms::threads"),
@@ -1181,7 +1183,7 @@ impl Service {
 		}
 
 		self.services
-			.event_handler
+			.server_keys
 			.fetch_required_signing_keys([&value], pub_key_map)
 			.await?;
 
diff --git a/src/service/rooms/event_handler/signing_keys.rs b/src/service/server_keys/mod.rs
similarity index 96%
rename from src/service/rooms/event_handler/signing_keys.rs
rename to src/service/server_keys/mod.rs
index d7cb3a9d..b27279af 100644
--- a/src/service/rooms/event_handler/signing_keys.rs
+++ b/src/service/server_keys/mod.rs
@@ -1,5 +1,6 @@
 use std::{
 	collections::{BTreeMap, HashMap, HashSet},
+	sync::Arc,
 	time::{Duration, SystemTime},
 };
 
@@ -21,7 +22,31 @@ use ruma::{
 use serde_json::value::RawValue as RawJsonValue;
 use tokio::sync::{RwLock, RwLockWriteGuard};
 
-impl super::Service {
+use crate::{globals, sending, Dep};
+
+pub struct Service {
+	services: Services,
+}
+
+struct Services {
+	globals: Dep<globals::Service>,
+	sending: Dep<sending::Service>,
+}
+
+impl crate::Service for Service {
+	fn build(args: crate::Args<'_>) -> Result<Arc<Self>> {
+		Ok(Arc::new(Self {
+			services: Services {
+				globals: args.depend::<globals::Service>("globals"),
+				sending: args.depend::<sending::Service>("sending"),
+			},
+		}))
+	}
+
+	fn name(&self) -> &str { crate::service::make_name(std::module_path!()) }
+}
+
+impl Service {
 	pub async fn fetch_required_signing_keys<'a, E>(
 		&'a self, events: E, pub_key_map: &RwLock<BTreeMap<String, BTreeMap<String, Base64>>>,
 	) -> Result<()>
diff --git a/src/service/services.rs b/src/service/services.rs
index 74e11d0b..2b9b93d4 100644
--- a/src/service/services.rs
+++ b/src/service/services.rs
@@ -12,7 +12,7 @@ use tokio::sync::Mutex;
 use crate::{
 	account_data, admin, appservice, client, emergency, globals, key_backups,
 	manager::Manager,
-	media, presence, pusher, resolver, rooms, sending, service,
+	media, presence, pusher, resolver, rooms, sending, server_keys, service,
 	service::{Args, Map, Service},
 	transaction_ids, uiaa, updates, users,
 };
@@ -31,6 +31,7 @@ pub struct Services {
 	pub resolver: Arc<resolver::Service>,
 	pub rooms: rooms::Service,
 	pub sending: Arc<sending::Service>,
+	pub server_keys: Arc<server_keys::Service>,
 	pub transaction_ids: Arc<transaction_ids::Service>,
 	pub uiaa: Arc<uiaa::Service>,
 	pub updates: Arc<updates::Service>,
@@ -94,6 +95,7 @@ impl Services {
 				user: build!(rooms::user::Service),
 			},
 			sending: build!(sending::Service),
+			server_keys: build!(server_keys::Service),
 			transaction_ids: build!(transaction_ids::Service),
 			uiaa: build!(uiaa::Service),
 			updates: build!(updates::Service),