diff --git chrome/browser/background_fetch/background_fetch_permission_context.cc chrome/browser/background_fetch/background_fetch_permission_context.cc
index 0a5aef10879ac..1b122c8848c97 100644
--- chrome/browser/background_fetch/background_fetch_permission_context.cc
+++ chrome/browser/background_fetch/background_fetch_permission_context.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/browser/background_fetch/background_fetch_permission_context.h"
 
+#include "cef/libcef/features/runtime.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/content_settings/host_content_settings_map_factory.h"
 #include "chrome/browser/download/download_request_limiter.h"
@@ -25,7 +26,8 @@ ContentSetting BackgroundFetchPermissionContext::GetPermissionStatusInternal(
     const GURL& embedding_origin) const {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
-  if (render_frame_host && !render_frame_host->GetParent()) {
+  if (!cef::IsAlloyRuntimeEnabled() &&
+      render_frame_host && !render_frame_host->GetParent()) {
     DownloadRequestLimiter* limiter =
         g_browser_process->download_request_limiter();
     DCHECK(limiter);
diff --git chrome/browser/background_sync/periodic_background_sync_permission_context.cc chrome/browser/background_sync/periodic_background_sync_permission_context.cc
index 16107572d4d0d..409e9ea870482 100644
--- chrome/browser/background_sync/periodic_background_sync_permission_context.cc
+++ chrome/browser/background_sync/periodic_background_sync_permission_context.cc
@@ -6,6 +6,7 @@
 
 #include "base/feature_list.h"
 #include "build/build_config.h"
+#include "cef/libcef/features/runtime.h"
 #include "chrome/browser/content_settings/host_content_settings_map_factory.h"
 #include "chrome/browser/installable/installable_utils.h"
 #include "chrome/browser/profiles/profile.h"
@@ -89,6 +90,10 @@ PeriodicBackgroundSyncPermissionContext::GetPermissionStatusInternal(
     return CONTENT_SETTING_ALLOW;
 #endif
 
+  if (cef::IsAlloyRuntimeEnabled()) {
+    return CONTENT_SETTING_BLOCK;
+  }
+
   bool can_bypass_install_requirement =
       base::FeatureList::IsEnabled(
           features::kPeriodicSyncPermissionForDefaultSearchEngine) &&
diff --git chrome/browser/permissions/chrome_permissions_client.cc chrome/browser/permissions/chrome_permissions_client.cc
index dfc443d307d52..4eb3b286b9838 100644
--- chrome/browser/permissions/chrome_permissions_client.cc
+++ chrome/browser/permissions/chrome_permissions_client.cc
@@ -14,6 +14,7 @@
 #include "base/time/time.h"
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
+#include "cef/libcef/features/runtime.h"
 #include "chrome/browser/bluetooth/bluetooth_chooser_context_factory.h"
 #include "chrome/browser/content_settings/cookie_settings_factory.h"
 #include "chrome/browser/content_settings/host_content_settings_map_factory.h"
@@ -175,6 +176,9 @@ ChromePermissionsClient::GetPermissionDecisionAutoBlocker(
 double ChromePermissionsClient::GetSiteEngagementScore(
     content::BrowserContext* browser_context,
     const GURL& origin) {
+  // No SiteEngagementService with the Alloy runtime.
+  if (cef::IsAlloyRuntimeEnabled())
+    return 0.0;
   return site_engagement::SiteEngagementService::Get(
              Profile::FromBrowserContext(browser_context))
       ->GetScore(origin);
@@ -331,8 +335,10 @@ ChromePermissionsClient::CreatePermissionUiSelectors(
       std::make_unique<ContextualNotificationPermissionUiSelector>());
   selectors.emplace_back(std::make_unique<PrefNotificationPermissionUiSelector>(
       Profile::FromBrowserContext(browser_context)));
+  if (!cef::IsAlloyRuntimeEnabled()) {
   selectors.emplace_back(std::make_unique<PredictionBasedPermissionUiSelector>(
       Profile::FromBrowserContext(browser_context)));
+  }
   return selectors;
 }
 
diff --git chrome/browser/permissions/permission_manager_factory.cc chrome/browser/permissions/permission_manager_factory.cc
index a6d47eebe0ba6..111a2e52df96f 100644
--- chrome/browser/permissions/permission_manager_factory.cc
+++ chrome/browser/permissions/permission_manager_factory.cc
@@ -6,6 +6,7 @@
 
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
+#include "cef/libcef/features/runtime.h"
 #include "chrome/browser/background_fetch/background_fetch_permission_context.h"
 #include "chrome/browser/background_sync/periodic_background_sync_permission_context.h"
 #include "chrome/browser/content_settings/host_content_settings_map_factory.h"
@@ -59,8 +60,10 @@ permissions::PermissionManager::PermissionContextMap CreatePermissionContexts(
       std::make_unique<GeolocationPermissionContextDelegate>(profile);
 #endif  // BUILDFLAG(IS_ANDROID)
 #if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_CHROMEOS)
+  if (!cef::IsAlloyRuntimeEnabled()) {
   delegates.geolocation_manager = g_browser_process->geolocation_manager();
   DCHECK(delegates.geolocation_manager);
+  }
 #endif
   delegates.media_stream_device_enumerator =
       MediaCaptureDevicesDispatcher::GetInstance();
diff --git chrome/browser/storage/durable_storage_permission_context.cc chrome/browser/storage/durable_storage_permission_context.cc
index c96408b160973..8bda825517235 100644
--- chrome/browser/storage/durable_storage_permission_context.cc
+++ chrome/browser/storage/durable_storage_permission_context.cc
@@ -8,6 +8,7 @@
 
 #include "base/check_op.h"
 #include "base/containers/contains.h"
+#include "cef/libcef/features/runtime.h"
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
 #include "chrome/browser/content_settings/cookie_settings_factory.h"
 #include "chrome/browser/content_settings/host_content_settings_map_factory.h"
@@ -56,7 +57,9 @@ void DurableStoragePermissionContext::DecidePermission(
 
   // Durable is only allowed to be granted to the top-level origin. Embedding
   // origin is the last committed navigation origin to the web contents.
-  if (requesting_origin != embedding_origin) {
+  // Permission depends on PWA and site engagement subsystems which are not
+  // supported by the Alloy runtime (see issue #3379).
+  if (cef::IsAlloyRuntimeEnabled() || requesting_origin != embedding_origin) {
     NotifyPermissionSet(id, requesting_origin, embedding_origin,
                         std::move(callback), /*persist=*/false,
                         CONTENT_SETTING_DEFAULT, /*is_one_time=*/false,
diff --git chrome/browser/ui/permission_bubble/permission_prompt.h chrome/browser/ui/permission_bubble/permission_prompt.h
index fbce13c16ad10..0512b2f09937e 100644
--- chrome/browser/ui/permission_bubble/permission_prompt.h
+++ chrome/browser/ui/permission_bubble/permission_prompt.h
@@ -11,6 +11,13 @@ namespace content {
 class WebContents;
 }
 
+using CreatePermissionPromptFunctionPtr =
+    std::unique_ptr<permissions::PermissionPrompt> (*)(
+        content::WebContents* web_contents,
+        permissions::PermissionPrompt::Delegate* delegate,
+        bool* default_handling);
+void SetCreatePermissionPromptFunction(CreatePermissionPromptFunctionPtr);
+
 // Factory function to create permission prompts for chrome.
 std::unique_ptr<permissions::PermissionPrompt> CreatePermissionPrompt(
     content::WebContents* web_contents,
diff --git chrome/browser/ui/views/permissions/permission_prompt_factory.cc chrome/browser/ui/views/permissions/permission_prompt_factory.cc
index 82a50b7e22dfe..c4ba55ec6bd54 100644
--- chrome/browser/ui/views/permissions/permission_prompt_factory.cc
+++ chrome/browser/ui/views/permissions/permission_prompt_factory.cc
@@ -158,11 +158,28 @@ std::unique_ptr<permissions::PermissionPrompt> CreateQuietPrompt(
   }
 }
 
+CreatePermissionPromptFunctionPtr g_create_permission_prompt_ptr = nullptr;
+
 }  // namespace
 
+void SetCreatePermissionPromptFunction(
+    CreatePermissionPromptFunctionPtr ptr) {
+  g_create_permission_prompt_ptr = ptr;
+}
+
 std::unique_ptr<permissions::PermissionPrompt> CreatePermissionPrompt(
     content::WebContents* web_contents,
     permissions::PermissionPrompt::Delegate* delegate) {
+  if (g_create_permission_prompt_ptr) {
+    bool default_handling = true;
+    auto prompt = g_create_permission_prompt_ptr(web_contents, delegate,
+                                                 &default_handling);
+    if (prompt)
+      return prompt;
+    if (!default_handling)
+      return nullptr;
+  }
+
   Browser* browser = chrome::FindBrowserWithWebContents(web_contents);
   if (!browser) {
     DLOG(WARNING) << "Permission prompt suppressed because the WebContents is "
diff --git components/embedder_support/permission_context_utils.cc components/embedder_support/permission_context_utils.cc
index ff8391841fc28..08562a3a03aef 100644
--- components/embedder_support/permission_context_utils.cc
+++ components/embedder_support/permission_context_utils.cc
@@ -5,6 +5,7 @@
 #include "components/embedder_support/permission_context_utils.h"
 
 #include "build/build_config.h"
+#include "cef/libcef/features/runtime.h"
 #include "components/background_sync/background_sync_permission_context.h"
 #include "components/permissions/contexts/accessibility_permission_context.h"
 #include "components/permissions/contexts/camera_pan_tilt_zoom_permission_context.h"
@@ -75,12 +76,19 @@ CreateDefaultPermissionContexts(content::BrowserContext* browser_context,
           browser_context,
           std::move(delegates.geolocation_permission_context_delegate));
 #elif BUILDFLAG(IS_MAC) || BUILDFLAG(IS_CHROMEOS)
+  if (cef::IsAlloyRuntimeEnabled()) {
+    permission_contexts[ContentSettingsType::GEOLOCATION] =
+        std::make_unique<permissions::GeolocationPermissionContext>(
+            browser_context,
+            std::move(delegates.geolocation_permission_context_delegate));
+  } else {
   DCHECK(delegates.geolocation_manager);
   permission_contexts[ContentSettingsType::GEOLOCATION] =
       std::make_unique<permissions::GeolocationPermissionContextSystem>(
           browser_context,
           std::move(delegates.geolocation_permission_context_delegate),
           delegates.geolocation_manager);
+  }
 #else
   permission_contexts[ContentSettingsType::GEOLOCATION] =
       std::make_unique<permissions::GeolocationPermissionContext>(