diff --git a/code/modules/admin/verbs/admingame.dm b/code/modules/admin/verbs/admingame.dm
index 317c8fafd3b..546225c8f85 100644
--- a/code/modules/admin/verbs/admingame.dm
+++ b/code/modules/admin/verbs/admingame.dm
@@ -43,7 +43,10 @@
if(SSplayer_ranks.is_veteran(M.client, admin_bypass = FALSE))
player_ranks += "Veteran"
-
+ //BUBBER ADDITION START
+ if(SSplayer_ranks.is_vetted(M.client, admin_bypass = FALSE))
+ player_ranks |= "Vetted"
+ // BUBBER ADDITION END
body += "
Player Ranks: [length(player_ranks) ? player_ranks.Join(", ") : "None"]"
// SKYRAT EDIT END
body += "
CentCom Galactic Ban DB: "
diff --git a/code/modules/client/preferences/middleware/jobs.dm b/code/modules/client/preferences/middleware/jobs.dm
index d61fb53c98f..319547e0d3c 100644
--- a/code/modules/client/preferences/middleware/jobs.dm
+++ b/code/modules/client/preferences/middleware/jobs.dm
@@ -102,6 +102,10 @@
if(SSplayer_ranks.is_veteran(user.client))
data["is_veteran"] = TRUE
// SKYRAT EDIT END
+ // BUBBER EDIT BEGIN
+ if(SSplayer_ranks.is_vetted(user.client))
+ data["is_vetted"] = TRUE
+ // BUBBER EDIT END
var/list/required_job_playtime = get_required_job_playtime(user)
if (!isnull(required_job_playtime))
data += required_job_playtime
diff --git a/config/bubbers/vetted_players.txt b/config/bubbers/vetted_players.txt
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/modular_skyrat/master_files/code/modules/client/preferences/erp_preferences.dm b/modular_skyrat/master_files/code/modules/client/preferences/erp_preferences.dm
index 2c4ffb82713..b04900ec2ef 100644
--- a/modular_skyrat/master_files/code/modules/client/preferences/erp_preferences.dm
+++ b/modular_skyrat/master_files/code/modules/client/preferences/erp_preferences.dm
@@ -20,7 +20,8 @@
/datum/preference/toggle/master_erp_preferences/is_accessible(datum/preferences/preferences)
if (!..(preferences))
return FALSE
-
+ if(!SSplayer_ranks.is_vetted(preferences.parent, admin_bypass = FALSE)) // BUBBER EDIT
+ return FALSE // BUBBER EDIT
if(CONFIG_GET(flag/disable_erp_preferences))
return FALSE
@@ -40,7 +41,8 @@
/datum/preference/toggle/erp/is_accessible(datum/preferences/preferences)
if (!..(preferences))
return FALSE
-
+ if(!SSplayer_ranks.is_vetted(preferences.parent, admin_bypass = FALSE)) // BUBBER EDIT
+ return FALSE // BUBBER EDIT
if(CONFIG_GET(flag/disable_erp_preferences))
return FALSE
diff --git a/modular_skyrat/modules/player_ranks/code/subsystem/player_ranks.dm b/modular_skyrat/modules/player_ranks/code/subsystem/player_ranks.dm
index 2b11cabb8b0..04130e93b7a 100644
--- a/modular_skyrat/modules/player_ranks/code/subsystem/player_ranks.dm
+++ b/modular_skyrat/modules/player_ranks/code/subsystem/player_ranks.dm
@@ -20,7 +20,7 @@ SUBSYSTEM_DEF(player_ranks)
var/datum/player_rank_controller/mentor/mentor_controller
/// The veteran player rank controller.
var/datum/player_rank_controller/veteran/veteran_controller
-
+ var/datum/player_rank_controller/vetted/vetted_controller // BUBBER EDIT ADDITION
/datum/controller/subsystem/player_ranks/Initialize()
if(IsAdminAdvancedProcCall())
@@ -29,7 +29,7 @@ SUBSYSTEM_DEF(player_ranks)
load_donators()
load_mentors()
load_veterans()
-
+ load_vetted_ckeys() // BUBBER EDIT ADDITION
return SS_INIT_SUCCESS
@@ -39,7 +39,7 @@ SUBSYSTEM_DEF(player_ranks)
QDEL_NULL(donator_controller)
QDEL_NULL(mentor_controller)
QDEL_NULL(veteran_controller)
-
+ QDEL_NULL(vetted_controller) // BUBBER EDIT ADDITION
/**
* Returns whether or not the user is qualified as a donator.
diff --git a/modular_zubbers/modules/vetted/examine.dm b/modular_zubbers/modules/vetted/examine.dm
new file mode 100644
index 00000000000..de2b450ccf4
--- /dev/null
+++ b/modular_zubbers/modules/vetted/examine.dm
@@ -0,0 +1,9 @@
+/mob/living/silicon/get_silicon_flavortext()
+ . = ..()
+ if(client && SSplayer_ranks.is_vetted(client, admin_bypass = FALSE))
+ . += span_greenannounce("This player has been vetted by staff.")
+
+/mob/living/carbon/human/examine(mob/user)
+ . = ..()
+ if(client && SSplayer_ranks.is_vetted(client, admin_bypass = FALSE))
+ . += span_greenannounce("This player has been vetted by staff.")
diff --git a/modular_zubbers/modules/vetted/vetted.dm b/modular_zubbers/modules/vetted/vetted.dm
new file mode 100644
index 00000000000..1682e818300
--- /dev/null
+++ b/modular_zubbers/modules/vetted/vetted.dm
@@ -0,0 +1,53 @@
+GLOBAL_LIST_EMPTY(vetted_list)
+GLOBAL_PROTECT(vetted_list)
+
+/datum/controller/subsystem/player_ranks
+
+/datum/player_rank_controller/vetted
+ rank_title = "vetted user"
+ var/file_path_vetted
+/datum/controller/subsystem/player_ranks/proc/is_vetted(client/user, admin_bypass = TRUE)
+ if(!istype(user))
+ CRASH("Invalid user type provided to is_vetted(), expected 'client' and obtained '[user ? user.type : "null"]'.")
+
+ if(GLOB.vetted_list[user.ckey])
+ return TRUE
+
+ if(admin_bypass && is_admin(user))
+ return TRUE
+
+ return FALSE
+
+
+/datum/controller/subsystem/player_ranks/proc/load_vetted_ckeys()
+ PROTECTED_PROC(TRUE)
+
+ if(IsAdminAdvancedProcCall())
+ return
+
+ vetted_controller = new
+ vetted_controller.file_path_vetted = "[global.config.directory]/bubbers/vetted_players.txt"
+ for(var/line in world.file2list(vetted_controller.file_path_vetted))
+ if(!line)
+ continue
+
+ if(findtextEx(line, "#", 1, 2))
+ continue
+
+ vetted_controller.add_player(line)
+
+ return TRUE
+
+/datum/player_rank_controller/vetted/add_player(ckey)
+ if(IsAdminAdvancedProcCall())
+ return
+
+ ckey = ckey(ckey)
+
+ GLOB.vetted_list[ckey] = TRUE
+
+/datum/player_rank_controller/vetted/remove_player(ckey)
+ if(IsAdminAdvancedProcCall())
+ return
+
+ GLOB.vetted_list -= ckey
diff --git a/tgstation.dme b/tgstation.dme
index dab890a999e..8673f5ed003 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -7882,4 +7882,6 @@
#include "modular_zubbers\modules\customization\modules\mob\dead\new_player\sprite_accessories\skrell_hair.dm"
#include "modular_zubbers\modules\customization\modules\mob\living\carbon\human\species\akula.dm"
#include "modular_zubbers\modules\emotes\code\emotes.dm"
+#include "modular_zubbers\modules\vetted\examine.dm"
+#include "modular_zubbers\modules\vetted\vetted.dm"
// END_INCLUDE
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/data.ts b/tgui/packages/tgui/interfaces/PreferencesMenu/data.ts
index d1213517b6c..7c841fdfbe5 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/data.ts
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/data.ts
@@ -176,7 +176,7 @@ export type PreferencesMenuData = {
preview_selection: string; // SKYRAT EDIT ADDITION
is_veteran: BooleanLike; // SKYRAT EDIT - Veteran status
-
+ is_vetted: BooleanLike; // BUBBER EDIT - Vetted Users
character_preferences: {
clothing: Record;
features: Record;