Index: binary-improvements2/WebServer/src/Commands/CreateWebUser.cs
===================================================================
--- binary-improvements2/WebServer/src/Commands/CreateWebUser.cs	(revision 404)
+++ binary-improvements2/WebServer/src/Commands/CreateWebUser.cs	(revision 404)
@@ -0,0 +1,73 @@
+using System.Collections.Generic;
+using System.Text.RegularExpressions;
+using JetBrains.Annotations;
+using Platform.EOS;
+using Platform.Steam;
+using Webserver.Permissions;
+
+namespace Webserver.Commands {
+	[UsedImplicitly]
+	public class CreateWebUser : ConsoleCmdAbstract {
+		private static readonly Regex validNameTokenMatcher = new Regex (@"^\w+$");
+
+		public override string[] GetCommands () {
+			return new[] {"createwebuser"};
+		}
+
+		public override string GetDescription () {
+			return "Create a web dashboard user account";
+		}
+
+		public override string GetHelp () {
+			return ""; // TODO
+		}
+
+		public override int DefaultPermissionLevel => 1000;
+		public override bool IsExecuteOnClient => true;
+
+		public override void Execute (List<string> _params, CommandSenderInfo _senderInfo) {
+			// if (GameManager.IsDedicatedServer) {
+			// 	SdtdConsole.Instance.Output ("Command can only be executed on game clients or listen servers.");
+			// 	return;
+			// }
+			
+			// TODO
+			
+			if (_params.Count < 2) {
+				SdtdConsole.Instance.Output ($"Wrong number of arguments");
+				return;
+			}
+
+			string name = _params [0];
+			string pass = _params [1];
+			
+			if (string.IsNullOrEmpty (name)) {
+				SdtdConsole.Instance.Output ("Argument 'name' is empty.");
+				return;
+			}
+
+			if (!validNameTokenMatcher.IsMatch (name)) {
+				SdtdConsole.Instance.Output (
+					"Argument 'name' may only contain characters (A-Z, a-z), digits (0-9) and underscores (_).");
+				return;
+			}
+
+			if (string.IsNullOrEmpty (pass)) {
+				SdtdConsole.Instance.Output ("Argument 'password' is empty.");
+				return;
+			}
+
+			if (!validNameTokenMatcher.IsMatch (pass)) {
+				SdtdConsole.Instance.Output (
+					"Argument 'password' may only contain characters (A-Z, a-z), digits (0-9) and underscores (_).");
+				return;
+			}
+
+			AdminWebUsers.Instance.AddUser (name, pass, new UserIdentifierSteam (76561198066968172ul),
+				new UserIdentifierEos ("0002bc29a5624774b4b0dc27e60b974f"));
+
+			SdtdConsole.Instance.Output ($"User added");
+		}
+
+	}
+}
Index: binary-improvements2/WebServer/src/Commands/ReloadWebPermissions.cs
===================================================================
--- binary-improvements2/WebServer/src/Commands/ReloadWebPermissions.cs	(revision 402)
+++ 	(revision )
@@ -1,20 +1,0 @@
-using System.Collections.Generic;
-using JetBrains.Annotations;
-
-namespace Webserver.Commands {
-	[UsedImplicitly]
-	public class ReloadWebPermissions : ConsoleCmdAbstract {
-		public override string GetDescription () {
-			return "force reload of web permissions file";
-		}
-
-		public override string[] GetCommands () {
-			return new[] {"reloadwebpermissions"};
-		}
-
-		public override void Execute (List<string> _params, CommandSenderInfo _senderInfo) {
-			WebPermissions.Instance.Load ();
-			SdtdConsole.Instance.Output ("Web permissions file reloaded");
-		}
-	}
-}
Index: binary-improvements2/WebServer/src/Commands/WebPermissionsCmd.cs
===================================================================
--- binary-improvements2/WebServer/src/Commands/WebPermissionsCmd.cs	(revision 402)
+++ binary-improvements2/WebServer/src/Commands/WebPermissionsCmd.cs	(revision 404)
@@ -1,4 +1,5 @@
 using System.Collections.Generic;
 using JetBrains.Annotations;
+using Webserver.Permissions;
 
 namespace Webserver.Commands {
@@ -44,5 +45,5 @@
 			}
 
-			if (!WebPermissions.Instance.IsKnownModule (_params [1])) {
+			if (!AdminWebModules.Instance.IsKnownModule (_params [1])) {
 				SdtdConsole.Instance.Output ($"\"{_params [1]}\" is not a valid web function.");
 				return;
@@ -54,5 +55,5 @@
 			}
 
-			WebPermissions.Instance.AddModulePermission (_params [1], level);
+			AdminWebModules.Instance.AddModule (_params [1], level);
 			SdtdConsole.Instance.Output ($"{_params [1]} added with permission level of {level}.");
 		}
@@ -64,10 +65,10 @@
 			}
 
-			if (!WebPermissions.Instance.IsKnownModule (_params [1])) {
+			if (!AdminWebModules.Instance.IsKnownModule (_params [1])) {
 				SdtdConsole.Instance.Output ($"\"{_params [1]}\" is not a valid web function.");
 				return;
 			}
 
-			WebPermissions.Instance.RemoveModulePermission (_params [1]);
+			AdminWebModules.Instance.RemoveModule (_params [1]);
 			SdtdConsole.Instance.Output ($"{_params [1]} removed from permissions list.");
 		}
