diff --git a/src/LocalData/AbstractLocalDataEventSubscriber.php b/src/LocalData/AbstractLocalDataEventSubscriber.php
index e35e035e936c97809c081582984814521e9f772b..e309f6645730a3e14f69594f3cd2e64405add987 100644
--- a/src/LocalData/AbstractLocalDataEventSubscriber.php
+++ b/src/LocalData/AbstractLocalDataEventSubscriber.php
@@ -22,14 +22,16 @@ use Symfony\Contracts\EventDispatcher\Event;
 abstract class AbstractLocalDataEventSubscriber extends AbstractAuthorizationService implements EventSubscriberInterface
 {
     protected const ROOT_CONFIG_NODE = 'local_data_mapping';
-    protected const SOURCE_ATTRIBUTES_CONFIG_NODE = 'source_attributes';
+    protected const SOURCE_ATTRIBUTE_CONFIG_NODE = 'source_attribute';
     protected const LOCAL_DATA_ATTRIBUTE_CONFIG_NODE = 'local_data_attribute';
     protected const AUTHORIZATION_EXPRESSION_CONFIG_NODE = 'authorization_expression';
+    protected const ALLOW_LOCAL_QUERY_CONFIG_NODE = 'allow_query';
     protected const DEFAULT_VALUE_ATTRIBUTE_CONFIG_NODE = 'default_value';
     protected const DEFAULT_VALUES_ATTRIBUTE_CONFIG_NODE = 'default_values';
 
-    private const SOURCE_ATTRIBUTES_KEY = 'source';
+    private const SOURCE_ATTRIBUTE_KEY = 'source';
     private const DEFAULT_VALUE_KEY = 'default';
+    private const QUERYABLE_KEY = 'queryable';
 
     /*
      * WORKAROUND: could not find a way to determine whether a Symfony config array node was NOT specified since it provides an empty
@@ -58,7 +60,8 @@ abstract class AbstractLocalDataEventSubscriber extends AbstractAuthorizationSer
             }
 
             $attributeMapEntry = [];
-            $attributeMapEntry[self::SOURCE_ATTRIBUTES_KEY] = $configMappingEntry[self::SOURCE_ATTRIBUTES_CONFIG_NODE];
+            $attributeMapEntry[self::SOURCE_ATTRIBUTE_KEY] = $configMappingEntry[self::SOURCE_ATTRIBUTE_CONFIG_NODE];
+            $attributeMapEntry[self::QUERYABLE_KEY] = $configMappingEntry[self::ALLOW_LOCAL_QUERY_CONFIG_NODE];
 
             $defaultValue = $configMappingEntry[self::DEFAULT_VALUE_ATTRIBUTE_CONFIG_NODE] ?? null;
             if ($defaultValue === null) {
@@ -97,33 +100,30 @@ abstract class AbstractLocalDataEventSubscriber extends AbstractAuthorizationSer
     public function onEvent(Event $event)
     {
         if ($event instanceof LocalDataPreEvent) {
-            foreach ($event->getPendingQueryParametersIn() as $localDataAttributeName => $localDataAttributeValue) {
-                if (($attributeMapEntry = $this->attributeMapping[$localDataAttributeName] ?? null) !== null) {
+            $localQueryParameters = [];
+            foreach ($event->getPendingQueryParameters() as $localDataAttributeName => $localDataAttributeValue) {
+                if (($attributeMapEntry = $this->attributeMapping[$localDataAttributeName] ?? null) !== null &&
+                    $attributeMapEntry[self::QUERYABLE_KEY] === true) {
                     if (!$this->isGranted($localDataAttributeName)) {
                         throw ApiError::withDetails(Response::HTTP_UNAUTHORIZED, sprintf('access to local data attribute \'%s\' denied', $localDataAttributeName));
                     }
-                    $sourceAttributeName = $attributeMapEntry[self::SOURCE_ATTRIBUTES_KEY][0];
-                    $event->addQueryParameterOut($sourceAttributeName, $localDataAttributeValue);
-                    $event->acknowledgeQueryParameterIn($localDataAttributeName);
+                    $sourceAttributeName = $attributeMapEntry[self::SOURCE_ATTRIBUTE_KEY];
+                    $localQueryParameters[$sourceAttributeName] = $localDataAttributeValue;
+                    $event->acknowledgeQueryParameter($localDataAttributeName);
                 }
             }
 
-            $this->onPreEvent($event);
+            $this->onPreEvent($event, $localQueryParameters);
         } elseif ($event instanceof LocalDataPostEvent) {
             foreach ($event->getPendingRequestedAttributes() as $localDataAttributeName) {
                 if (($attributeMapEntry = $this->attributeMapping[$localDataAttributeName] ?? null) !== null) {
                     if (!$this->isGranted($localDataAttributeName)) {
                         throw ApiError::withDetails(Response::HTTP_UNAUTHORIZED, sprintf('access to local data attribute \'%s\' denied', $localDataAttributeName));
                     }
-                    $attributeValue = null;
-                    foreach ($attributeMapEntry[self::SOURCE_ATTRIBUTES_KEY] as $sourceAttributeName) {
-                        if (($value = $event->getSourceData()[$sourceAttributeName] ?? null) !== null) {
-                            $attributeValue = $value;
-                            break;
-                        }
-                    }
 
+                    $attributeValue = $event->getSourceData()[$attributeMapEntry[self::SOURCE_ATTRIBUTE_KEY]] ?? null;
                     $attributeValue = $attributeValue ?? $attributeMapEntry[self::DEFAULT_VALUE_KEY] ?? null;
+
                     if ($attributeValue !== null) {
                         $event->setLocalDataAttribute($localDataAttributeName, $attributeValue);
                     } else {
@@ -153,20 +153,23 @@ abstract class AbstractLocalDataEventSubscriber extends AbstractAuthorizationSer
                     ->scalarNode(self::LOCAL_DATA_ATTRIBUTE_CONFIG_NODE)
                         ->info('The name of the local data attribute.')
                     ->end()
-                    ->arrayNode(self::SOURCE_ATTRIBUTES_CONFIG_NODE)
-                        ->info('The list of source attributes to map to the local data attribute ordered by preferred usage. If an attribute is not found, the next attribute in the list is used.')
-                        ->scalarPrototype()->end()
+                    ->scalarNode(self::SOURCE_ATTRIBUTE_CONFIG_NODE)
+                        ->info('The source attribute to map to the local data attribute. If the source attribute is not found, the default value is used.')
                     ->end()
                     ->scalarNode(self::AUTHORIZATION_EXPRESSION_CONFIG_NODE)
                         ->defaultValue('false')
                         ->info('A boolean expression evaluable by the Symfony Expression Language determining whether the current user may request read the local data attribute.')
                     ->end()
+                    ->booleanNode(self::ALLOW_LOCAL_QUERY_CONFIG_NODE)
+                        ->defaultValue('false')
+                        ->info('Indicates whether the local data attribute can be used in local queries.')
+                    ->end()
                     ->scalarNode(self::DEFAULT_VALUE_ATTRIBUTE_CONFIG_NODE)
-                        ->info('The default value for scalar (i.e. non-array) attributes. If none is specified, an exception is thrown in case none of the source attributes is found.')
+                        ->info('The default value for scalar (i.e. non-array) attributes. If none is specified, an exception is thrown in case the source attribute is not found.')
                     ->end()
                     ->arrayNode(self::DEFAULT_VALUES_ATTRIBUTE_CONFIG_NODE)
                         ->defaultValue(self::ARRAY_VALUE_NOT_SPECIFIED)
-                        ->info('The default value for array type attributes. If none is specified, an exception is thrown in case none of the source attributes is found.')
+                        ->info('The default value for array type attributes. If none is specified, an exception is thrown in case the source attribute is not found.')
                         ->scalarPrototype()->end()
                     ->end()
                 ->end()
@@ -179,7 +182,7 @@ abstract class AbstractLocalDataEventSubscriber extends AbstractAuthorizationSer
         throw new \RuntimeException(sprintf('child classes must implement the \'%s\' method', __METHOD__));
     }
 
-    protected function onPreEvent(LocalDataPreEvent $preEvent)
+    protected function onPreEvent(LocalDataPreEvent $preEvent, array $localQueryParameters)
     {
     }
 
diff --git a/src/LocalData/LocalDataEventDispatcher.php b/src/LocalData/LocalDataEventDispatcher.php
index 6635d57b32fbc8078ff1f2d4d623d6b0a24f412b..93f7d9238890db8e6bb3dc6eede4103b3d6f1570 100644
--- a/src/LocalData/LocalDataEventDispatcher.php
+++ b/src/LocalData/LocalDataEventDispatcher.php
@@ -83,10 +83,10 @@ class LocalDataEventDispatcher
     public function dispatch(Event $event, string $eventName = null): void
     {
         if ($event instanceof LocalDataPreEvent) {
-            $event->initQueryParametersIn($this->queryParameters);
+            $event->initQueryParameters($this->queryParameters);
             $this->eventDispatcher->dispatch($event, $eventName);
 
-            $pendingAttributes = $event->getPendingQueryParametersIn();
+            $pendingAttributes = $event->getPendingQueryParameters();
             if (count($pendingAttributes) !== 0) {
                 throw ApiError::withDetails(Response::HTTP_BAD_REQUEST, sprintf("the following local query attributes were not acknowledged for resource '%s': %s", $this->uniqueEntityName, implode(', ', array_keys($pendingAttributes))));
             }
diff --git a/src/LocalData/LocalDataPreEvent.php b/src/LocalData/LocalDataPreEvent.php
index 9fad9e6088d3df62a89e21b8834a631328240dc7..d548930d9ba8f3c219af16d8775b3589fbb01b87 100644
--- a/src/LocalData/LocalDataPreEvent.php
+++ b/src/LocalData/LocalDataPreEvent.php
@@ -11,45 +11,37 @@ class LocalDataPreEvent extends Event
     /** @var string[] */
     private $queryParametersIn;
 
-    /** @var string[] */
-    private $queryParametersOut;
+    /** @var array */
+    private $options;
 
-    public function __construct()
+    public function __construct(array $options)
     {
         $this->queryParametersIn = [];
-        $this->queryParametersOut = [];
-    }
-
-    /**
-     * @deprecated Use getQueryParametersOut
-     */
-    public function getQueryParameters(): array
-    {
-        return $this->queryParametersOut;
+        $this->options = $options;
     }
 
-    public function initQueryParametersIn(array $queryParametersIn): void
+    public function initQueryParameters(array $queryParametersIn): void
     {
         $this->queryParametersIn = $queryParametersIn;
     }
 
-    public function getPendingQueryParametersIn(): array
+    public function getPendingQueryParameters(): array
     {
         return $this->queryParametersIn;
     }
 
-    public function acknowledgeQueryParameterIn(string $queryParameterName): void
+    public function acknowledgeQueryParameter(string $queryParameterName): void
     {
         unset($this->queryParametersIn[$queryParameterName]);
     }
 
-    public function addQueryParameterOut(string $queryParameterName, string $queryParameterValue): void
+    public function getOptions(): array
     {
-        $this->queryParametersOut[$queryParameterName] = $queryParameterValue;
+        return $this->options;
     }
 
-    public function getQueryParametersOut(): array
+    public function setOptions(array $options): void
     {
-        return $this->queryParametersOut;
+        $this->options = $options;
     }
 }
