diff --git a/src/Authorization/UserAuthorizationChecker.php b/src/Authorization/UserAuthorizationChecker.php
index 78bbbe73262b8e1e97e333581b467394ee892582..dda9986cd2ec49ade81a1f5186ee76095fcdb3c1 100644
--- a/src/Authorization/UserAuthorizationChecker.php
+++ b/src/Authorization/UserAuthorizationChecker.php
@@ -49,8 +49,8 @@ class UserAuthorizationChecker
 
     public function setConfig(array $config)
     {
-        $this->loadExpressions($config[self::RIGHTS_CONFIG_ATTRIBUTE], $this->rightExpressions);
-        $this->loadExpressions($config[self::ATTRIBUTES_CONFIG_ATTRIBUTE], $this->attributeExpressions);
+        $this->loadExpressions($config[self::RIGHTS_CONFIG_ATTRIBUTE] ?? [], $this->rightExpressions);
+        $this->loadExpressions($config[self::ATTRIBUTES_CONFIG_ATTRIBUTE] ?? [], $this->attributeExpressions);
     }
 
     public function init()
diff --git a/src/ProxyApi/AbstractProxyDataEventSubscriber.php b/src/ProxyApi/AbstractProxyDataEventSubscriber.php
index 062ae2013ee9ee5c5f0b2967211f405a5155a880..8b2318d5f315859360179349ab735e6cdca2cf89 100644
--- a/src/ProxyApi/AbstractProxyDataEventSubscriber.php
+++ b/src/ProxyApi/AbstractProxyDataEventSubscriber.php
@@ -4,18 +4,18 @@ declare(strict_types=1);
 
 namespace Dbp\Relay\CoreBundle\ProxyApi;
 
+use Dbp\Relay\CoreBundle\Exception\ApiError;
 use Exception;
 use Symfony\Component\EventDispatcher\EventSubscriberInterface;
 use Symfony\Component\HttpFoundation\Exception\BadRequestException;
+use Symfony\Component\HttpFoundation\Response;
 
 abstract class AbstractProxyDataEventSubscriber implements EventSubscriberInterface
 {
-    protected const NAMESPACE = '';
-
     public static function getSubscribedEvents(): array
     {
         return [
-            ProxyDataEvent::NAME.'.'.static::NAMESPACE => 'onProxyDataEvent',
+            ProxyDataEvent::NAME.'.'.static::getSubscribedNamespace() => 'onProxyDataEvent',
         ];
     }
 
@@ -30,10 +30,11 @@ abstract class AbstractProxyDataEventSubscriber implements EventSubscriberInterf
         $arguments = $proxyData->getArguments();
         $returnValue = null;
 
-        if ($this->isFunctionDefined($functionName) === false) {
-            throw new BadRequestException(sprintf('unknown function "%s" under namespace "%s"', $functionName, static::NAMESPACE));
-        } elseif ($this->areAllRequiredArgumentsDefined($functionName, $arguments) === false) {
-            throw new BadRequestException(sprintf('incomplete argument list for function "%s" under namespace "%s"', $functionName, static::NAMESPACE));
+        $requiredFunctionArguments = static::getAvailableFunctionSignatures()[$functionName] ?? null;
+        if ($requiredFunctionArguments === null) {
+            throw new BadRequestException(sprintf('unknown function "%s" under namespace "%s"', $functionName, static::getSubscribedNamespace()));
+        } elseif ($this->areAllRequiredArgumentsDefined($requiredFunctionArguments, array_keys($arguments)) === false) {
+            throw new BadRequestException(sprintf('incomplete argument list for function "%s" under namespace "%s"', $functionName, static::getSubscribedNamespace()));
         }
 
         try {
@@ -45,9 +46,27 @@ abstract class AbstractProxyDataEventSubscriber implements EventSubscriberInterf
         $proxyData->setData($returnValue);
     }
 
-    abstract protected function isFunctionDefined(string $functionName): bool;
+    /**
+     * Must be overridden by deriving classes to indicate, which namespace they subscribe for.
+     */
+    protected static function getSubscribedNamespace(): string
+    {
+        throw ApiError::withDetails(Response::HTTP_INTERNAL_SERVER_ERROR, 'proxy data event subscribers must subscribe for a namespace');
+    }
 
-    abstract protected function areAllRequiredArgumentsDefined(string $functionName, array $arguments): bool;
+    /**
+     * Must be overridden by deriving classes to indicate, which functions are available and which mandatory arguments they have. The format is a follows:
+     * ['func1' => ['arg1', 'arg2'], 'func2' => []].
+     */
+    protected static function getAvailableFunctionSignatures(): array
+    {
+        throw ApiError::withDetails(Response::HTTP_INTERNAL_SERVER_ERROR, 'proxy data event subscribers must provide a list of available function signatures');
+    }
 
     abstract protected function callFunction(string $functionName, array $arguments);
+
+    private function areAllRequiredArgumentsDefined(array $requiredFunctionArguments, array $arguments): bool
+    {
+        return count(array_intersect($requiredFunctionArguments, $arguments)) === count($requiredFunctionArguments);
+    }
 }
diff --git a/src/ProxyApi/ProxyDataEventSubscriber.php b/src/ProxyApi/ProxyDataEventSubscriber.php
index 04c6603bae433b581149eac0eef64123b589b299..615dfd5e81bb3bb3be5b84f2151ef3c3d990090f 100644
--- a/src/ProxyApi/ProxyDataEventSubscriber.php
+++ b/src/ProxyApi/ProxyDataEventSubscriber.php
@@ -38,18 +38,17 @@ class ProxyDataEventSubscriber extends AbstractProxyDataEventSubscriber
         return self::$isCurrentlyActive;
     }
 
-    protected function isFunctionDefined(string $functionName): bool
+    protected static function getSubscribedNamespace(): string
     {
-        return
-            $functionName === self::GET_AVAILABLE_ATTRIBUTES_FUNCTION_NAME ||
-            $functionName === self::GET_USER_ATTRIBUTES_FUNCTION_NAME;
+        return self::NAMESPACE;
     }
 
-    protected function areAllRequiredArgumentsDefined(string $functionName, array $arguments): bool
+    protected static function getAvailableFunctionSignatures(): array
     {
-        return
-            $functionName !== self::GET_USER_ATTRIBUTES_FUNCTION_NAME ||
-            !Tools::isNullOrEmpty($arguments[self::USER_ID_PARAMETER_NAME] ?? null);
+        return [
+            self::GET_AVAILABLE_ATTRIBUTES_FUNCTION_NAME => [],
+            self::GET_USER_ATTRIBUTES_FUNCTION_NAME => [self::USER_ID_PARAMETER_NAME],
+        ];
     }
 
     /**