Index: core/kernel/event_handler.php
===================================================================
--- core/kernel/event_handler.php
+++ core/kernel/event_handler.php
@@ -201,26 +201,73 @@
 		}
 
 		/**
-		 * Checks user permission to execute given $event
+		 * Automatically decides what permission checking method to use for a given event/user.
 		 *
-		 * @param kEvent $event
-		 * @return bool
-		 * @access public
+		 * @param kEvent $event Event.
+		 *
+		 * @return boolean
+		 */
+		public function AutoCheckPermission(kEvent $event)
+		{
+			if ( $this->Application->permissionCheckingDisabled() ) {
+				return $this->CheckMetaPermission($event);
+			}
+
+			return $this->CheckPermission($event);
+		}
+
+		/**
+		 * Checks user static permission to execute given $event.
+		 *
+		 * @param kEvent $event Event.
+		 *
+		 * @return boolean
 		 */
 		public function CheckPermission(kEvent $event)
 		{
+			$this->addDynamicPermissionMappings($event);
+
 			/** @var kPermissionsHelper $perm_helper */
 			$perm_helper = $this->Application->recallObject('PermissionsHelper');
 
-			if ( !isset($this->permMapping[$event->Name]) ) {
-				$ajax_event_name = $this->getAjaxSubEventName($event);
+			return $perm_helper->CheckEventPermission($event, $this->permMapping);
+		}
 
-				if ( $ajax_event_name != '' && isset($this->permMapping[$ajax_event_name]) ) {
-					$this->permMapping[$event->Name] = $this->permMapping[$ajax_event_name];
-				}
+		/**
+		 * Checks user meta-permission to execute given $event.
+		 *
+		 * @param kEvent $event Event.
+		 *
+		 * @return boolean
+		 */
+		public function CheckMetaPermission(kEvent $event)
+		{
+			$this->addDynamicPermissionMappings($event);
+
+			/** @var kPermissionsHelper $perm_helper */
+			$perm_helper = $this->Application->recallObject('PermissionsHelper');
+
+			return $perm_helper->CheckEventMetaPermission($event, $this->permMapping);
+		}
+
+		/**
+		 * Adds dynamic permission mappings.
+		 *
+		 * @param kEvent $event Event.
+		 *
+		 * @return void
+		 */
+		protected function addDynamicPermissionMappings(kEvent $event)
+		{
+			if ( isset($this->permMapping[$event->Name]) ) {
+				return;
 			}
 
-			return $perm_helper->CheckEventPermission($event, $this->permMapping);
+			$ajax_event_name = $this->getAjaxSubEventName($event);
+
+			if ( $ajax_event_name != '' && isset($this->permMapping[$ajax_event_name]) ) {
+				$this->permMapping[$event->Name] = $this->permMapping[$ajax_event_name];
+			}
 		}
 
 		/**
@@ -271,4 +318,4 @@
 			$event->setEventParam('sql', $sql);
 		}
 
-	}
\ No newline at end of file
+	}
Index: core/kernel/managers/request_manager.php
===================================================================
--- core/kernel/managers/request_manager.php
+++ core/kernel/managers/request_manager.php
@@ -157,7 +157,7 @@
 		/** @var kEventHandler $event_handler */
 		$event_handler = $this->Application->recallObject($event->Prefix . '_EventHandler');
 
-		if ( $this->Application->permissionCheckingDisabled() || $event_handler->CheckPermission($event) ) {
+		if ( $event_handler->AutoCheckPermission($event) ) {
 			$this->Application->HandleEvent($event);
 			$this->Application->notifyEventSubscribers($event);
 		}
Index: core/units/helpers/permissions_helper.php
===================================================================
--- core/units/helpers/permissions_helper.php
+++ core/units/helpers/permissions_helper.php
@@ -111,15 +111,15 @@
 			}
 
 			$perm_status = false;
-			foreach ($check_perms as $perm_name) {
-				// check if at least one of required permissions is set
-				if ($perm_name == 'debug' && $this->Application->isDebugMode(false)) {
-					// universal "debug" permission
-					return true;
-				}
-				elseif ( $perm_name == 'admin' && $this->Application->isAdminUser ) {
-					// any logged-in admin user will suffice
-					return true;
+
+			foreach ( $check_perms as $perm_name ) {
+				// Check if at least one of required permissions is set.
+				if ( $this->isMetaPermission($perm_name) ) {
+					if ( $this->checkMetaPermission($perm_name) ) {
+						return true;
+					}
+
+					continue;
 				}
 
 				$perm_name = $section.'.'.$perm_name;
@@ -138,6 +138,84 @@
 		}
 
 		/**
+		 * Common event meta-permission checking method.
+		 *
+		 * @param kEvent $event        Event.
+		 * @param array  $perm_mapping Perm mapping.
+		 *
+		 * @return boolean
+		 */
+		public function CheckEventMetaPermission(kEvent $event, array $perm_mapping)
+		{
+			// For a non-root user a "kEventHandler::CheckPermission" method is overridden to fix below issues.
+			try {
+				/*
+				 * Exception will be thrown, when "PermSection" isn't defined.
+				 *
+				 * This populates "top_prefix" event parameter used in "getPermissionByEvent" method.
+				 */
+				$event->getSection();
+
+				// Exception will be thrown if a permission mapping is absent.
+				$check_perms = $this->getPermissionByEvent($event, $perm_mapping);
+			}
+			catch ( Exception $e ) {
+				// Permission mapping is absent > grant access.
+				return true;
+			}
+
+			// Event is defined in mapping but is not checked by permissions.
+			if ( $check_perms === true ) {
+				return true;
+			}
+
+			// Event is mapped to a meta-permission > check used meta-permission.
+			foreach ( $check_perms as $perm_name ) {
+				if ( $this->isMetaPermission($perm_name) ) {
+					return $this->finalizePermissionCheck($event, $this->checkMetaPermission($perm_name));
+				}
+			}
+
+			// Event isn't mapped to a meta-permission > grant access.
+			return true;
+		}
+
+		/**
+		 * Determines if this is a meta-permission.
+		 *
+		 * @param string $permission_name Permission name.
+		 *
+		 * @return boolean
+		 */
+		public function isMetaPermission($permission_name)
+		{
+			return $permission_name === 'admin' || $permission_name === 'debug';
+		}
+
+		/**
+		 * Determines if this is a meta-permission.
+		 *
+		 * @param string $permission_name Permission name.
+		 *
+		 * @return boolean
+		 * @throws InvalidArgumentException When a non-meta-permission is given.
+		 */
+		public function checkMetaPermission($permission_name)
+		{
+			if ( $permission_name === 'debug' ) {
+				// Universal "debug" permission.
+				return $this->Application->isDebugMode(false);
+			}
+
+			if ( $permission_name === 'admin' ) {
+				// Any logged-in admin user will suffice.
+				return $this->Application->isAdminUser;
+			}
+
+			throw new InvalidArgumentException('The "' . $permission_name . '" permission is not a meta permission.');
+		}
+
+		/**
 		 * Returns owner + primary category for each item (used for permission checking)
 		 *
 		 * @param string $prefix
@@ -260,13 +338,12 @@
 					continue;
 				}
 
-				if ( $perm_name == 'debug' && $this->Application->isDebugMode(false) ) {
-					// universal "debug" permission
-					return true;
-				}
-				elseif ( $perm_name == 'admin' && $this->Application->isAdminUser ) {
-					// any logged-in admin user will suffice
-					return true;
+				if ( $this->isMetaPermission($perm_name) ) {
+					if ( $this->checkMetaPermission($perm_name) ) {
+						return true;
+					}
+
+					continue;
 				}
 
 				$perm_name = $item_prefix . '.' . $perm_mapping[$perm_name];
@@ -406,8 +483,8 @@
 			$permission_groups = getArrayValue($params, 'permissions');
 			$check_admin = isset($params['admin']) && $params['admin'];
 
-			if ($permission_groups && !$perm_event) {
-				// check permissions by permission names in current category
+			if ( $permission_groups && !$perm_event ) {
+				// Check permissions by permission names in current category.
 				$permission_groups = explode('|', $permission_groups);
 				$group_has_permission = false;
 
@@ -444,14 +521,15 @@
 				}
 				return false;
 			}
-			elseif ( $perm_event && !$this->Application->permissionCheckingDisabled() ) {
-				// check permission by event name
-				list ($prefix, ) = explode(':', $perm_event);
+
+			if ( $perm_event ) {
+				// Check permission by event name.
+				list ($prefix,) = explode(':', $perm_event);
 
 				/** @var kEventHandler $event_handler */
 				$event_handler = $this->Application->recallObject($prefix . '_EventHandler');
 
-				return $event_handler->CheckPermission( new kEvent($perm_event) );
+				return $event_handler->AutoCheckPermission(new kEvent($perm_event));
 			}
 
 			return true;