diff --git a/tests/LocalData/LocalDataTest.php b/tests/LocalData/LocalDataTest.php
index 29fd03e7497d46f4cfcca6d71470f60af7f7f031..06f1d1652ae4fa547ac5337fac78c3c7bf1a86a5 100644
--- a/tests/LocalData/LocalDataTest.php
+++ b/tests/LocalData/LocalDataTest.php
@@ -73,18 +73,6 @@ class LocalDataTest extends TestCase
         $this->assertEquals([0], $testEntity->getLocalDataValue($localDataAttributeName));
     }
 
-    public function testLocalDataMappingFallback()
-    {
-        // first source attribute specified in config is present in source data -> return first source attribute value
-        $localDataAttributeName = 'attribute_2';
-        $testEntity = $this->getTestEntity($localDataAttributeName, ['src_attribute_2_1' => 'value_2_1', 'src_attribute_2_2' => 'value_2_2']);
-        $this->assertEquals('value_2_1', $testEntity->getLocalDataValue($localDataAttributeName));
-
-        // first source attribute specified in config is not present in source data, however second attribute is preset -> return second source attribute value
-        $testEntity = $this->getTestEntity($localDataAttributeName, ['src_attribute_2_2' => 'value_2_2']);
-        $this->assertEquals('value_2_2', $testEntity->getLocalDataValue($localDataAttributeName));
-    }
-
     public function testLocalDataMappingAccessDenied()
     {
         // authorization expression of attribute evaluates to false -> deny access
@@ -106,15 +94,15 @@ class LocalDataTest extends TestCase
         $options[LocalData::QUERY_PARAMETER_NAME] = $localDataAttributeName.':value_1';
 
         $this->localDataEventDispatcher->onNewOperation($options);
-        $preEvent = new TestEntityPreEvent();
+        $preEvent = new TestEntityPreEvent($options);
         $this->localDataEventDispatcher->dispatch($preEvent);
 
-        $filters = $preEvent->getQueryParametersOut();
-        $this->assertArrayHasKey('src_attribute_1', $filters);
-        $this->assertEquals('value_1', $filters['src_attribute_1']);
+        $options = $preEvent->getOptions();
+        $this->assertArrayHasKey('src_attribute_1', $options);
+        $this->assertEquals('value_1', $options['src_attribute_1']);
     }
 
