diff --git a/core/modules/menu_ui/src/Hook/MenuUiHooks.php b/core/modules/menu_ui/src/Hook/MenuUiHooks.php
index ac7c7602f3be8edd09f97598777659bbbab33983..9b32ffa182476332a0516980346f9d09bad7f223 100644
--- a/core/modules/menu_ui/src/Hook/MenuUiHooks.php
+++ b/core/modules/menu_ui/src/Hook/MenuUiHooks.php
@@ -16,6 +16,9 @@
 use Drupal\Core\Url;
 use Drupal\Core\Routing\RouteMatchInterface;
 use Drupal\Core\Hook\Attribute\Hook;
+use Drupal\menu_link_content\Entity\MenuLinkContent;
+use Drupal\Core\Access\AccessResultInterface;
+use Drupal\Core\Entity\EntityTypeManagerInterface;
 
 /**
  * Hook implementations for menu_ui.
@@ -24,6 +27,16 @@ class MenuUiHooks {
 
   use StringTranslationTrait;
 
+  /**
+   * Constructs a new MenuUiHooks object.
+   *
+   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
+   *   The entity type manager.
+   */
+  public function __construct(
+    protected EntityTypeManagerInterface $entityTypeManager,
+  ) {}
+
   /**
    * Implements hook_help().
    */
@@ -86,6 +99,27 @@ public function blockViewSystemMenuBlockAlter(array &$build, BlockPluginInterfac
     }
   }
 
