diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 75e71e414262435f417434ace60c7c6f709621df..9ac1e9f58dbca396aa65d4b21b723b8c6dfd560c 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -730,6 +730,9 @@
     <!-- Whether the communal service should be enabled -->
     <bool name="config_communalServiceEnabled">false</bool>
 
+    <!-- Component names of allowed communal widgets -->
+    <string-array name="config_communalWidgetAllowlist" translatable="false" />
+
     <!-- Component name of communal source service -->
     <string name="config_communalSourceComponent" translatable="false">@null</string>
 
diff --git a/packages/SystemUI/src/com/android/systemui/communal/data/model/CommunalWidgetMetadata.kt b/packages/SystemUI/src/com/android/systemui/communal/data/model/CommunalWidgetMetadata.kt
new file mode 100644
index 0000000000000000000000000000000000000000..f9c4f29afee9e28b3c2723dd3e05519fb6c96d01
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/communal/data/model/CommunalWidgetMetadata.kt
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.communal.data.model
+
+import com.android.systemui.communal.shared.CommunalContentSize
+
+/** Metadata for the default widgets */
+data class CommunalWidgetMetadata(
+    /* Widget provider component name */
+    val componentName: String,
+
+    /* Defines the order in which the widget will be rendered in the grid. */
+    val priority: Int,
+
+    /* Supported sizes */
+    val sizes: List<CommunalContentSize>
+)
diff --git a/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalWidgetRepository.kt b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalWidgetRepository.kt
index e2a7d077a32c7adb399b0c6d28f72a611fdee94a..f13b62fbfeb90a8dc5a5a5d3cf0b91c4dc563ddf 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalWidgetRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalWidgetRepository.kt
@@ -27,13 +27,17 @@ import android.content.pm.PackageManager
 import android.os.UserManager
 import com.android.systemui.broadcast.BroadcastDispatcher
 import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
+import com.android.systemui.communal.data.model.CommunalWidgetMetadata
 import com.android.systemui.communal.shared.CommunalAppWidgetInfo
+import com.android.systemui.communal.shared.CommunalContentSize
 import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.flags.Flags
 import com.android.systemui.log.LogBuffer
 import com.android.systemui.log.core.Logger
 import com.android.systemui.log.dagger.CommunalLog
+import com.android.systemui.res.R
 import com.android.systemui.settings.UserTracker
 import javax.inject.Inject
 import kotlinx.coroutines.channels.awaitClose