-    public function testLocalDataQueryAttributeUnacknowledged()
+    public function testLocalDataQueryAttributeUnacknowledgedNotConfigure()
     {
         // 'attribute_4' has no configured source attribute.
         // Throw bad request error because no event subscriber acknowledged local query parameter 'attribute_4'.
@@ -125,7 +113,25 @@ class LocalDataTest extends TestCase
 
         try {
             $this->localDataEventDispatcher->onNewOperation($options);
-            $preEvent = new TestEntityPreEvent();
+            $preEvent = new TestEntityPreEvent($options);
+            $this->localDataEventDispatcher->dispatch($preEvent);
+        } catch (ApiError $exception) {
+            $this->assertEquals(Response::HTTP_BAD_REQUEST, $exception->getStatusCode());
+        }
+    }
+
+    public function testLocalDataQueryAttributeUnacknowledgedNotQueryable()
+    {
+        // 'attribute_2' is configured 'allow_query': false (default value)
+        // Throw bad request error because no event subscriber acknowledged local query parameter 'attribute_2'.
+        $localDataAttributeName = 'attribute_2';
+
+        $options = [];
+        $options[LocalData::QUERY_PARAMETER_NAME] = $localDataAttributeName.':value_2';
+
+        try {
+            $this->localDataEventDispatcher->onNewOperation($options);
+            $preEvent = new TestEntityPreEvent($options);
             $this->localDataEventDispatcher->dispatch($preEvent);
         } catch (ApiError $exception) {
             $this->assertEquals(Response::HTTP_BAD_REQUEST, $exception->getStatusCode());
@@ -142,7 +148,7 @@ class LocalDataTest extends TestCase
 
         try {
             $this->localDataEventDispatcher->onNewOperation($options);
-            $preEvent = new TestEntityPreEvent();
+            $preEvent = new TestEntityPreEvent($options);
             $this->localDataEventDispatcher->dispatch($preEvent);
         } catch (ApiError $exception) {
             $this->assertEquals(Response::HTTP_UNAUTHORIZED, $exception->getStatusCode());
@@ -168,24 +174,28 @@ class LocalDataTest extends TestCase
         $config['local_data_mapping'] = [
             [
                 'local_data_attribute' => 'attribute_1',
-                'source_attributes' => ['src_attribute_1'],
+                'source_attribute' => 'src_attribute_1',
                 'authorization_expression' => 'true',
+                'allow_query' => true,
                 'default_value' => 0,
             ],
             [
                 'local_data_attribute' => 'attribute_2',
-                'source_attributes' => ['src_attribute_2_1', 'src_attribute_2_2'],
+                'source_attribute' => 'src_attribute_2_1',
                 'authorization_expression' => 'true',
+                'allow_query' => false,
             ],
             [
                 'local_data_attribute' => 'attribute_3',
-                'source_attributes' => ['src_attribute_3'],
+                'source_attribute' => 'src_attribute_3',
                 'authorization_expression' => 'false',
+                'allow_query' => true,
             ],
             [
                 'local_data_attribute' => 'array_attribute_1',
-                'source_attributes' => ['array_src_attribute_1'],
+                'source_attribute' => 'array_src_attribute_1',
                 'authorization_expression' => 'true',
+                'allow_query' => false,
                 'default_values' => [0],
             ],
         ];
diff --git a/tests/LocalData/TestEntityLocalDataEventSubscriber.php b/tests/LocalData/TestEntityLocalDataEventSubscriber.php
index a85a1d84d6a154592e4147fb2097abc1753c36e8..5263feb2847f00ffc7bbdb964aa71fc684cdf237 100644
--- a/tests/LocalData/TestEntityLocalDataEventSubscriber.php
+++ b/tests/LocalData/TestEntityLocalDataEventSubscriber.php
@@ -5,6 +5,7 @@ declare(strict_types=1);
 namespace Dbp\Relay\CoreBundle\Tests\LocalData;
 
 use Dbp\Relay\CoreBundle\LocalData\AbstractLocalDataPostEventSubscriber;
+use Dbp\Relay\CoreBundle\LocalData\LocalDataPreEvent;
 
 class TestEntityLocalDataEventSubscriber extends AbstractLocalDataPostEventSubscriber
 {
@@ -15,4 +16,9 @@ class TestEntityLocalDataEventSubscriber extends AbstractLocalDataPostEventSubsc
             TestEntityPreEvent::class,
             ];
     }
+
+    protected function onPreEvent(LocalDataPreEvent $preEvent, array $localQueryParameters)
+    {
+        $preEvent->setOptions($localQueryParameters);
+    }
 }