+  /**
+   * Check if user is allowed to use the menu link subform.
+   *
+   * @param array $defaults
+   *   An array that contains default values for the menu link form.
+   *
+   * @see menu_ui_get_menu_link_defaults()
+   */
+  protected function getMenuLinkContentAccess(array $defaults): AccessResultInterface {
+    if (!empty($defaults['entity_id'])) {
+      $entity = MenuLinkContent::load($defaults['entity_id']);
+
+      // The form can be used to edit or delete the menu link.
+      return $entity->access('update', NULL, TRUE)->andIf($entity->access('delete', NULL, TRUE));
+    }
+    else {
+      // If the node has no corresponding menu link, users needs to permission to create one.
+      return $this->entityTypeManager->getAccessControlHandler('menu_link_content')->createAccess(NULL, NULL, [], TRUE);
+    }
+  }
+
   /**
    * Implements hook_form_BASE_FORM_ID_alter() for \Drupal\node\NodeForm.
    *
@@ -128,7 +162,7 @@ public function formNodeFormAlter(&$form, FormStateInterface $form_state) : void
     $form['menu'] = [
       '#type' => 'details',
       '#title' => $this->t('Menu settings'),
-      '#access' => \Drupal::currentUser()->hasPermission('administer menu'),
+      '#access' => $this->getMenuLinkContentAccess($defaults),
       '#open' => (bool) $defaults['id'],
       '#group' => 'advanced',
       '#attached' => [
diff --git a/core/modules/menu_ui/tests/modules/menu_link_access_test/menu_link_access_test.info.yml b/core/modules/menu_ui/tests/modules/menu_link_access_test/menu_link_access_test.info.yml
new file mode 100644
index 0000000000000000000000000000000000000000..36ba82e667713b87941c2c348979e4c70503d0e0
--- /dev/null
+++ b/core/modules/menu_ui/tests/modules/menu_link_access_test/menu_link_access_test.info.yml
@@ -0,0 +1,4 @@
+name: 'Tests menu link access'
+type: module
+package: Testing
+version: VERSION
diff --git a/core/modules/menu_ui/tests/modules/menu_link_access_test/src/Hook/MenuLinkAccessTestHooks.php b/core/modules/menu_ui/tests/modules/menu_link_access_test/src/Hook/MenuLinkAccessTestHooks.php
new file mode 100644
index 0000000000000000000000000000000000000000..586d2a793691dfb94efdee6a489bb86b6742cf61
--- /dev/null
+++ b/core/modules/menu_ui/tests/modules/menu_link_access_test/src/Hook/MenuLinkAccessTestHooks.php
@@ -0,0 +1,38 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Drupal\menu_link_access_test\Hook;
+
+use Drupal\Core\Access\AccessResult;
+use Drupal\Core\Access\AccessResultInterface;
+use Drupal\Core\Session\AccountInterface;
+use Drupal\Core\Entity\EntityInterface;
+use Drupal\Core\Hook\Attribute\Hook;
+
+/**
+ * Hook implementations for menu_link_access_test.
+ */
+class MenuLinkAccessTestHooks {
+
+  /**
+   * Implements hook_ENTITY_TYPE_access().
+   */
+  #[Hook('menu_link_content_access')]
+  public function entityTestAccess(EntityInterface $entity, $operation, AccountInterface $account): AccessResultInterface {
+    if (in_array($operation, ['update', 'delete'])) {
+      return AccessResult::forbidden();
+    }
+
+    return AccessResult::neutral();
+  }
+
+  /**
+   * Implements hook_ENTITY_TYPE_create_access().
+   */
+  #[Hook('menu_link_content_create_access')]
+  public function entityTestCreateAccess(AccountInterface $account, $context, $entity_bundle): AccessResultInterface {
+    return AccessResult::forbidden();
+  }
+
+}
diff --git a/core/modules/menu_ui/tests/src/Functional/MenuUiNodeAccessTest.php b/core/modules/menu_ui/tests/src/Functional/MenuUiNodeAccessTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..93acdc88754f03ecbc16ef90ec955d32ea8ced67
--- /dev/null
+++ b/core/modules/menu_ui/tests/src/Functional/MenuUiNodeAccessTest.php
@@ -0,0 +1,88 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Drupal\Tests\menu_ui\Functional;
+
+use Drupal\menu_link_content\Entity\MenuLinkContent;
+use Drupal\node\Entity\Node;
+use Drupal\Tests\BrowserTestBase;
+
+/**
+ * Edit a node when you don't have permission to add or edit menu links.
+ *
+ * @group menu_ui
+ */
+class MenuUiNodeAccessTest extends BrowserTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $modules = [
+    'menu_ui',
+    'test_page_test',
+    'node',
+    'menu_link_access_test',
+  ];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected $defaultTheme = 'stark';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp(): void {
+    parent::setUp();
+
+    $this->drupalCreateContentType(['type' => 'page', 'name' => 'Basic page']);
+  }
+
+  /**
+   * Tests menu link create access is enforced.
+   */
+  public function testMenuLinkCreateAccess(): void {
+    $this->drupalLogin($this->drupalCreateUser([
+      'administer menu',
+      'edit any page content',
+    ]));
+    $node = Node::create([
+      'type' => 'page',
+      'title' => $this->randomMachineName(),
+      'uid' => $this->rootUser->id(),
+      'status' => 1,
+    ]);
+    $node->save();
+
+    $this->drupalGet('node/' . $node->id() . '/edit');
+    $this->assertSession()->elementNotExists('css', 'input[name="menu[title]"]');
+  }
+
+  /**
+   * Tests menu link edit/delete access is enforced.
+   */
+  public function testMenuLinkEditAccess(): void {
+    $this->drupalLogin($this->drupalCreateUser([
+      'administer menu',
+      'edit any page content',
+    ]));
+    $mainLinkTitle = $this->randomMachineName();
+    $node = Node::create([
+      'type' => 'page',
+      'title' => $this->randomMachineName(),
+      'uid' => $this->rootUser->id(),
+      'status' => 1,
+    ]);
+    $node->save();
+    MenuLinkContent::create([
+      'link' => [['uri' => 'entity:node/' . $node->id()]],
+      'title' => $mainLinkTitle,
+      'menu_name' => 'main',
+    ])->save();
+
+    $this->drupalGet('node/' . $node->id() . '/edit');
+    $this->assertSession()->elementNotExists('css', 'input[name="menu[title]"]');
+  }
+
+}
diff --git a/core/modules/menu_ui/tests/src/Functional/MenuUiNodeTest.php b/core/modules/menu_ui/tests/src/Functional/MenuUiNodeTest.php
index 69b11f376d03e41b650b65f42fb0f62060a1f04a..0025ae08718c9e0673ba495b99551b5151db0794 100644
--- a/core/modules/menu_ui/tests/src/Functional/MenuUiNodeTest.php
+++ b/core/modules/menu_ui/tests/src/Functional/MenuUiNodeTest.php
@@ -191,7 +191,9 @@ public function testMenuNodeFormWidget(): void {
     $this->drupalGet('test-page');
     $this->assertSession()->linkNotExists($node_title, 'Found no menu link with the node unpublished');
     // Assert that the link exists if published.
-    $edit['status[value]'] = TRUE;
+    $edit = [
+      'status[value]' => TRUE,
+    ];
     $this->drupalGet('node/' . $node->id() . '/edit');
     $this->submitForm($edit, 'Save');
     $this->drupalGet('test-page');
diff --git a/core/modules/menu_ui/tests/src/Kernel/MenuBlockTest.php b/core/modules/menu_ui/tests/src/Kernel/MenuBlockTest.php
index f87a2639b877248c6616d7daeb8204e1ae1dfc6f..f3f6d51e512e12cd973a0a4440d0dc44f68ce9d2 100644
--- a/core/modules/menu_ui/tests/src/Kernel/MenuBlockTest.php
+++ b/core/modules/menu_ui/tests/src/Kernel/MenuBlockTest.php
@@ -71,7 +71,7 @@ public function testOperationLinks(): void {
     ]);
 
     // Test when user does have "administer menu" permission.
-    $menuUiEntityOperation = new MenuUiHooks();
+    $menuUiEntityOperation = new MenuUiHooks(\Drupal::entityTypeManager());
     $this->assertEquals([
       'menu-edit' => [
         'title' => 'Edit menu',