@@ -45,15 +49,20 @@ import kotlinx.coroutines.flow.map
 interface CommunalWidgetRepository {
     /** A flow of provider info for the stopwatch widget, or null if widget is unavailable. */
     val stopwatchAppWidgetInfo: Flow<CommunalAppWidgetInfo?>
+
+    /** Widgets that are allowed to render in the glanceable hub */
+    val communalWidgetAllowlist: List<CommunalWidgetMetadata>
 }
 
 @SysUISingleton
 class CommunalWidgetRepositoryImpl
 @Inject
 constructor(
+    @Application private val applicationContext: Context,
     private val appWidgetManager: AppWidgetManager,
     private val appWidgetHost: AppWidgetHost,
     broadcastDispatcher: BroadcastDispatcher,
+    communalRepository: CommunalRepository,
     private val packageManager: PackageManager,
     private val userManager: UserManager,
     private val userTracker: UserTracker,
@@ -64,12 +73,18 @@ constructor(
         const val TAG = "CommunalWidgetRepository"
         const val WIDGET_LABEL = "Stopwatch"
     }
+    override val communalWidgetAllowlist: List<CommunalWidgetMetadata>
 
     private val logger = Logger(logBuffer, TAG)
 
     // Whether the [AppWidgetHost] is listening for updates.
     private var isHostListening = false
 
+    init {
+        communalWidgetAllowlist =
+            if (communalRepository.isCommunalEnabled) getWidgetAllowlist() else emptyList()
+    }
+
     // Widgets that should be rendered in communal mode.
     private val widgets: HashMap<Int, CommunalAppWidgetInfo> = hashMapOf()
 
@@ -129,6 +144,18 @@ constructor(
             return@map addWidget(providerInfo)
         }
 
+    private fun getWidgetAllowlist(): List<CommunalWidgetMetadata> {
+        val componentNames =
+            applicationContext.resources.getStringArray(R.array.config_communalWidgetAllowlist)
+        return componentNames.mapIndexed { index, name ->
+            CommunalWidgetMetadata(
+                componentName = name,
+                priority = componentNames.size - index,
+                sizes = listOf(CommunalContentSize.HALF)
+            )
+        }
+    }
+
     private fun startListening() {
         if (isHostListening) {
             return
diff --git a/packages/SystemUI/src/com/android/systemui/communal/shared/CommunalContentSize.kt b/packages/SystemUI/src/com/android/systemui/communal/shared/CommunalContentSize.kt
new file mode 100644
index 0000000000000000000000000000000000000000..0bd7d86c972d28c125108d4f577878cd6a03179d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/communal/shared/CommunalContentSize.kt
@@ -0,0 +1,8 @@
+package com.android.systemui.communal.shared
+
+/** Supported sizes for communal content in the layout grid. */
+enum class CommunalContentSize {
+    FULL,
+    HALF,
+    THIRD,
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/communal/data/repository/CommunalWidgetRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/communal/data/repository/CommunalWidgetRepositoryImplTest.kt
index 3df9cbb29e4aeb17a0897983913a7fbbdae6f9c4..91409a37655685dec6049d9b49857dfe6454b0ac 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/communal/data/repository/CommunalWidgetRepositoryImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/communal/data/repository/CommunalWidgetRepositoryImplTest.kt
@@ -11,11 +11,14 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.broadcast.BroadcastDispatcher
+import com.android.systemui.communal.data.model.CommunalWidgetMetadata
+import com.android.systemui.communal.shared.CommunalContentSize
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.flags.Flags
 import com.android.systemui.log.LogBuffer
 import com.android.systemui.log.core.FakeLogBuffer
+import com.android.systemui.res.R
 import com.android.systemui.settings.UserTracker
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.kotlinArgumentCaptor
@@ -59,9 +62,12 @@ class CommunalWidgetRepositoryImplTest : SysuiTestCase() {
 
     @Mock private lateinit var stopwatchProviderInfo: AppWidgetProviderInfo
 
+    private lateinit var communalRepository: FakeCommunalRepository
+
     private lateinit var logBuffer: LogBuffer
 
     private val testDispatcher = StandardTestDispatcher()
+
     private val testScope = TestScope(testDispatcher)
 
     @Before
@@ -71,6 +77,14 @@ class CommunalWidgetRepositoryImplTest : SysuiTestCase() {
         logBuffer = FakeLogBuffer.Factory.create()
 
         featureFlagEnabled(true)
+        communalRepository = FakeCommunalRepository()
+        communalRepository.setIsCommunalEnabled(true)
+
+        overrideResource(
+            R.array.config_communalWidgetAllowlist,
+            arrayOf(componentName1, componentName2)
+        )
+
         whenever(stopwatchProviderInfo.loadLabel(any())).thenReturn("Stopwatch")
         whenever(userTracker.userHandle).thenReturn(userHandle)
     }
@@ -219,11 +233,36 @@ class CommunalWidgetRepositoryImplTest : SysuiTestCase() {
             Mockito.verify(appWidgetHost).stopListening()
         }
 
+    @Test
+    fun getCommunalWidgetAllowList_onInit() {
+        testScope.runTest {
+            val repository = initCommunalWidgetRepository()
+            val communalWidgetAllowlist = repository.communalWidgetAllowlist
+            assertThat(
+                    listOf(
+                        CommunalWidgetMetadata(
+                            componentName = componentName1,
+                            priority = 2,
+                            sizes = listOf(CommunalContentSize.HALF)
+                        ),
+                        CommunalWidgetMetadata(
+                            componentName = componentName2,
+                            priority = 1,
+                            sizes = listOf(CommunalContentSize.HALF)
+                        )
+                    )
+                )
+                .containsExactly(*communalWidgetAllowlist.toTypedArray())
+        }
+    }
+
     private fun initCommunalWidgetRepository(): CommunalWidgetRepositoryImpl {
         return CommunalWidgetRepositoryImpl(
+            context,
             appWidgetManager,
             appWidgetHost,
             broadcastDispatcher,
+            communalRepository,
             packageManager,
             userManager,
             userTracker,
@@ -282,4 +321,9 @@ class CommunalWidgetRepositoryImplTest : SysuiTestCase() {
     private fun installedProviders(providers: List<AppWidgetProviderInfo>) {
         whenever(appWidgetManager.installedProviders).thenReturn(providers)
     }
+
+    companion object {
+        const val componentName1 = "component name 1"
+        const val componentName2 = "component name 2"
+    }
 }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/FakeCommunalWidgetRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/FakeCommunalWidgetRepository.kt
index 1a8c5830e453e0aceba2aaa93eb634fd78268762..30132f7747b7e2356d1658a466bb3b7893b72fbb 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/FakeCommunalWidgetRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/FakeCommunalWidgetRepository.kt
@@ -1,5 +1,6 @@
 package com.android.systemui.communal.data.repository
 
+import com.android.systemui.communal.data.model.CommunalWidgetMetadata
 import com.android.systemui.communal.shared.CommunalAppWidgetInfo
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.MutableStateFlow
@@ -8,6 +9,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
 class FakeCommunalWidgetRepository : CommunalWidgetRepository {
     private val _stopwatchAppWidgetInfo = MutableStateFlow<CommunalAppWidgetInfo?>(null)
     override val stopwatchAppWidgetInfo: Flow<CommunalAppWidgetInfo?> = _stopwatchAppWidgetInfo
+    override var communalWidgetAllowlist: List<CommunalWidgetMetadata> = emptyList()
 
     fun setStopwatchAppWidgetInfo(appWidgetInfo: CommunalAppWidgetInfo) {
         _stopwatchAppWidgetInfo.value = appWidgetInfo