diff --git a/typo3/sysext/core/Documentation/Changelog/13.2/Feature-102869-ListWorkspacesInLiveSearch.rst b/typo3/sysext/core/Documentation/Changelog/13.2/Feature-102869-ListWorkspacesInLiveSearch.rst
new file mode 100644
index 0000000000000000000000000000000000000000..4f7b848f59d164ea1dea60de3e532d910c9c4a2e
--- /dev/null
+++ b/typo3/sysext/core/Documentation/Changelog/13.2/Feature-102869-ListWorkspacesInLiveSearch.rst
@@ -0,0 +1,26 @@
+.. include:: /Includes.rst.txt
+
+.. _feature-102869-1705661913:
+
+================================================
+Feature: #102869 - List workspaces in LiveSearch
+================================================
+
+See :issue:`102869`
+
+Description
+===========
+
+The backend LiveSearch is now able to list workspaces a backend user has access
+to, offering the possibility to switch to a workspace quickly outside the
+Workspaces module.
+
+
+Impact
+======
+
+Backend users now have another, quickly accessible way to access a workspace.
+With proper permissions, a backend user may also switch to the edit interface of
+a workspace to configure its settings.
+
+.. index:: Backend, ext:workspaces
diff --git a/typo3/sysext/workspaces/Classes/Backend/LiveSearch/WorkspaceProvider.php b/typo3/sysext/workspaces/Classes/Backend/LiveSearch/WorkspaceProvider.php
new file mode 100644
index 0000000000000000000000000000000000000000..fdc3c594ad4959e204776a6aef4f8507ec366cd1
--- /dev/null
+++ b/typo3/sysext/workspaces/Classes/Backend/LiveSearch/WorkspaceProvider.php
@@ -0,0 +1,142 @@
+<?php
+
+declare(strict_types=1);
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+namespace TYPO3\CMS\Workspaces\Backend\LiveSearch;
+
+use Symfony\Component\DependencyInjection\Attribute\Autowire;
+use TYPO3\CMS\Backend\Routing\UriBuilder;
+use TYPO3\CMS\Backend\Search\LiveSearch\ResultItem;
+use TYPO3\CMS\Backend\Search\LiveSearch\ResultItemAction;
+use TYPO3\CMS\Backend\Search\LiveSearch\SearchDemand\SearchDemand;
+use TYPO3\CMS\Backend\Search\LiveSearch\SearchProviderInterface;
+use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
+use TYPO3\CMS\Core\Cache\Frontend\FrontendInterface;
+use TYPO3\CMS\Core\Imaging\IconFactory;
+use TYPO3\CMS\Core\Imaging\IconSize;
+use TYPO3\CMS\Core\Localization\LanguageService;
+use TYPO3\CMS\Core\Localization\LanguageServiceFactory;
+use TYPO3\CMS\Workspaces\Service\WorkspaceService;
+
+/**
+ * Search provider to query workspaces from database
+ *
+ * @internal
+ */
+final readonly class WorkspaceProvider implements SearchProviderInterface
+{
+    private LanguageService $languageService;
+
+    public function __construct(
+        #[Autowire(service: 'cache.runtime')]
+        private FrontendInterface $runtimeCache,
+        private WorkspaceService $workspaceService,
+        private UriBuilder $uriBuilder,
+        private IconFactory $iconFactory,
+        private LanguageServiceFactory $languageServiceFactory,
+    ) {
+        $this->languageService = $this->languageServiceFactory->createFromUserPreferences($this->getBackendUser());
+    }
+
+    public function count(SearchDemand $searchDemand): int
+    {
+        return count($this->getFilteredWorkspaces($searchDemand));
+    }
+
+    public function find(SearchDemand $searchDemand): array
+    {
+        $icon = $this->iconFactory->getIcon('mimetypes-x-sys_workspace', IconSize::SMALL);
+        $typeLabel = $this->languageService->sL($GLOBALS['TCA']['sys_workspace']['ctrl']['title']);
+        $workspaces = $this->getFilteredWorkspaces($searchDemand);
+        $items = [];
+
+        foreach ($workspaces as $workspaceId => $workspaceLabel) {
+            $actions = [];
+            $actions[] = (new ResultItemAction('open_workspace'))
+                ->setLabel($this->languageService->sL('LLL:EXT:workspaces/Resources/Private/Language/locallang.xlf:action.switchToWorkspace'))
+                ->setUrl((string)$this->uriBuilder->buildUriFromRoute('workspaces_admin', [
+                    'workspace' => $workspaceId,
+                    'id' => $searchDemand->getPageId(),
+                ]))
+            ;
+
+            if ($workspaceId > 0 && $this->getBackendUser()->isAdmin()) {
+                $editWorkspaceRecordUrl = (string)$this->uriBuilder->buildUriFromRoute('record_edit', [
+                    'edit' => [
+                        'sys_workspace' => [
+                            $workspaceId => 'edit',
+                        ],
+                    ],
+                    'returnUrl' => (string)$this->uriBuilder->buildUriFromRoute('workspaces_admin', ['id' => $searchDemand->getPageId()]),
+                ]);
+
+                $actions[] = (new ResultItemAction('configure_workspace'))
+                    ->setLabel($this->languageService->sL('LLL:EXT:workspaces/Resources/Private/Language/locallang.xlf:button.editWorkspaceSettings'))
+                    ->setIcon($this->iconFactory->getIcon('actions-cog-alt', IconSize::SMALL))
+                    ->setUrl($editWorkspaceRecordUrl);
+            }
+
+            $items[] = (new ResultItem(self::class))
+                ->setItemTitle($workspaceLabel)
+                ->setTypeLabel($typeLabel)
+                ->setIcon($icon)
+                ->setActions(...$actions);
+        }
+
+        return $items;
+    }
+
+    public function getFilterLabel(): string
+    {
+        return $this->languageService->sL($GLOBALS['TCA']['sys_workspace']['ctrl']['title']);
+    }
+
+    private function getAvailableWorkspaces(): array
+    {
+        $cacheId = 'available-workspaces-' . hash('xxh3', $this->getBackendUser()->name);
+        $availableWorkspaces = $this->runtimeCache->get($cacheId);
+        if ($availableWorkspaces === false) {
+            $availableWorkspaces = $this->workspaceService->getAvailableWorkspaces();
+            $this->runtimeCache->set($cacheId, $availableWorkspaces);
+        }
+
+        return $availableWorkspaces;
+    }
+
+    private function getFilteredWorkspaces(SearchDemand $searchDemand): array
+    {
+        // @todo: This isn't nice. The interface should rather have an `canAccess()` method to check whether the current
+        //        backend user is permitted to use a provider at all.
+        if (count($this->getAvailableWorkspaces()) <= 1) {
+            return [];
+        }
+
+        $filteredWorkspaces = array_filter(
+            $this->getAvailableWorkspaces(),
+            static fn(string $workspaceName) => str_contains(mb_strtolower($workspaceName), mb_strtolower($searchDemand->getQuery()))
+        );
+
+        $firstResult = $searchDemand->getOffset();
+        $remainingItems = $searchDemand->getLimit();
+
+        return array_slice($filteredWorkspaces, $firstResult, $remainingItems, true);
+    }
+
+    private function getBackendUser(): BackendUserAuthentication
+    {
+        return $GLOBALS['BE_USER'];
+    }
+}
diff --git a/typo3/sysext/workspaces/Resources/Private/Language/locallang.xlf b/typo3/sysext/workspaces/Resources/Private/Language/locallang.xlf
index 3e9364b4e0757bec3bcdb1634b23303c391041d5..8b664c456c7e814d7fec5893833a3b82dfbcfed2 100644
--- a/typo3/sysext/workspaces/Resources/Private/Language/locallang.xlf
+++ b/typo3/sysext/workspaces/Resources/Private/Language/locallang.xlf
@@ -393,6 +393,9 @@
 			<trans-unit id="moduleMenu.dropdown.label" resname="moduleMenu.dropdown.label">
 				<source>Selected workspace</source>
 			</trans-unit>
+			<trans-unit id="action.switchToWorkspace" resname="action.switchToWorkspace">
+				<source>Switch to workspace</source>
+			</trans-unit>
 		</body>
 	</file>
 </xliff>