@@ -76,6 +77,10 @@
 			SdtdConsole.Instance.Output ("Defined web function permissions:");
 			SdtdConsole.Instance.Output ("  Level: Web function");
-			foreach (WebPermissions.WebModulePermission wmp in WebPermissions.Instance.GetModules ()) {
-				SdtdConsole.Instance.Output ($"  {wmp.permissionLevel,5}: {wmp.module}");
+			
+			List<AdminWebModules.WebModule> wmps = AdminWebModules.Instance.GetModules ();
+			for (int i = 0; i < wmps.Count; i++) {
+				AdminWebModules.WebModule wmp = wmps [i];
+				
+				SdtdConsole.Instance.Output ($"  {wmp.PermissionLevel,5}: {wmp.Name}");
 			}
 		}
Index: binary-improvements2/WebServer/src/Commands/WebTokens.cs
===================================================================
--- binary-improvements2/WebServer/src/Commands/WebTokens.cs	(revision 402)
+++ binary-improvements2/WebServer/src/Commands/WebTokens.cs	(revision 404)
@@ -2,4 +2,5 @@
 using System.Text.RegularExpressions;
 using JetBrains.Annotations;
+using Webserver.Permissions;
 
 namespace Webserver.Commands {
@@ -19,6 +20,6 @@
 			return "Set/get webtoken permission levels. A level of 0 is maximum permission.\n" +
 			       "Usage:\n" +
-			       "   webtokens add <username> <usertoken> <level>\n" +
-			       "   webtokens remove <username>\n" +
+			       "   webtokens add <tokenname> <tokensecret> <level>\n" +
+			       "   webtokens remove <tokenname>\n" +
 			       "   webtokens list";
 		}
@@ -47,5 +48,5 @@
 
 			if (string.IsNullOrEmpty (_params [1])) {
-				SdtdConsole.Instance.Output ("Argument 'username' is empty.");
+				SdtdConsole.Instance.Output ("Argument 'tokenname' is empty.");
 				return;
 			}
@@ -53,10 +54,10 @@
 			if (!validNameTokenMatcher.IsMatch (_params [1])) {
 				SdtdConsole.Instance.Output (
-					"Argument 'username' may only contain characters (A-Z, a-z), digits (0-9) and underscores (_).");
+					"Argument 'tokenname' may only contain characters (A-Z, a-z), digits (0-9) and underscores (_).");
 				return;
 			}
 
 			if (string.IsNullOrEmpty (_params [2])) {
-				SdtdConsole.Instance.Output ("Argument 'usertoken' is empty.");
+				SdtdConsole.Instance.Output ("Argument 'tokensecret' is empty.");
 				return;
 			}
@@ -64,5 +65,5 @@
 			if (!validNameTokenMatcher.IsMatch (_params [2])) {
 				SdtdConsole.Instance.Output (
-					"Argument 'usertoken' may only contain characters (A-Z, a-z), digits (0-9) and underscores (_).");
+					"Argument 'tokensecret' may only contain characters (A-Z, a-z), digits (0-9) and underscores (_).");
 				return;
 			}
@@ -73,6 +74,6 @@
 			}
 
-			WebPermissions.Instance.AddAdmin (_params [1], _params [2], level);
-			SdtdConsole.Instance.Output ($"Web user with name={_params [1]} and password={_params [2]} added with permission level of {level}.");
+			AdminApiTokens.Instance.AddToken (_params [1], _params [2], level);
+			SdtdConsole.Instance.Output ($"Web API token with name={_params [1]} and secret={_params [2]} added with permission level of {level}.");
 		}
 
@@ -84,5 +85,5 @@
 
 			if (string.IsNullOrEmpty (_params [1])) {
-				SdtdConsole.Instance.Output ("Argument 'username' is empty.");
+				SdtdConsole.Instance.Output ("Argument 'tokenname' is empty.");
 				return;
 			}
@@ -90,17 +91,17 @@
 			if (!validNameTokenMatcher.IsMatch (_params [1])) {
 				SdtdConsole.Instance.Output (
-					"Argument 'username' may only contain characters (A-Z, a-z), digits (0-9) and underscores (_).");
+					"Argument 'tokenname' may only contain characters (A-Z, a-z), digits (0-9) and underscores (_).");
 				return;
 			}
 
-			WebPermissions.Instance.RemoveAdmin (_params [1]);
-			SdtdConsole.Instance.Output ($"{_params [1]} removed from web user permissions list.");
+			AdminApiTokens.Instance.RemoveToken (_params [1]);
+			SdtdConsole.Instance.Output ($"{_params [1]} removed from web API token permissions list.");
 		}
 
 		private void ExecuteList () {
-			SdtdConsole.Instance.Output ("Defined webuser permissions:");
-			SdtdConsole.Instance.Output ("  Level: Name / Token");
-			foreach (WebPermissions.AdminToken at in WebPermissions.Instance.GetAdmins ()) {
-				SdtdConsole.Instance.Output ($"  {at.permissionLevel,5}: {at.name} / {at.token}");
+			SdtdConsole.Instance.Output ("Defined web API token permissions:");
+			SdtdConsole.Instance.Output ("  Level: Name / Secret");
+			foreach ((string _, AdminApiTokens.ApiToken apiToken) in AdminApiTokens.Instance.GetTokens ()) {
+				SdtdConsole.Instance.Output ($"  {apiToken.PermissionLevel,5}: {apiToken.Name} / {apiToken.Secret}");
 			}
 		}
