diff --git a/core/lib/Drupal/Core/Access/RouteProcessorCsrf.php b/core/lib/Drupal/Core/Access/RouteProcessorCsrf.php
index d0aec30185..f2975bb922 100644
--- a/core/lib/Drupal/Core/Access/RouteProcessorCsrf.php
+++ b/core/lib/Drupal/Core/Access/RouteProcessorCsrf.php
@@ -4,14 +4,14 @@
 
 use Drupal\Component\Utility\Crypt;
 use Drupal\Core\Render\BubbleableMetadata;
-use Drupal\Core\Security\TrustedCallbackInterface;
+use Drupal\Core\Security\Attribute\TrustedCallback;
 use Drupal\Core\RouteProcessor\OutboundRouteProcessorInterface;
 use Symfony\Component\Routing\Route;
 
 /**
  * Processes the outbound route to handle the CSRF token.
  */
-class RouteProcessorCsrf implements OutboundRouteProcessorInterface, TrustedCallbackInterface {
+class RouteProcessorCsrf implements OutboundRouteProcessorInterface {
 
   /**
    * The CSRF token generator.
@@ -70,6 +70,7 @@ public function processOutbound($route_name, Route $route, array &$parameters, B
    * @return array
    *   A renderable array representing the CSRF token.
    */
+  #[TrustedCallback]
   public function renderPlaceholderCsrfToken($path) {
     return [
       '#markup' => $this->csrfToken->get($path),
@@ -82,11 +83,4 @@ public function renderPlaceholderCsrfToken($path) {
     ];
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public static function trustedCallbacks() {
-    return ['renderPlaceholderCsrfToken'];
-  }
-
 }
diff --git a/core/lib/Drupal/Core/Entity/Controller/EntityViewController.php b/core/lib/Drupal/Core/Entity/Controller/EntityViewController.php
index cf660ab0cb..1434f9151c 100644
--- a/core/lib/Drupal/Core/Entity/Controller/EntityViewController.php
+++ b/core/lib/Drupal/Core/Entity/Controller/EntityViewController.php
@@ -6,14 +6,14 @@
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Entity\EntityTypeManagerInterface;
 use Drupal\Core\Entity\FieldableEntityInterface;
-use Drupal\Core\Security\TrustedCallbackInterface;
+use Drupal\Core\Security\Attribute\TrustedCallback;
 use Drupal\Core\Render\RendererInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
  * Defines a generic controller to render a single entity.
  */
-class EntityViewController implements ContainerInjectionInterface, TrustedCallbackInterface {
+class EntityViewController implements ContainerInjectionInterface {
 
   /**
    * The entity type manager.
@@ -74,6 +74,7 @@ public static function create(ContainerInterface $container) {
    * @return array
    *   The changed page render array.
    */
+  #[TrustedCallback]
   public function buildTitle(array $page) {
     $entity_type = $page['#entity_type'];
     $entity = $page['#' . $entity_type];
@@ -164,13 +165,6 @@ public function view(EntityInterface $_entity, $view_mode = 'full') {
     return $page;
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public static function trustedCallbacks() {
-    return ['buildTitle'];
-  }
-
   /**
    * Provides a page to render a single entity revision.
    *
diff --git a/core/lib/Drupal/Core/Entity/EntityViewBuilder.php b/core/lib/Drupal/Core/Entity/EntityViewBuilder.php
index 8233d69c6d..97340ddaf3 100644
--- a/core/lib/Drupal/Core/Entity/EntityViewBuilder.php
+++ b/core/lib/Drupal/Core/Entity/EntityViewBuilder.php
@@ -10,7 +10,7 @@
 use Drupal\Core\Field\FieldItemListInterface;
 use Drupal\Core\Language\LanguageManagerInterface;
 use Drupal\Core\Render\Element;
-use Drupal\Core\Security\TrustedCallbackInterface;
+use Drupal\Core\Security\Attribute\TrustedCallback;
 use Drupal\Core\Theme\Registry;
 use Drupal\Core\TypedData\TranslatableInterface as TranslatableDataInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -20,7 +20,7 @@
  *
  * @ingroup entity_api
  */
-class EntityViewBuilder extends EntityHandlerBase implements EntityHandlerInterface, EntityViewBuilderInterface, TrustedCallbackInterface {
+class EntityViewBuilder extends EntityHandlerBase implements EntityHandlerInterface, EntityViewBuilderInterface {
 
   /**
    * The type of entities for which this view builder is instantiated.
@@ -132,13 +132,6 @@ public function view(EntityInterface $entity, $view_mode = 'full', $langcode = N
     return $build;
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public static function trustedCallbacks() {
-    return ['build', 'buildMultiple'];
-  }
-
   /**
    * {@inheritdoc}
    */
@@ -233,6 +226,7 @@ protected function getBuildDefaults(EntityInterface $entity, $view_mode) {
    *
    * @see \Drupal\Core\Render\RendererInterface::render()
    */
+  #[TrustedCallback]
   public function build(array $build) {
     $build_list = [$build];
     $build_list = $this->buildMultiple($build_list);
@@ -257,6 +251,7 @@ public function build(array $build) {
    *
    * @see \Drupal\Core\Render\RendererInterface::render()
    */
+  #[TrustedCallback]
   public function buildMultiple(array $build_list) {
     // Build the view modes and display objects.
     $view_modes = [];
diff --git a/core/lib/Drupal/Core/Form/FormBuilder.php b/core/lib/Drupal/Core/Form/FormBuilder.php
index 6b3393e2fb..c6b9f5ea5f 100644
--- a/core/lib/Drupal/Core/Form/FormBuilder.php
+++ b/core/lib/Drupal/Core/Form/FormBuilder.php
@@ -15,7 +15,7 @@
 use Drupal\Core\Form\Exception\BrokenPostRequestException;
 use Drupal\Core\Render\Element;
 use Drupal\Core\Render\ElementInfoManagerInterface;
-use Drupal\Core\Security\TrustedCallbackInterface;
+use Drupal\Core\Security\Attribute\TrustedCallback;
 use Drupal\Core\Theme\ThemeManagerInterface;
 use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
 use Symfony\Component\HttpFoundation\FileBag;
@@ -28,7 +28,7 @@
  *
  * @ingroup form_api
  */
-class FormBuilder implements FormBuilderInterface, FormValidatorInterface, FormSubmitterInterface, FormCacheInterface, TrustedCallbackInterface {
+class FormBuilder implements FormBuilderInterface, FormValidatorInterface, FormSubmitterInterface, FormCacheInterface {
 
   /**
    * The module handler.
@@ -650,6 +650,7 @@ public function processForm($form_id, &$form, FormStateInterface &$form_state) {
    * @return array
    *   A renderable array representing the form action.
    */
+  #[TrustedCallback]
   public function renderPlaceholderFormAction() {
     return [
       '#type' => 'markup',
@@ -668,6 +669,7 @@ public function renderPlaceholderFormAction() {
    * @return array
    *   A renderable array containing the CSRF token.
    */
+  #[TrustedCallback]
   public function renderFormTokenPlaceholder($placeholder) {
     return [
       '#markup' => $this->csrfToken->get($placeholder),
@@ -1418,11 +1420,4 @@ protected function currentUser() {
     return $this->currentUser;
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public static function trustedCallbacks() {
-    return ['renderPlaceholderFormAction', 'renderFormTokenPlaceholder'];
-  }
-
 }
diff --git a/core/lib/Drupal/Core/Security/DoTrustedCallbackTrait.php b/core/lib/Drupal/Core/Security/DoTrustedCallbackTrait.php
index 5c1079b9e0..e1c9bc53b5 100644
--- a/core/lib/Drupal/Core/Security/DoTrustedCallbackTrait.php
+++ b/core/lib/Drupal/Core/Security/DoTrustedCallbackTrait.php
@@ -70,6 +70,7 @@ public function doTrustedCallback(callable $callback, array $args, $message, $er
         $safe_callback = TRUE;
       }
       elseif (is_subclass_of($object_or_classname, TrustedCallbackInterface::class)) {
+        @trigger_error('Usage of the ' . TrustedCallbackInterface::class . " is deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. Instead, you should use \Drupal\Core\Security\Attribute\TrustedCallback attribute for the method. See https://www.drupal.org/node/3349470", E_USER_DEPRECATED);
         if (is_object($object_or_classname)) {
           $methods = $object_or_classname->trustedCallbacks();
         }
diff --git a/core/lib/Drupal/Core/Security/TrustedCallbackInterface.php b/core/lib/Drupal/Core/Security/TrustedCallbackInterface.php
index 78f6bb9343..38c08ec152 100644
--- a/core/lib/Drupal/Core/Security/TrustedCallbackInterface.php
+++ b/core/lib/Drupal/Core/Security/TrustedCallbackInterface.php
@@ -35,6 +35,11 @@ interface TrustedCallbackInterface {
    *   List of method names implemented by the class that can be used as trusted
    *   callbacks.
    *
+   * @deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. Instead,
+   *   you should use \Drupal\Core\Security\Attribute\TrustedCallback attribute
+   *   for the method.
+   *
+   * @see https://www.drupal.org/node/3349470
    * @see \Drupal\Core\Security\DoTrustedCallbackTrait::doTrustedCallback()
    */
   public static function trustedCallbacks();
diff --git a/core/lib/Drupal/Core/Url.php b/core/lib/Drupal/Core/Url.php
index 13497348c9..632d1a50a5 100644
--- a/core/lib/Drupal/Core/Url.php
+++ b/core/lib/Drupal/Core/Url.php
@@ -6,7 +6,7 @@
 use Drupal\Component\Utility\UrlHelper;
 use Drupal\Core\Access\AccessResult;
 use Drupal\Core\DependencyInjection\DependencySerializationTrait;
-use Drupal\Core\Security\TrustedCallbackInterface;
+use Drupal\Core\Security\Attribute\TrustedCallback;
 use Drupal\Core\Routing\RouteMatchInterface;
 use Drupal\Core\Routing\UrlGeneratorInterface;
 use Drupal\Core\Session\AccountInterface;
@@ -27,7 +27,7 @@
  *
  * @see \Drupal\Core\Entity\EntityBase::toUrl()
  */
-class Url implements TrustedCallbackInterface {
+class Url {
   use DependencySerializationTrait;
 
   /**
@@ -848,6 +848,7 @@ public function access(AccountInterface $account = NULL, $return_as_object = FAL
    *
    * @see https://www.drupal.org/node/3342977
    */
+  #[TrustedCallback]
   public static function renderAccess(array $element) {
     @trigger_error(__METHOD__ . '() is deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. There is no replacement. See https://www.drupal.org/node/3342977', E_USER_DEPRECATED);
     return $element['#url']->access();
@@ -916,12 +917,4 @@ public function setUnroutedUrlAssembler(UnroutedUrlAssemblerInterface $url_assem
     return $this;
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public static function trustedCallbacks() {
-    // @todo Clean-up in https://www.drupal.org/i/3343153
-    return ['renderAccess'];
-  }
-
 }
diff --git a/core/modules/big_pipe/tests/modules/big_pipe_regression_test/src/BigPipeRegressionTestController.php b/core/modules/big_pipe/tests/modules/big_pipe_regression_test/src/BigPipeRegressionTestController.php
index 6c1fde7331..fff7830699 100644
--- a/core/modules/big_pipe/tests/modules/big_pipe_regression_test/src/BigPipeRegressionTestController.php
+++ b/core/modules/big_pipe/tests/modules/big_pipe_regression_test/src/BigPipeRegressionTestController.php
@@ -3,9 +3,9 @@
 namespace Drupal\big_pipe_regression_test;
 
 use Drupal\big_pipe\Render\BigPipeMarkup;
-use Drupal\Core\Security\TrustedCallbackInterface;
+use Drupal\Core\Security\Attribute\TrustedCallback;
 
-class BigPipeRegressionTestController implements TrustedCallbackInterface {
+class BigPipeRegressionTestController {
 
   const MARKER_2678662 = '<script>var hitsTheFloor = "</body>";</script>';
 
@@ -37,6 +37,7 @@ public function regression2802923() {
    *
    * @return array
    */
+  #[TrustedCallback]
   public static function currentTime() {
     return [
       '#markup' => '<time datetime="' . date('Y-m-d', time()) . '"></time>',
@@ -44,11 +45,4 @@ public static function currentTime() {
     ];
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public static function trustedCallbacks() {
-    return ['currentTime'];
-  }
-
 }
diff --git a/core/modules/big_pipe/tests/modules/big_pipe_test/src/BigPipeTestController.php b/core/modules/big_pipe/tests/modules/big_pipe_test/src/BigPipeTestController.php
index 6e6ea88f6a..6f88069119 100644
--- a/core/modules/big_pipe/tests/modules/big_pipe_test/src/BigPipeTestController.php
+++ b/core/modules/big_pipe/tests/modules/big_pipe_test/src/BigPipeTestController.php
@@ -4,9 +4,9 @@
 
 use Drupal\big_pipe\Render\BigPipeMarkup;
 use Drupal\big_pipe_test\EventSubscriber\BigPipeTestSubscriber;
-use Drupal\Core\Security\TrustedCallbackInterface;
+use Drupal\Core\Security\Attribute\TrustedCallback;
 
-class BigPipeTestController implements TrustedCallbackInterface {
+class BigPipeTestController {
 
   /**
    * Returns all BigPipe placeholder test case render arrays.
@@ -120,6 +120,7 @@ public function placeholderPreview() {
    *
    * @return array
    */
+  #[TrustedCallback]
   public static function currentTime() {
     return [
       '#markup' => '<time datetime="' . date('Y-m-d', 668948400) . '"></time>',
@@ -132,6 +133,7 @@ public static function currentTime() {
    *
    * @return array
    */
+  #[TrustedCallback]
   public static function helloOrYarhar() {
     return [
       '#markup' => BigPipeMarkup::create('<marquee>Yarhar llamas forever!</marquee>'),
@@ -147,6 +149,7 @@ public static function helloOrYarhar() {
    *
    * @throws \Exception
    */
+  #[TrustedCallback]
   public static function exception() {
     throw new \Exception('You are not allowed to say llamas are not cool!');
   }
@@ -158,6 +161,7 @@ public static function exception() {
    *
    * @return array
    */
+  #[TrustedCallback]
   public static function responseException() {
     return ['#plain_text' => BigPipeTestSubscriber::CONTENT_TRIGGER_EXCEPTION];
   }
@@ -170,6 +174,7 @@ public static function responseException() {
    * @return array
    *   The render array.
    */
+  #[TrustedCallback]
   public static function counter() {
     // Lazy builders are not allowed to build their own state like this function
     // does, but in this case we're intentionally doing that for testing
@@ -189,11 +194,4 @@ public static function counter() {
     ];
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public static function trustedCallbacks() {
-    return ['currentTime', 'helloOrYarhar', 'exception', 'responseException', 'counter'];
-  }
-
 }
diff --git a/core/modules/block/src/BlockViewBuilder.php b/core/modules/block/src/BlockViewBuilder.php
index b4cdf0c7aa..aca676c770 100644
--- a/core/modules/block/src/BlockViewBuilder.php
+++ b/core/modules/block/src/BlockViewBuilder.php
@@ -12,12 +12,12 @@
 use Drupal\Core\Plugin\ContextAwarePluginInterface;
 use Drupal\Core\Render\Element;
 use Drupal\block\Entity\Block;
-use Drupal\Core\Security\TrustedCallbackInterface;
+use Drupal\Core\Security\Attribute\TrustedCallback;
 
 /**
  * Provides a Block view builder.
  */
-class BlockViewBuilder extends EntityViewBuilder implements TrustedCallbackInterface {
+class BlockViewBuilder extends EntityViewBuilder {
 
   /**
    * {@inheritdoc}
@@ -136,13 +136,6 @@ protected static function buildPreRenderableBlock(BlockInterface $entity, Module
     return $build;
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public static function trustedCallbacks() {
-    return ['preRender', 'lazyBuilder'];
-  }
-
   /**
    * #lazy_builder callback; builds a #pre_render-able block.
    *
@@ -154,6 +147,7 @@ public static function trustedCallbacks() {
    * @return array
    *   A render array with a #pre_render callback to render the block.
    */
+  #[TrustedCallback]
   public static function lazyBuilder($entity_id, $view_mode) {
     return static::buildPreRenderableBlock(Block::load($entity_id), \Drupal::service('module_handler'));
   }
@@ -167,6 +161,7 @@ public static function lazyBuilder($entity_id, $view_mode) {
    * - if there is content, moves the contextual links from the block content to
    *   the block itself.
    */
+  #[TrustedCallback]
   public static function preRender($build) {
     $content = $build['#block']->getPlugin()->build();
     // Remove the block entity from the render array, to ensure that blocks
diff --git a/core/modules/comment/src/CommentLazyBuilders.php b/core/modules/comment/src/CommentLazyBuilders.php
index d719849914..bcc508a798 100644
--- a/core/modules/comment/src/CommentLazyBuilders.php
+++ b/core/modules/comment/src/CommentLazyBuilders.php
@@ -8,7 +8,7 @@
 use Drupal\Core\Entity\EntityTypeManagerInterface;
 use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\Core\Render\Element\Link;
-use Drupal\Core\Security\TrustedCallbackInterface;
+use Drupal\Core\Security\Attribute\TrustedCallback;
 use Drupal\Core\Render\RendererInterface;
 use Drupal\Core\Session\AccountInterface;
 use Drupal\Core\Url;
@@ -16,7 +16,7 @@
 /**
  * Defines a service for comment #lazy_builder callbacks.
  */
-class CommentLazyBuilders implements TrustedCallbackInterface {
+class CommentLazyBuilders {
 
   /**
    * The entity type manager service.
@@ -100,6 +100,7 @@ public function __construct(EntityTypeManagerInterface $entity_type_manager, Ent
    * @return array
    *   A renderable array containing the comment form.
    */
+  #[TrustedCallback]
   public function renderForm($commented_entity_type_id, $commented_entity_id, $field_name, $comment_type_id) {
     $values = [
       'entity_type' => $commented_entity_type_id,
@@ -127,6 +128,7 @@ public function renderForm($commented_entity_type_id, $commented_entity_id, $fie
    * @return array
    *   A renderable array representing the comment links.
    */
+  #[TrustedCallback]
   public function renderLinks($comment_entity_id, $view_mode, $langcode, $is_in_preview) {
     $links = [
       '#theme' => 'links__comment',
@@ -228,11 +230,4 @@ protected function access(EntityInterface $entity) {
     return content_translation_translate_access($entity);
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public static function trustedCallbacks() {
-    return ['renderLinks', 'renderForm'];
-  }
-
 }
diff --git a/core/modules/editor/src/Element.php b/core/modules/editor/src/Element.php
index 91739d74a6..16cfbb0510 100644
--- a/core/modules/editor/src/Element.php
+++ b/core/modules/editor/src/Element.php
@@ -2,7 +2,7 @@
 
 namespace Drupal\editor;
 
-use Drupal\Core\Security\TrustedCallbackInterface;
+use Drupal\Core\Security\Attribute\TrustedCallback;
 use Drupal\editor\Entity\Editor;
 use Drupal\filter\Entity\FilterFormat;
 use Drupal\Component\Plugin\PluginManagerInterface;
@@ -11,7 +11,7 @@
 /**
  * Defines a service for Text Editor's render elements.
  */
-class Element implements TrustedCallbackInterface {
+class Element {
 
   /**
    * The Text Editor plugin manager service.
@@ -30,16 +30,10 @@ public function __construct(PluginManagerInterface $plugin_manager) {
     $this->pluginManager = $plugin_manager;
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public static function trustedCallbacks() {
-    return ['preRenderTextFormat'];
-  }
-
   /**
    * Additional #pre_render callback for 'text_format' elements.
    */
+  #[TrustedCallback]
   public function preRenderTextFormat(array $element) {
     // Allow modules to programmatically enforce no client-side editor by
     // setting the #editor property to FALSE.
diff --git a/core/modules/filter/tests/filter_test/src/Plugin/Filter/FilterTestPlaceholders.php b/core/modules/filter/tests/filter_test/src/Plugin/Filter/FilterTestPlaceholders.php
index 6e34bd6139..8e215e2aef 100644
--- a/core/modules/filter/tests/filter_test/src/Plugin/Filter/FilterTestPlaceholders.php
+++ b/core/modules/filter/tests/filter_test/src/Plugin/Filter/FilterTestPlaceholders.php
@@ -3,7 +3,7 @@
 namespace Drupal\filter_test\Plugin\Filter;
 
 use Drupal\Component\Render\FormattableMarkup;
-use Drupal\Core\Security\TrustedCallbackInterface;
+use Drupal\Core\Security\Attribute\TrustedCallback;
 use Drupal\filter\FilterProcessResult;
 use Drupal\filter\Plugin\FilterBase;
 
@@ -17,7 +17,7 @@
  *   type = Drupal\filter\Plugin\FilterInterface::TYPE_TRANSFORM_REVERSIBLE
  * )
  */
-class FilterTestPlaceholders extends FilterBase implements TrustedCallbackInterface {
+class FilterTestPlaceholders extends FilterBase {
 
   /**
    * {@inheritdoc}
@@ -38,17 +38,11 @@ public function process($text, $langcode) {
    * @return array
    *   A renderable array.
    */
+  #[TrustedCallback]
   public static function renderDynamicThing($thing) {
     return [
       '#markup' => new FormattableMarkup('This is a dynamic @thing.', ['@thing' => $thing]),
     ];
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public static function trustedCallbacks() {
-    return ['renderDynamicThing'];
-  }
-
 }
diff --git a/core/modules/media/src/Plugin/Filter/MediaEmbed.php b/core/modules/media/src/Plugin/Filter/MediaEmbed.php
index 3f9324edb1..606bd09a04 100644
--- a/core/modules/media/src/Plugin/Filter/MediaEmbed.php
+++ b/core/modules/media/src/Plugin/Filter/MediaEmbed.php
@@ -14,7 +14,7 @@
 use Drupal\Core\Render\BubbleableMetadata;
 use Drupal\Core\Render\RenderContext;
 use Drupal\Core\Render\RendererInterface;
-use Drupal\Core\Security\TrustedCallbackInterface;
+use Drupal\Core\Security\Attribute\TrustedCallback;
 use Drupal\filter\FilterProcessResult;
 use Drupal\filter\Plugin\FilterBase;
 use Drupal\image\Plugin\Field\FieldType\ImageItem;
@@ -39,7 +39,7 @@
  *
  * @internal
  */
-class MediaEmbed extends FilterBase implements ContainerFactoryPluginInterface, TrustedCallbackInterface {
+class MediaEmbed extends FilterBase implements ContainerFactoryPluginInterface {
 
   /**
    * The entity repository.
@@ -430,6 +430,7 @@ protected static function replaceNodeContent(\DOMNode &$node, $content) {
    *
    * @see \Drupal\Core\Entity\EntityViewBuilder::addContextualLinks()
    */
+  #[TrustedCallback]
   public static function disableContextualLinks(array $build) {
     unset($build['#contextual_links']);
     return $build;
@@ -506,13 +507,6 @@ protected function getMediaImageSourceField(MediaInterface $media) {
     return NULL;
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public static function trustedCallbacks() {
-    return ['disableContextualLinks'];
-  }
-
   /**
    * {@inheritdoc}
    */
diff --git a/core/modules/media_library/src/Form/AddFormBase.php b/core/modules/media_library/src/Form/AddFormBase.php
index 83742a3a17..b7939ca30b 100644
--- a/core/modules/media_library/src/Form/AddFormBase.php
+++ b/core/modules/media_library/src/Form/AddFormBase.php
@@ -14,7 +14,7 @@
 use Drupal\Core\Form\FormBase;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Render\Element;
-use Drupal\Core\Security\TrustedCallbackInterface;
+use Drupal\Core\Security\Attribute\TrustedCallback;
 use Drupal\Core\Url;
 use Drupal\media\MediaInterface;
 use Drupal\media\MediaTypeInterface;
@@ -26,7 +26,7 @@
 /**
  * Provides a base class for creating media items from within the media library.
  */
-abstract class AddFormBase extends FormBase implements BaseFormIdInterface, TrustedCallbackInterface {
+abstract class AddFormBase extends FormBase implements BaseFormIdInterface {
 
   /**
    * The entity type manager.
@@ -339,13 +339,6 @@ protected function buildEntityFormElement(MediaInterface $media, array $form, Fo
     return $element;
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public static function trustedCallbacks() {
-    return ['preRenderAddedMedia'];
-  }
-
   /**
    * Converts the set of newly added media into an item list for rendering.
    *
@@ -355,6 +348,7 @@ public static function trustedCallbacks() {
    * @return array
    *   The transformed render element.
    */
+  #[TrustedCallback]
   public function preRenderAddedMedia(array $element) {
     // Transform the element into an item list for rendering.
     $element['#theme'] = 'item_list__media_library_add_form_media_list';
diff --git a/core/modules/media_library/src/Plugin/Field/FieldWidget/MediaLibraryWidget.php b/core/modules/media_library/src/Plugin/Field/FieldWidget/MediaLibraryWidget.php
index 4bd939f753..6db6530c5a 100644
--- a/core/modules/media_library/src/Plugin/Field/FieldWidget/MediaLibraryWidget.php
+++ b/core/modules/media_library/src/Plugin/Field/FieldWidget/MediaLibraryWidget.php
@@ -17,7 +17,7 @@
 use Drupal\Core\Field\FieldStorageDefinitionInterface;
 use Drupal\Core\Field\WidgetBase;
 use Drupal\Core\Form\FormStateInterface;
-use Drupal\Core\Security\TrustedCallbackInterface;
+use Drupal\Core\Security\Attribute\TrustedCallback;
 use Drupal\Core\Session\AccountInterface;
 use Drupal\Core\StringTranslation\TranslatableMarkup;
 use Drupal\Core\Url;
@@ -44,7 +44,7 @@
  * @internal
  *   Plugin classes are internal.
  */
-class MediaLibraryWidget extends WidgetBase implements TrustedCallbackInterface {
+class MediaLibraryWidget extends WidgetBase {
 
   /**
    * Entity type manager service.
@@ -597,13 +597,6 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen
     return $element;
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public static function trustedCallbacks() {
-    return ['preRenderWidget'];
-  }
-
   /**
    * Prepares the widget's render element for rendering.
    *
@@ -615,6 +608,7 @@ public static function trustedCallbacks() {
    *
    * @see ::formElement()
    */
+  #[TrustedCallback]
   public function preRenderWidget(array $element) {
     if (isset($element['open_button'])) {
       $element['#field_suffix']['open_button'] = $element['open_button'];
diff --git a/core/modules/node/src/NodeViewBuilder.php b/core/modules/node/src/NodeViewBuilder.php
index c10a75b71c..9721282529 100644
--- a/core/modules/node/src/NodeViewBuilder.php
+++ b/core/modules/node/src/NodeViewBuilder.php
@@ -5,12 +5,12 @@
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Entity\EntityViewBuilder;
 use Drupal\Core\Render\Element\Link;
-use Drupal\Core\Security\TrustedCallbackInterface;
+use Drupal\Core\Security\Attribute\TrustedCallback;
 
 /**
  * View builder handler for nodes.
  */
-class NodeViewBuilder extends EntityViewBuilder implements TrustedCallbackInterface {
+class NodeViewBuilder extends EntityViewBuilder {
 
   /**
    * {@inheritdoc}
@@ -86,6 +86,7 @@ protected function getBuildDefaults(EntityInterface $entity, $view_mode) {
    * @return array
    *   A renderable array representing the node links.
    */
+  #[TrustedCallback]
   public static function renderLinks($node_entity_id, $view_mode, $langcode, $is_in_preview, $revision_id = NULL) {
     $links = [
       '#theme' => 'links__node',
@@ -148,13 +149,4 @@ protected static function buildLinks(NodeInterface $entity, $view_mode) {
     ];
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public static function trustedCallbacks() {
-    $callbacks = parent::trustedCallbacks();
-    $callbacks[] = 'renderLinks';
-    return $callbacks;
-  }
-
 }
diff --git a/core/modules/node/src/Plugin/Search/NodeSearch.php b/core/modules/node/src/Plugin/Search/NodeSearch.php
index 1f6e166530..2e3eab787b 100644
--- a/core/modules/node/src/Plugin/Search/NodeSearch.php
+++ b/core/modules/node/src/Plugin/Search/NodeSearch.php
@@ -17,7 +17,7 @@
 use Drupal\Core\Language\LanguageManagerInterface;
 use Drupal\Core\Messenger\MessengerInterface;
 use Drupal\Core\Render\RendererInterface;
-use Drupal\Core\Security\TrustedCallbackInterface;
+use Drupal\Core\Security\Attribute\TrustedCallback;
 use Drupal\Core\Session\AccountInterface;
 use Drupal\node\NodeInterface;
 use Drupal\search\Plugin\ConfigurableSearchPluginBase;
@@ -34,7 +34,7 @@
  *   title = @Translation("Content")
  * )
  */
-class NodeSearch extends ConfigurableSearchPluginBase implements AccessibleInterface, SearchIndexingInterface, TrustedCallbackInterface {
+class NodeSearch extends ConfigurableSearchPluginBase implements AccessibleInterface, SearchIndexingInterface {
 
   /**
    * The current database connection.
@@ -424,6 +424,7 @@ protected function prepareResults(StatementInterface $found) {
    * @return array
    *   The modified build array.
    */
+  #[TrustedCallback]
   public function removeSubmittedInfo(array $build) {
     unset($build['created']);
     unset($build['uid']);
@@ -867,11 +868,4 @@ public function submitConfigurationForm(array &$form, FormStateInterface $form_s
     }
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public static function trustedCallbacks() {
-    return ['removeSubmittedInfo'];
-  }
-
 }
diff --git a/core/modules/shortcut/src/ShortcutLazyBuilders.php b/core/modules/shortcut/src/ShortcutLazyBuilders.php
index e2672104c5..cdc5f3887a 100644
--- a/core/modules/shortcut/src/ShortcutLazyBuilders.php
+++ b/core/modules/shortcut/src/ShortcutLazyBuilders.php
@@ -3,13 +3,13 @@
 namespace Drupal\shortcut;
 
 use Drupal\Core\Render\RendererInterface;
-use Drupal\Core\Security\TrustedCallbackInterface;
+use Drupal\Core\Security\Attribute\TrustedCallback;
 use Drupal\Core\Url;
 
 /**
  * Lazy builders for the shortcut module.
  */
-class ShortcutLazyBuilders implements TrustedCallbackInterface {
+class ShortcutLazyBuilders {
 
   /**
    * The renderer service.
@@ -28,19 +28,13 @@ public function __construct(RendererInterface $renderer) {
     $this->renderer = $renderer;
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public static function trustedCallbacks() {
-    return ['lazyLinks'];
-  }
-
   /**
    * #lazy_builder callback; builds shortcut toolbar links.
    *
    * @return array
    *   A renderable array of shortcut links.
    */
+  #[TrustedCallback]
   public function lazyLinks() {
     $shortcut_set = shortcut_current_displayed_set();
 
diff --git a/core/modules/system/tests/modules/element_info_test/src/ElementInfoTestNumberBuilder.php b/core/modules/system/tests/modules/element_info_test/src/ElementInfoTestNumberBuilder.php
index ae4ad3bac4..09133545e7 100644
--- a/core/modules/system/tests/modules/element_info_test/src/ElementInfoTestNumberBuilder.php
+++ b/core/modules/system/tests/modules/element_info_test/src/ElementInfoTestNumberBuilder.php
@@ -2,25 +2,19 @@
 
 namespace Drupal\element_info_test;
 
-use Drupal\Core\Security\TrustedCallbackInterface;
+use Drupal\Core\Security\Attribute\TrustedCallback;
 
 /**
  * Provides a trusted callback to alter the element_info_test number element.
  *
  * @see element_info_test_element_info_alter()
  */
-class ElementInfoTestNumberBuilder implements TrustedCallbackInterface {
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function trustedCallbacks() {
-    return ['preRender'];
-  }
+class ElementInfoTestNumberBuilder {
 
   /**
    * Sets element_info_test - #pre_render callback.
    */
+  #[TrustedCallback]
   public static function preRender(array $element): array {
     return $element;
   }
diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestInputForgeryForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestInputForgeryForm.php
index b581c9e488..7556ecfc49 100644
--- a/core/modules/system/tests/modules/form_test/src/Form/FormTestInputForgeryForm.php
+++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestInputForgeryForm.php
@@ -4,7 +4,7 @@
 
 use Drupal\Core\Form\FormBase;
 use Drupal\Core\Form\FormStateInterface;
-use Drupal\Core\Security\TrustedCallbackInterface;
+use Drupal\Core\Security\Attribute\TrustedCallback;
 use Symfony\Component\HttpFoundation\JsonResponse;
 
 /**
@@ -12,7 +12,7 @@
  *
  * @internal
  */
-class FormTestInputForgeryForm extends FormBase implements TrustedCallbackInterface {
+class FormTestInputForgeryForm extends FormBase {
 
   /**
    * {@inheritdoc}
@@ -58,6 +58,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
    *
    * @see \Drupal\Tests\system\Functional\Form\FormTest::testInputForgery()
    */
+  #[TrustedCallback]
   public static function postRender($rendered_form) {
     return str_replace('value="two"', 'value="FORGERY"', $rendered_form);
   }
@@ -69,11 +70,4 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
     return new JsonResponse($form_state->getValues());
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public static function trustedCallbacks() {
-    return ['postRender'];
-  }
-
 }
diff --git a/core/modules/system/tests/modules/pager_test/src/Controller/PagerTestController.php b/core/modules/system/tests/modules/pager_test/src/Controller/PagerTestController.php
index ded2f19551..89480b8096 100644
--- a/core/modules/system/tests/modules/pager_test/src/Controller/PagerTestController.php
+++ b/core/modules/system/tests/modules/pager_test/src/Controller/PagerTestController.php
@@ -6,13 +6,13 @@
 use Drupal\Core\Database\Database;
 use Drupal\Core\Database\Query\PagerSelectExtender;
 use Drupal\Core\Pager\PagerParametersInterface;
-use Drupal\Core\Security\TrustedCallbackInterface;
+use Drupal\Core\Security\Attribute\TrustedCallback;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
  * Controller routine for testing the pager.
  */
-class PagerTestController extends ControllerBase implements TrustedCallbackInterface {
+class PagerTestController extends ControllerBase {
 
   /**
    * The pager request service.
@@ -146,16 +146,10 @@ public function multiplePagers() {
   /**
    * #pre_render callback for #type => pager that shows the pager cache context.
    */
+  #[TrustedCallback]
   public static function showPagerCacheContext(array $pager) {
     \Drupal::messenger()->addStatus(\Drupal::service('cache_contexts_manager')->convertTokensToKeys(['url.query_args.pagers:' . $pager['#element']])->getKeys()[0]);
     return $pager;
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public static function trustedCallbacks() {
-    return ['showPagerCacheContext'];
-  }
-
 }
diff --git a/core/modules/system/tests/modules/render_placeholder_message_test/src/RenderPlaceholderMessageTestController.php b/core/modules/system/tests/modules/render_placeholder_message_test/src/RenderPlaceholderMessageTestController.php
index d59ed4edda..8b1a4ecde2 100644
--- a/core/modules/system/tests/modules/render_placeholder_message_test/src/RenderPlaceholderMessageTestController.php
+++ b/core/modules/system/tests/modules/render_placeholder_message_test/src/RenderPlaceholderMessageTestController.php
@@ -2,12 +2,12 @@
 
 namespace Drupal\render_placeholder_message_test;
 
-use Drupal\Core\Security\TrustedCallbackInterface;
+use Drupal\Core\Security\Attribute\TrustedCallback;
 use Drupal\Core\Render\RenderContext;
 use Symfony\Component\DependencyInjection\ContainerAwareInterface;
 use Symfony\Component\DependencyInjection\ContainerAwareTrait;
 
-class RenderPlaceholderMessageTestController implements ContainerAwareInterface, TrustedCallbackInterface {
+class RenderPlaceholderMessageTestController implements ContainerAwareInterface {
 
   use ContainerAwareTrait;
 
@@ -90,6 +90,7 @@ protected function build(array $placeholder_order) {
    * @return array
    *   A renderable array containing the message.
    */
+  #[TrustedCallback]
   public static function setAndLogMessage($message) {
     // Set message.
     \Drupal::messenger()->addStatus($message);
@@ -98,11 +99,4 @@ public static function setAndLogMessage($message) {
     return ['#markup' => '<p class="logged-message">Message: ' . $message . '</p>'];
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public static function trustedCallbacks() {
-    return ['setAndLogMessage'];
-  }
-
 }
diff --git a/core/modules/system/tests/modules/system_test/src/Controller/SystemTestController.php b/core/modules/system/tests/modules/system_test/src/Controller/SystemTestController.php
index 03f44fec4b..1ffd68d230 100644
--- a/core/modules/system/tests/modules/system_test/src/Controller/SystemTestController.php
+++ b/core/modules/system/tests/modules/system_test/src/Controller/SystemTestController.php
@@ -6,7 +6,7 @@
 use Drupal\Core\Cache\CacheableResponse;
 use Drupal\Core\Controller\ControllerBase;
 use Drupal\Core\Messenger\MessengerInterface;
-use Drupal\Core\Security\TrustedCallbackInterface;
+use Drupal\Core\Security\Attribute\TrustedCallback;
 use Drupal\Core\Render\RendererInterface;
 use Drupal\Core\Render\Markup;
 use Drupal\Core\Session\AccountInterface;
@@ -20,7 +20,7 @@
 /**
  * Controller routines for system_test routes.
  */
-class SystemTestController extends ControllerBase implements TrustedCallbackInterface {
+class SystemTestController extends ControllerBase {
 
   /**
    * The lock service.
@@ -272,6 +272,7 @@ public function system_test_cache_maxage_page() {
   /**
    * Sets a cache tag on an element to help test #pre_render and cache tags.
    */
+  #[TrustedCallback]
   public static function preRenderCacheTags($elements) {
     $elements['#cache']['tags'][] = 'pre_render';
     return $elements;
@@ -420,13 +421,6 @@ public function getCacheableResponseWithCustomCacheControl() {
     return new CacheableResponse('Foo', 200, ['Cache-Control' => 'bar']);
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public static function trustedCallbacks() {
-    return ['preRenderCacheTags'];
-  }
-
   /**
    * Use a plain Symfony response object to output the current install_profile.
    */
diff --git a/core/modules/text/src/Plugin/Field/FieldFormatter/TextTrimmedFormatter.php b/core/modules/text/src/Plugin/Field/FieldFormatter/TextTrimmedFormatter.php
index d961036a91..121ad013e0 100644
--- a/core/modules/text/src/Plugin/Field/FieldFormatter/TextTrimmedFormatter.php
+++ b/core/modules/text/src/Plugin/Field/FieldFormatter/TextTrimmedFormatter.php
@@ -5,7 +5,7 @@
 use Drupal\Core\Field\FormatterBase;
 use Drupal\Core\Field\FieldItemListInterface;
 use Drupal\Core\Form\FormStateInterface;
-use Drupal\Core\Security\TrustedCallbackInterface;
+use Drupal\Core\Security\Attribute\TrustedCallback;
 
 /**
  * Plugin implementation of the 'text_trimmed' formatter.
@@ -25,7 +25,7 @@
  *   }
  * )
  */
-class TextTrimmedFormatter extends FormatterBase implements TrustedCallbackInterface {
+class TextTrimmedFormatter extends FormatterBase {
 
   /**
    * {@inheritdoc}
@@ -117,16 +117,10 @@ public function viewElements(FieldItemListInterface $items, $langcode) {
    * @see filter_pre_render_text()
    * @see text_summary()
    */
+  #[TrustedCallback]
   public static function preRenderSummary(array $element) {
     $element['#markup'] = text_summary($element['#markup'], $element['#format'], $element['#text_summary_trim_length']);
     return $element;
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public static function trustedCallbacks() {
-    return ['preRenderSummary'];
-  }
-
 }
diff --git a/core/modules/toolbar/src/Controller/ToolbarController.php b/core/modules/toolbar/src/Controller/ToolbarController.php
index c683494f50..1d418ea226 100644
--- a/core/modules/toolbar/src/Controller/ToolbarController.php
+++ b/core/modules/toolbar/src/Controller/ToolbarController.php
@@ -8,13 +8,13 @@
 use Drupal\Core\Controller\ControllerBase;
 use Drupal\Core\Menu\MenuTreeParameters;
 use Drupal\Core\Render\RenderContext;
-use Drupal\Core\Security\TrustedCallbackInterface;
+use Drupal\Core\Security\Attribute\TrustedCallback;
 use Drupal\toolbar\Ajax\SetSubtreesCommand;
 
 /**
  * Defines a controller for the toolbar module.
  */
-class ToolbarController extends ControllerBase implements TrustedCallbackInterface {
+class ToolbarController extends ControllerBase {
 
   /**
    * Returns an AJAX response to render the toolbar subtrees.
@@ -66,6 +66,7 @@ public function checkSubTreeAccess($hash) {
    *
    * @see \Drupal\Core\Render\RendererInterface::render()
    */
+  #[TrustedCallback]
   public static function preRenderAdministrationTray(array $element) {
     $menu_tree = \Drupal::service('toolbar.menu_tree');
     // Load the administrative menu. The first level is the "Administration"
@@ -90,6 +91,7 @@ public static function preRenderAdministrationTray(array $element) {
    *
    * @internal
    */
+  #[TrustedCallback]
   public static function preRenderGetRenderedSubtrees(array $data) {
     $menu_tree = \Drupal::service('toolbar.menu_tree');
     $renderer = \Drupal::service('renderer');
@@ -137,11 +139,4 @@ public static function preRenderGetRenderedSubtrees(array $data) {
     return $data;
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public static function trustedCallbacks() {
-    return ['preRenderAdministrationTray', 'preRenderGetRenderedSubtrees'];
-  }
-
 }
diff --git a/core/modules/user/src/AccountForm.php b/core/modules/user/src/AccountForm.php
index e51b0f9ea0..8ceb7076d1 100644
--- a/core/modules/user/src/AccountForm.php
+++ b/core/modules/user/src/AccountForm.php
@@ -11,7 +11,7 @@
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Language\LanguageInterface;
 use Drupal\Core\Language\LanguageManagerInterface;
-use Drupal\Core\Security\TrustedCallbackInterface;
+use Drupal\Core\Security\Attribute\TrustedCallback;
 use Drupal\Core\Url;
 use Drupal\language\ConfigurableLanguageManagerInterface;
 use Drupal\user\Plugin\LanguageNegotiation\LanguageNegotiationUser;
@@ -21,7 +21,7 @@
 /**
  * Form controller for the user account forms.
  */
-abstract class AccountForm extends ContentEntityForm implements TrustedCallbackInterface {
+abstract class AccountForm extends ContentEntityForm {
 
   /**
    * The language manager.
@@ -311,13 +311,6 @@ public function form(array $form, FormStateInterface $form_state) {
     return parent::form($form, $form_state);
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public static function trustedCallbacks() {
-    return ['alterPreferredLangcodeDescription'];
-  }
-
   /**
    * Alters the preferred language widget description.
    *
@@ -327,6 +320,7 @@ public static function trustedCallbacks() {
    * @return array
    *   The preferred language form element.
    */
+  #[TrustedCallback]
   public function alterPreferredLangcodeDescription(array $element) {
     // Only add to the description if the form element has a description.
     if (isset($element['#description'])) {
diff --git a/core/modules/user/src/Plugin/Block/UserLoginBlock.php b/core/modules/user/src/Plugin/Block/UserLoginBlock.php
index f55a70d611..d6c1c1b9ac 100644
--- a/core/modules/user/src/Plugin/Block/UserLoginBlock.php
+++ b/core/modules/user/src/Plugin/Block/UserLoginBlock.php
@@ -5,7 +5,7 @@
 use Drupal\Component\Utility\UrlHelper;
 use Drupal\Core\Access\AccessResult;
 use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
-use Drupal\Core\Security\TrustedCallbackInterface;
+use Drupal\Core\Security\Attribute\TrustedCallback;
 use Drupal\Core\Routing\RedirectDestinationTrait;
 use Drupal\Core\Routing\RouteMatchInterface;
 use Drupal\Core\Url;
@@ -23,7 +23,7 @@
  *   category = @Translation("Forms")
  * )
  */
-class UserLoginBlock extends BlockBase implements ContainerFactoryPluginInterface, TrustedCallbackInterface {
+class UserLoginBlock extends BlockBase implements ContainerFactoryPluginInterface {
 
   use RedirectDestinationTrait;
 
@@ -153,6 +153,7 @@ public function build() {
    *
    * @see \Drupal\Core\Form\FormBuilder::renderPlaceholderFormAction()
    */
+  #[TrustedCallback]
   public static function renderPlaceholderFormAction() {
     return [
       '#type' => 'markup',
@@ -161,11 +162,4 @@ public static function renderPlaceholderFormAction() {
     ];
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public static function trustedCallbacks() {
-    return ['renderPlaceholderFormAction'];
-  }
-
 }
diff --git a/core/modules/user/src/ToolbarLinkBuilder.php b/core/modules/user/src/ToolbarLinkBuilder.php
index b278db6dba..46e3fdae01 100644
--- a/core/modules/user/src/ToolbarLinkBuilder.php
+++ b/core/modules/user/src/ToolbarLinkBuilder.php
@@ -2,7 +2,7 @@
 
 namespace Drupal\user;
 
-use Drupal\Core\Security\TrustedCallbackInterface;
+use Drupal\Core\Security\Attribute\TrustedCallback;
 use Drupal\Core\Session\AccountProxyInterface;
 use Drupal\Core\StringTranslation\StringTranslationTrait;
 use Drupal\Core\Url;
@@ -10,7 +10,7 @@
 /**
  * ToolbarLinkBuilder fills out the placeholders generated in user_toolbar().
  */
-class ToolbarLinkBuilder implements TrustedCallbackInterface {
+class ToolbarLinkBuilder {
 
   use StringTranslationTrait;
 
@@ -37,6 +37,7 @@ public function __construct(AccountProxyInterface $account) {
    * @return array
    *   A renderable array as expected by the renderer service.
    */
+  #[TrustedCallback]
   public function renderToolbarLinks() {
     $links = [
       'account' => [
@@ -78,17 +79,11 @@ public function renderToolbarLinks() {
    * @return array
    *   A renderable array as expected by the renderer service.
    */
+  #[TrustedCallback]
   public function renderDisplayName() {
     return [
       '#markup' => $this->account->getDisplayName(),
     ];
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public static function trustedCallbacks() {
-    return ['renderToolbarLinks', 'renderDisplayName'];
-  }
-
 }
diff --git a/core/modules/views/src/Form/ViewsFormMainForm.php b/core/modules/views/src/Form/ViewsFormMainForm.php
index 80fb39d2b3..2f9113461e 100644
--- a/core/modules/views/src/Form/ViewsFormMainForm.php
+++ b/core/modules/views/src/Form/ViewsFormMainForm.php
@@ -6,12 +6,12 @@
 use Drupal\Component\Utility\Html;
 use Drupal\Core\Form\FormInterface;
 use Drupal\Core\Form\FormStateInterface;
-use Drupal\Core\Security\TrustedCallbackInterface;
+use Drupal\Core\Security\Attribute\TrustedCallback;
 use Drupal\views\Render\ViewsRenderPipelineMarkup;
 use Drupal\views\ViewExecutable;
 use Drupal\Core\StringTranslation\StringTranslationTrait;
 
-class ViewsFormMainForm implements FormInterface, TrustedCallbackInterface {
+class ViewsFormMainForm implements FormInterface {
 
   use StringTranslationTrait;
 
@@ -32,6 +32,7 @@ public function getFormId() {
    *   The $element with prepared variables ready for #theme 'form'
    *   in views_form_views_form.
    */
+  #[TrustedCallback]
   public static function preRenderViewsForm(array $element) {
     // Placeholders and their substitutions (usually rendered form elements).
     $search = [];
@@ -63,13 +64,6 @@ public static function preRenderViewsForm(array $element) {
     return $element;
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public static function trustedCallbacks() {
-    return ['preRenderViewsForm'];
-  }
-
   /**
    * {@inheritdoc}
    */
diff --git a/core/modules/views/src/Plugin/views/PluginBase.php b/core/modules/views/src/Plugin/views/PluginBase.php
index 2a7fd90db5..f4a6c35e50 100644
--- a/core/modules/views/src/Plugin/views/PluginBase.php
+++ b/core/modules/views/src/Plugin/views/PluginBase.php
@@ -9,7 +9,7 @@
 use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
 use Drupal\Core\Plugin\PluginBase as ComponentPluginBase;
 use Drupal\Core\Render\Element;
-use Drupal\Core\Security\TrustedCallbackInterface;
+use Drupal\Core\Security\Attribute\TrustedCallback;
 use Drupal\Core\StringTranslation\TranslatableMarkup;
 use Drupal\views\Plugin\views\display\DisplayPluginBase;
 use Drupal\views\ViewExecutable;
@@ -37,7 +37,7 @@
  *
  * @ingroup views_plugins
  */
-abstract class PluginBase extends ComponentPluginBase implements ContainerFactoryPluginInterface, ViewsPluginInterface, DependentPluginInterface, TrustedCallbackInterface {
+abstract class PluginBase extends ComponentPluginBase implements ContainerFactoryPluginInterface, ViewsPluginInterface, DependentPluginInterface {
 
   /**
    * Include negotiated languages when listing languages.
@@ -275,13 +275,6 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) {
     $form['#pre_render'][] = [static::class, 'preRenderAddFieldsetMarkup'];
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public static function trustedCallbacks() {
-    return ['preRenderAddFieldsetMarkup'];
-  }
-
   /**
    * {@inheritdoc}
    */
@@ -485,6 +478,7 @@ public function globalTokenForm(&$form, FormStateInterface $form_state) {
   /**
    * {@inheritdoc}
    */
+  #[TrustedCallback]
   public static function preRenderAddFieldsetMarkup(array $form) {
     foreach (Element::children($form) as $key) {
       $element = $form[$key];
@@ -503,6 +497,7 @@ public static function preRenderAddFieldsetMarkup(array $form) {
   /**
    * {@inheritdoc}
    */
+  #[TrustedCallback]
   public static function preRenderFlattenData($form) {
     foreach (Element::children($form) as $key) {
       $element = $form[$key];
diff --git a/core/modules/views/src/Plugin/views/argument/ArgumentPluginBase.php b/core/modules/views/src/Plugin/views/argument/ArgumentPluginBase.php
index 72466b5f48..7b20a68890 100644
--- a/core/modules/views/src/Plugin/views/argument/ArgumentPluginBase.php
+++ b/core/modules/views/src/Plugin/views/argument/ArgumentPluginBase.php
@@ -9,6 +9,7 @@
 use Drupal\Core\Cache\CacheableDependencyInterface;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Render\Element;
+use Drupal\Core\Security\Attribute\TrustedCallback;
 use Drupal\views\Plugin\views\display\DisplayPluginBase;
 use Drupal\views\ViewExecutable;
 use Drupal\views\Plugin\views\HandlerBase;
@@ -198,15 +199,6 @@ protected function defineOptions() {
     return $options;
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public static function trustedCallbacks() {
-    $callbacks = parent::trustedCallbacks();
-    $callbacks[] = 'preRenderMoveArgumentOptions';
-    return $callbacks;
-  }
-
   public function buildOptionsForm(&$form, FormStateInterface $form_state) {
     parent::buildOptionsForm($form, $form_state);
 
@@ -1245,6 +1237,7 @@ public static function processContainerRadios($element) {
    * So if #argument_option is specified as 'default', the element is moved
    * to the 'default_options' fieldset.
    */
+  #[TrustedCallback]
   public static function preRenderMoveArgumentOptions($form) {
     foreach (Element::children($form) as $key) {
       $element = $form[$key];
diff --git a/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php b/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php
index 7b764e4768..690a31c47f 100644
--- a/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php
+++ b/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php
@@ -12,6 +12,7 @@
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Language\LanguageInterface;
 use Drupal\Core\Plugin\PluginDependencyTrait;
+use Drupal\Core\Security\Attribute\TrustedCallback;
 use Drupal\Core\Session\AccountInterface;
 use Drupal\Core\Link;
 use Drupal\Core\Url;
@@ -2196,15 +2197,6 @@ public function render() {
     return $element;
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public static function trustedCallbacks() {
-    $callbacks = parent::trustedCallbacks();
-    $callbacks[] = 'elementPreRender';
-    return $callbacks;
-  }
-
   /**
    * Applies the cacheability of the current display to the given render array.
    *
@@ -2226,6 +2218,7 @@ protected function applyDisplayCacheabilityMetadata(array &$element) {
   /**
    * {@inheritdoc}
    */
+  #[TrustedCallback]
   public function elementPreRender(array $element) {
     $view = $element['#view'];
     $empty = empty($view->result);
diff --git a/core/modules/views/src/Plugin/views/field/Custom.php b/core/modules/views/src/Plugin/views/field/Custom.php
index fb699ea6e3..e4d8549b54 100644
--- a/core/modules/views/src/Plugin/views/field/Custom.php
+++ b/core/modules/views/src/Plugin/views/field/Custom.php
@@ -4,6 +4,7 @@
 
 use Drupal\Component\Utility\Xss;
 use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Security\Attribute\TrustedCallback;
 use Drupal\views\Render\ViewsRenderPipelineMarkup;
 use Drupal\views\ResultRow;
 
@@ -55,15 +56,6 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) {
     $form['#pre_render'][] = [$this, 'preRenderCustomForm'];
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public static function trustedCallbacks() {
-    $callbacks = parent::trustedCallbacks();
-    $callbacks[] = 'preRenderCustomForm';
-    return $callbacks;
-  }
-
   /**
    * {@inheritdoc}
    */
@@ -81,6 +73,7 @@ public function render(ResultRow $values) {
    * @return array
    *   The modified form build array.
    */
+  #[TrustedCallback]
   public function preRenderCustomForm($form) {
     $form['text'] = $form['alter']['text'];
     $form['help'] = $form['alter']['help'];
diff --git a/core/modules/views/src/Plugin/views/filter/FilterPluginBase.php b/core/modules/views/src/Plugin/views/filter/FilterPluginBase.php
index 74308eb547..43fd0359e0 100644
--- a/core/modules/views/src/Plugin/views/filter/FilterPluginBase.php
+++ b/core/modules/views/src/Plugin/views/filter/FilterPluginBase.php
@@ -663,15 +663,6 @@ public function buildExposeForm(&$form, FormStateInterface $form_state) {
     ];
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public static function trustedCallbacks() {
-    $callbacks = parent::trustedCallbacks();
-    $callbacks[] = 'preRenderFlattenData';
-    return $callbacks;
-  }
-
   /**
    * Validate the options form.
    */
diff --git a/core/modules/views/src/Plugin/views/sort/SortPluginBase.php b/core/modules/views/src/Plugin/views/sort/SortPluginBase.php
index fcac77e013..949c75e21e 100644
--- a/core/modules/views/src/Plugin/views/sort/SortPluginBase.php
+++ b/core/modules/views/src/Plugin/views/sort/SortPluginBase.php
@@ -255,15 +255,6 @@ public function validateExposeForm($form, FormStateInterface $form_state) {
     }
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public static function trustedCallbacks() {
-    $callbacks = parent::trustedCallbacks();
-    $callbacks[] = 'preRenderFlattenData';
-    return $callbacks;
-  }
-
   /**
    * Provide default options for exposed sorts.
    */
diff --git a/core/modules/views/src/Plugin/views/style/StylePluginBase.php b/core/modules/views/src/Plugin/views/style/StylePluginBase.php
index 6b83922265..cc90799535 100644
--- a/core/modules/views/src/Plugin/views/style/StylePluginBase.php
+++ b/core/modules/views/src/Plugin/views/style/StylePluginBase.php
@@ -5,6 +5,7 @@
 use Drupal\Component\Utility\Html;
 use Drupal\Component\Utility\Xss;
 use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Security\Attribute\TrustedCallback;
 use Drupal\views\Plugin\views\display\DisplayPluginBase;
 use Drupal\views\Plugin\views\PluginBase;
 use Drupal\views\Plugin\views\wizard\WizardInterface;
@@ -736,15 +737,6 @@ protected function renderFields(array $result) {
     }
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public static function trustedCallbacks() {
-    $callbacks = parent::trustedCallbacks();
-    $callbacks[] = 'elementPreRenderRow';
-    return $callbacks;
-  }
-
   /**
    * #pre_render callback for view row field rendering.
    *
@@ -756,6 +748,7 @@ public static function trustedCallbacks() {
    * @return array
    *   The processed element.
    */
+  #[TrustedCallback]
   public function elementPreRenderRow(array $data) {
     // Render row fields.
     foreach ($this->view->field as $id => $field) {
diff --git a/core/modules/views/tests/modules/views_test_data/src/Controller/ViewsTestDataController.php b/core/modules/views/tests/modules/views_test_data/src/Controller/ViewsTestDataController.php
index 1a467131b5..5f984c89a6 100644
--- a/core/modules/views/tests/modules/views_test_data/src/Controller/ViewsTestDataController.php
+++ b/core/modules/views/tests/modules/views_test_data/src/Controller/ViewsTestDataController.php
@@ -2,12 +2,12 @@
 
 namespace Drupal\views_test_data\Controller;
 
-use Drupal\Core\Security\TrustedCallbackInterface;
+use Drupal\Core\Security\Attribute\TrustedCallback;
 
 /**
  * Controller class for views_test_data callbacks.
  */
-class ViewsTestDataController implements TrustedCallbackInterface {
+class ViewsTestDataController {
 
   /**
    * Renders an error form page.
@@ -29,6 +29,7 @@ public function errorFormPage() {
   /**
    * #lazy_builder callback; for testing purposes only.
    */
+  #[TrustedCallback]
   public static function placeholderLazyBuilder() {
     // No-op.
     return [];
@@ -43,16 +44,10 @@ public static function placeholderLazyBuilder() {
    * @return array
    *   The changed render array.
    */
+  #[TrustedCallback]
   public static function preRender($element) {
     $element['#markup'] = '\Drupal\views_test_data\Controller\ViewsTestDataController::preRender executed';
     return $element;
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public static function trustedCallbacks() {
-    return ['placeholderLazyBuilder', 'preRender'];
-  }
-
 }
diff --git a/core/tests/Drupal/KernelTests/Core/Datetime/DatelistElementFormTest.php b/core/tests/Drupal/KernelTests/Core/Datetime/DatelistElementFormTest.php
index 63db70745f..85fb16aaa4 100644
--- a/core/tests/Drupal/KernelTests/Core/Datetime/DatelistElementFormTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Datetime/DatelistElementFormTest.php
@@ -7,7 +7,7 @@
 use Drupal\Core\Form\FormInterface;
 use Drupal\Core\Form\FormState;
 use Drupal\Core\Form\FormStateInterface;
-use Drupal\Core\Security\TrustedCallbackInterface;
+use Drupal\Core\Security\Attribute\TrustedCallback;
 use Drupal\Core\Security\UntrustedCallbackException;
 use Drupal\KernelTests\KernelTestBase;
 
@@ -16,7 +16,7 @@
  *
  * @group Form
  */
-class DatelistElementFormTest extends KernelTestBase implements FormInterface, TrustedCallbackInterface {
+class DatelistElementFormTest extends KernelTestBase implements FormInterface {
 
   /**
    * Modules to enable.
@@ -42,6 +42,7 @@ public function getFormId() {
   /**
    * {@inheritdoc}
    */
+  #[TrustedCallback]
   public function datelistDateCallbackTrusted(array &$element, FormStateInterface $form_state, DrupalDateTime $date = NULL) {
     $element['datelistDateCallbackExecuted'] = [
       '#value' => TRUE,
@@ -127,13 +128,4 @@ public function testDatelistElementUntrustedCallbacks() : void {
     $form = \Drupal::formBuilder()->getForm($this, 'datelistDateCallback');
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public static function trustedCallbacks() {
-    return [
-      'datelistDateCallbackTrusted',
-    ];
-  }
-
 }
diff --git a/core/tests/Drupal/KernelTests/Core/Datetime/DatetimeElementFormTest.php b/core/tests/Drupal/KernelTests/Core/Datetime/DatetimeElementFormTest.php
index 3a474f3d8e..c9dad47e21 100644
--- a/core/tests/Drupal/KernelTests/Core/Datetime/DatetimeElementFormTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Datetime/DatetimeElementFormTest.php
@@ -7,7 +7,7 @@
 use Drupal\Core\Form\FormInterface;
 use Drupal\Core\Form\FormState;
 use Drupal\Core\Form\FormStateInterface;
-use Drupal\Core\Security\TrustedCallbackInterface;
+use Drupal\Core\Security\Attribute\TrustedCallback;
 use Drupal\Core\Security\UntrustedCallbackException;
 use Drupal\KernelTests\KernelTestBase;
 
@@ -16,7 +16,7 @@
  *
  * @group Form
  */
-class DatetimeElementFormTest extends KernelTestBase implements FormInterface, TrustedCallbackInterface {
+class DatetimeElementFormTest extends KernelTestBase implements FormInterface {
 
   /**
    * Modules to enable.
@@ -42,6 +42,7 @@ public function getFormId() {
   /**
    * {@inheritdoc}
    */
+  #[TrustedCallback]
   public function datetimeDateCallbackTrusted(array &$element, FormStateInterface $form_state, DrupalDateTime $date = NULL) {
     $element['datetimeDateCallbackExecuted'] = [
       '#value' => TRUE,
@@ -62,6 +63,7 @@ public function datetimeDateCallback(array &$element, FormStateInterface $form_s
   /**
    * {@inheritdoc}
    */
+  #[TrustedCallback]
   public function datetimeTimeCallbackTrusted(array &$element, FormStateInterface $form_state, DrupalDateTime $date = NULL) {
     $element['timeCallbackExecuted'] = [
       '#value' => TRUE,
@@ -207,14 +209,4 @@ public function testTimezoneHandling() {
     $this->assertEquals('UTC', $form['datetime_element']['#date_timezone']);
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public static function trustedCallbacks() {
-    return [
-      'datetimeDateCallbackTrusted',
-      'datetimeTimeCallbackTrusted',
-    ];
-  }
-
 }
diff --git a/core/tests/Drupal/Tests/Core/Render/RendererBubblingTest.php b/core/tests/Drupal/Tests/Core/Render/RendererBubblingTest.php
index e9041d9dea..9c1fa6153a 100644
--- a/core/tests/Drupal/Tests/Core/Render/RendererBubblingTest.php
+++ b/core/tests/Drupal/Tests/Core/Render/RendererBubblingTest.php
@@ -9,7 +9,7 @@
 
 use Drupal\Core\Cache\MemoryBackend;
 use Drupal\Core\KeyValueStore\KeyValueMemoryFactory;
-use Drupal\Core\Security\TrustedCallbackInterface;
+use Drupal\Core\Security\Attribute\TrustedCallback;
 use Drupal\Core\State\State;
 use Drupal\Core\Cache\Cache;
 
@@ -633,11 +633,12 @@ public function testOverWriteCacheKeys() {
 }
 
 
-class BubblingTest implements TrustedCallbackInterface {
+class BubblingTest {
 
   /**
    * #pre_render callback for testBubblingWithPrerender().
    */
+  #[TrustedCallback]
   public static function bubblingPreRender($elements) {
     $elements += [
       'child_cache_context' => [
@@ -677,6 +678,7 @@ public static function bubblingPreRender($elements) {
   /**
    * #pre_render callback for testBubblingWithPrerender().
    */
+  #[TrustedCallback]
   public static function bubblingNestedPreRenderUncached($elements) {
     \Drupal::state()->set('bubbling_nested_pre_render_uncached', TRUE);
     $elements['#markup'] = 'Nested!';
@@ -686,6 +688,7 @@ public static function bubblingNestedPreRenderUncached($elements) {
   /**
    * #pre_render callback for testBubblingWithPrerender().
    */
+  #[TrustedCallback]
   public static function bubblingNestedPreRenderCached($elements) {
     \Drupal::state()->set('bubbling_nested_pre_render_cached', TRUE);
     return $elements;
@@ -694,6 +697,7 @@ public static function bubblingNestedPreRenderCached($elements) {
   /**
    * #lazy_builder callback for testBubblingWithPrerender().
    */
+  #[TrustedCallback]
   public static function bubblingPlaceholder($foo, $baz) {
     return [
       '#markup' => 'Placeholder!' . $foo . $baz,
@@ -703,6 +707,7 @@ public static function bubblingPlaceholder($foo, $baz) {
   /**
    * #pre_render callback for testOverWriteCacheKeys().
    */
+  #[TrustedCallback]
   public static function bubblingCacheOverwritePrerender($elements) {
     // Overwrite the #cache entry with new data.
     $elements['#cache'] = [
@@ -712,11 +717,4 @@ public static function bubblingCacheOverwritePrerender($elements) {
     return $elements;
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public static function trustedCallbacks() {
-    return ['bubblingPreRender', 'bubblingNestedPreRenderUncached', 'bubblingNestedPreRenderCached', 'bubblingPlaceholder', 'bubblingCacheOverwritePrerender'];
-  }
-
 }
diff --git a/core/tests/Drupal/Tests/Core/Render/RendererPlaceholdersTest.php b/core/tests/Drupal/Tests/Core/Render/RendererPlaceholdersTest.php
index c23cc1943e..436ff8b95d 100644
--- a/core/tests/Drupal/Tests/Core/Render/RendererPlaceholdersTest.php
+++ b/core/tests/Drupal/Tests/Core/Render/RendererPlaceholdersTest.php
@@ -11,7 +11,7 @@
 use Drupal\Component\Utility\Html;
 use Drupal\Core\Cache\Cache;
 use Drupal\Core\Render\Markup;
-use Drupal\Core\Security\TrustedCallbackInterface;
+use Drupal\Core\Security\Attribute\TrustedCallback;
 use Drupal\Core\Render\RenderContext;
 
 /**
@@ -1159,7 +1159,7 @@ protected function setupThemeManagerForDetails() {
 /**
  * @see \Drupal\Tests\Core\Render\RendererPlaceholdersTest::testRecursivePlaceholder()
  */
-class RecursivePlaceholdersTest implements TrustedCallbackInterface {
+class RecursivePlaceholdersTest {
 
   /**
    * #lazy_builder callback; bubbles another placeholder.
@@ -1170,6 +1170,7 @@ class RecursivePlaceholdersTest implements TrustedCallbackInterface {
    * @return array
    *   A renderable array.
    */
+  #[TrustedCallback]
   public static function callback($animal) {
     return [
       'another' => [
@@ -1179,11 +1180,4 @@ public static function callback($animal) {
     ];
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public static function trustedCallbacks() {
-    return ['callback'];
-  }
-
 }
diff --git a/core/tests/Drupal/Tests/Core/Render/RendererTest.php b/core/tests/Drupal/Tests/Core/Render/RendererTest.php
index 7a2a7eedfb..33d4d74f1a 100644
--- a/core/tests/Drupal/Tests/Core/Render/RendererTest.php
+++ b/core/tests/Drupal/Tests/Core/Render/RendererTest.php
@@ -11,7 +11,7 @@
 use Drupal\Core\Access\AccessResult;
 use Drupal\Core\Access\AccessResultInterface;
 use Drupal\Core\Cache\Cache;
-use Drupal\Core\Security\TrustedCallbackInterface;
+use Drupal\Core\Security\Attribute\TrustedCallback;
 use Drupal\Core\Render\Element;
 use Drupal\Core\Render\Markup;
 use Drupal\Core\Template\Attribute;
@@ -1038,45 +1038,36 @@ public function providerTestAddCacheableDependency() {
 
 }
 
-class TestAccessClass implements TrustedCallbackInterface {
+class TestAccessClass {
 
+  #[TrustedCallback]
   public static function accessTrue() {
     return TRUE;
   }
 
+  #[TrustedCallback]
   public static function accessFalse() {
     return FALSE;
   }
 
+  #[TrustedCallback]
   public static function accessResultAllowed() {
     return AccessResult::allowed();
   }
 
+  #[TrustedCallback]
   public static function accessResultForbidden() {
     return AccessResult::forbidden();
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public static function trustedCallbacks() {
-    return ['accessTrue', 'accessFalse', 'accessResultAllowed', 'accessResultForbidden'];
-  }
-
 }
 
-class TestCallables implements TrustedCallbackInterface {
+class TestCallables {
 
+  #[TrustedCallback]
   public function preRenderPrinted($elements) {
     $elements['#printed'] = TRUE;
     return $elements;
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public static function trustedCallbacks() {
-    return ['preRenderPrinted'];
-  }
-
 }
diff --git a/core/tests/Drupal/Tests/Core/Render/RendererTestBase.php b/core/tests/Drupal/Tests/Core/Render/RendererTestBase.php
index 4419f04ceb..281220ed44 100644
--- a/core/tests/Drupal/Tests/Core/Render/RendererTestBase.php
+++ b/core/tests/Drupal/Tests/Core/Render/RendererTestBase.php
@@ -10,7 +10,7 @@
 use Drupal\Core\Cache\Cache;
 use Drupal\Core\Cache\Context\ContextCacheKeys;
 use Drupal\Core\Cache\MemoryBackend;
-use Drupal\Core\Security\TrustedCallbackInterface;
+use Drupal\Core\Security\Attribute\TrustedCallback;
 use Drupal\Core\Render\PlaceholderGenerator;
 use Drupal\Core\Render\PlaceholderingRenderCache;
 use Drupal\Core\Render\Renderer;
@@ -268,7 +268,7 @@ protected function assertRenderCacheItem($cid, $data, $bin = 'render') {
 }
 
 
-class PlaceholdersTest implements TrustedCallbackInterface {
+class PlaceholdersTest {
 
   /**
    * #lazy_builder callback; attaches setting, generates markup.
@@ -282,6 +282,7 @@ class PlaceholdersTest implements TrustedCallbackInterface {
    * @return array
    *   A renderable array.
    */
+  #[TrustedCallback]
   public static function callback($animal, $use_animal_as_array_key = FALSE) {
     $value = $animal;
     if ($use_animal_as_array_key) {
@@ -306,6 +307,7 @@ public static function callback($animal, $use_animal_as_array_key = FALSE) {
    * @return array
    *   A renderable array.
    */
+  #[TrustedCallback]
   public static function callbackPerUser($animal) {
     $build = static::callback($animal);
     $build['#cache']['contexts'][] = 'user';
@@ -321,6 +323,7 @@ public static function callbackPerUser($animal) {
    * @return array
    *   A renderable array.
    */
+  #[TrustedCallback]
   public static function callbackTagCurrentTemperature($animal) {
     $build = static::callback($animal);
     $build['#cache']['tags'][] = 'current-temperature';
@@ -333,15 +336,9 @@ public static function callbackTagCurrentTemperature($animal) {
    * @return bool
    *   TRUE, which is not a valid return value for a lazy builder.
    */
+  #[TrustedCallback]
   public static function callbackNonArrayReturn() {
     return TRUE;
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public static function trustedCallbacks() {
-    return ['callbackTagCurrentTemperature', 'callbackPerUser', 'callback', 'callbackNonArrayReturn'];
-  }
-
 }
diff --git a/core/tests/Drupal/Tests/Core/Security/DoTrustedCallbackTraitTest.php b/core/tests/Drupal/Tests/Core/Security/DoTrustedCallbackTraitTest.php
index cab6e8d68d..e63a08b9b8 100644
--- a/core/tests/Drupal/Tests/Core/Security/DoTrustedCallbackTraitTest.php
+++ b/core/tests/Drupal/Tests/Core/Security/DoTrustedCallbackTraitTest.php
@@ -33,10 +33,7 @@ public function providerTestTrustedCallbacks() {
     };
 
     $tests['closure'] = [$closure];
-    $tests['TrustedCallbackInterface_object'] = [[new TrustedMethods(), 'callback'], TrustedInterface::class];
     $tests['TrustedCallbackInterface_object_attribute'] = [[new TrustedMethods(), 'attributeCallback'], TrustedInterface::class];
-    $tests['TrustedCallbackInterface_static_string'] = ['\Drupal\Tests\Core\Security\TrustedMethods::callback', TrustedInterface::class];
-    $tests['TrustedCallbackInterface_static_array'] = [[TrustedMethods::class, 'callback'], TrustedInterface::class];
     $tests['TrustedCallbackInterface_static_array_attribute'] = [[TrustedMethods::class, 'attributeCallback'], TrustedInterface::class];
     $tests['extra_trusted_interface_object'] = [[new TrustedObject(), 'callback'], TrustedInterface::class];
     $tests['extra_trusted_interface_static_string'] = ['\Drupal\Tests\Core\Security\TrustedObject::callback', TrustedInterface::class];
@@ -67,6 +64,27 @@ public function providerTestUntrustedCallbacks() {
     return $tests;
   }
 
+  /**
+   * @covers ::doTrustedCallback
+   * @dataProvider providerTestDeprecatedTrustedCallbacks
+   * @group legacy
+   */
+  public function testDeprecatedTrustedCallbacks($callback, $extra_trusted_interface = NULL) {
+    $this->expectDeprecation('Usage of the Drupal\Core\Security\TrustedCallbackInterface is deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. Instead, you should use \Drupal\Core\Security\Attribute\TrustedCallback attribute for the method. See https://www.drupal.org/node/3349470');
+    $return = $this->doTrustedCallback($callback, [], '%s is not trusted', TrustedCallbackInterface::THROW_EXCEPTION, $extra_trusted_interface);
+    $this->assertSame('test', $return);
+  }
+
+  /**
+   * Data provider for ::testDeprecatedTrustedCallbacks().
+   */
+  public function providerTestDeprecatedTrustedCallbacks() {
+    $tests['TrustedCallbackInterface_object'] = [[new DeprecatedTrustedMethod(), 'callback'], TrustedInterface::class];
+    $tests['TrustedCallbackInterface_static_string'] = ['\Drupal\Tests\Core\Security\DeprecatedTrustedMethod::callback', TrustedInterface::class];
+    $tests['TrustedCallbackInterface_static_array'] = [[DeprecatedTrustedMethod::class, 'callback'], TrustedInterface::class];
+    return $tests;
+  }
+
   /**
    * @dataProvider errorTypeProvider
    */
@@ -133,22 +151,26 @@ public function __invoke() {
 
 }
 
-class TrustedMethods implements TrustedCallbackInterface {
+class TrustedMethods {
 
-  public static function trustedCallbacks() {
-    return ['callback'];
+  #[TrustedCallback]
+  public static function attributeCallback() {
+    return 'test';
   }
 
-  public static function callback() {
+  public static function unTrustedCallback() {
     return 'test';
   }
 
-  #[TrustedCallback]
-  public static function attributeCallback() {
-    return 'test';
+}
+
+class DeprecatedTrustedMethod implements TrustedCallbackInterface {
+
+  public static function trustedCallbacks() {
+    return ['callback'];
   }
 
-  public static function unTrustedCallback() {
+  public static function callback() {
     return 'test';
   }
 
diff --git a/core/themes/claro/src/ClaroPreRender.php b/core/themes/claro/src/ClaroPreRender.php
index 82f73ac9fa..f6ca03d005 100644
--- a/core/themes/claro/src/ClaroPreRender.php
+++ b/core/themes/claro/src/ClaroPreRender.php
@@ -3,18 +3,19 @@
 namespace Drupal\claro;
 
 use Drupal\Core\Render\Element;
-use Drupal\Core\Security\TrustedCallbackInterface;
+use Drupal\Core\Security\Attribute\TrustedCallback;
 
 /**
  * Implements trusted prerender callbacks for the Claro theme.
  *
  * @internal
  */
-class ClaroPreRender implements TrustedCallbackInterface {
+class ClaroPreRender {
 
   /**
    * Prerender callback for managed_file.
    */
+  #[TrustedCallback]
   public static function managedFile($element) {
     if (!empty($element['remove_button']) && is_array($element['remove_button'])) {
       $element['remove_button']['#attributes']['class'][] = 'button--extrasmall';
@@ -64,6 +65,7 @@ public static function managedFile($element) {
   /**
    * Prerender callback for Vertical Tabs element.
    */
+  #[TrustedCallback]
   public static function verticalTabs($element) {
     $group_type_is_details = isset($element['group']['#type']) && $element['group']['#type'] === 'details';
     $groups_are_present = isset($element['group']['#groups']) && is_array($element['group']['#groups']);
@@ -115,6 +117,7 @@ public static function verticalTabs($element) {
   /**
    * Prerender callback for the Operations element.
    */
+  #[TrustedCallback]
   public static function operations($element) {
     if (empty($element['#dropbutton_type'])) {
       $element['#dropbutton_type'] = 'extrasmall';
@@ -131,6 +134,7 @@ public static function operations($element) {
    * @return array
    *   The processed container element.
    */
+  #[TrustedCallback]
   public static function container(array $element) {
     if (!empty($element['#accordion'])) {
       // The container must work as an accordion list wrapper.
@@ -153,6 +157,7 @@ public static function container(array $element) {
   /**
    * Prerender callback for text_format elements.
    */
+  #[TrustedCallback]
   public static function textFormat($element) {
     // Add clearfix for filter wrapper.
     $element['format']['#attributes']['class'][] = 'clearfix';
@@ -182,6 +187,7 @@ public static function textFormat($element) {
    * @return array
    *   The updated renderable array containing the placeholder.
    */
+  #[TrustedCallback]
   public static function messagePlaceholder(array $element) {
     if (isset($element['fallback']['#markup'])) {
       $element['fallback']['#markup'] = '<div data-drupal-messages-fallback class="hidden messages-list"></div>';
@@ -189,18 +195,4 @@ public static function messagePlaceholder(array $element) {
     return $element;
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public static function trustedCallbacks() {
-    return [
-      'managedFile',
-      'verticalTabs',
-      'operations',
-      'container',
-      'textFormat',
-      'messagePlaceholder',
-    ];
-  }
-
 }
diff --git a/core/themes/olivero/src/OliveroPreRender.php b/core/themes/olivero/src/OliveroPreRender.php
index 39dbd09a0b..0651676490 100644
--- a/core/themes/olivero/src/OliveroPreRender.php
+++ b/core/themes/olivero/src/OliveroPreRender.php
@@ -2,18 +2,19 @@
 
 namespace Drupal\olivero;
 
-use Drupal\Core\Security\TrustedCallbackInterface;
+use Drupal\Core\Security\Attribute\TrustedCallback;
 
 /**
  * Implements trusted prerender callbacks for the Olivero theme.
  *
  * @internal
  */
-class OliveroPreRender implements TrustedCallbackInterface {
+class OliveroPreRender {
 
   /**
    * Prerender callback for text_format elements.
    */
+  #[TrustedCallback]
   public static function textFormat($element) {
     $element['format']['#attributes']['class'][] = 'filter-wrapper';
     $element['format']['format']['#wrapper_attributes']['class'][] = 'form-item--editor-format';
@@ -34,6 +35,7 @@ public static function textFormat($element) {
    * @return array
    *   The updated renderable array containing the placeholder.
    */
+  #[TrustedCallback]
   public static function messagePlaceholder(array $element) {
     if (isset($element['fallback']['#markup'])) {
       $element['fallback']['#markup'] = '<div data-drupal-messages-fallback class="hidden messages-list"></div>';
@@ -41,14 +43,4 @@ public static function messagePlaceholder(array $element) {
     return $element;
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public static function trustedCallbacks() {
-    return [
-      'textFormat',
-      'messagePlaceholder',
-    ];
-  }
-
 }
