diff --git a/public/app/features/plugins/admin/components/PluginSubtitle.test.tsx b/public/app/features/plugins/admin/components/PluginSubtitle.test.tsx
new file mode 100644
index 00000000000..cf2efa6fe54
--- /dev/null
+++ b/public/app/features/plugins/admin/components/PluginSubtitle.test.tsx
@@ -0,0 +1,120 @@
+import { render, screen } from '@testing-library/react';
+
+import { PluginSignatureStatus } from '@grafana/data';
+import { contextSrv } from 'app/core/core';
+
+import * as runtime from '../state/hooks';
+import { CatalogPlugin } from '../types';
+
+import { PluginSubtitle, registerPluginSubtitleExtension } from './PluginSubtitle';
+
+jest.mock('../state/hooks', () => ({
+  useIsRemotePluginsAvailable: jest.fn().mockReturnValue(true),
+  useInstallStatus: jest.fn().mockReturnValue({ error: null }),
+}));
+
+describe('PluginSubtitle', () => {
+  const basePlugin: CatalogPlugin = {
+    description: 'Test description',
+    downloads: 5,
+    id: 'test-plugin',
+    name: 'Test Plugin',
+    orgName: 'Test',
+    signature: PluginSignatureStatus.valid,
+    isInstalled: false,
+    hasUpdate: false,
+    isCore: false,
+    isDev: false,
+    details: {
+      links: [{ name: 'Website', url: 'http://test.com' }],
+      versions: [{ version: '1.0.0', grafanaDependency: '>=9.0.0', isCompatible: true, createdAt: '2020-01-01' }],
+    },
+    publishedAt: '2020-09-01',
+    updatedAt: '2021-06-28',
+    isEnterprise: false,
+    isDisabled: false,
+    isDeprecated: false,
+    isPublished: true,
+    isManaged: false,
+    isPreinstalled: { found: false, withVersion: false },
+    info: {
+      logos: {
+        small: 'https://grafana.com/api/plugins/test-plugin/versions/0.0.10/logos/small',
+        large: 'https://grafana.com/api/plugins/test-plugin/versions/0.0.10/logos/large',
+      },
+      keywords: ['test', 'plugin'],
+    },
+    popularity: 0,
+  };
+
+  beforeEach(() => {});
+  afterEach(() => {
+    jest.clearAllMocks();
+  });
+
+  it('renders nothing when no plugin provided', () => {
+    const { container } = render(<PluginSubtitle />);
+    expect(container.firstChild).toBeNull();
+  });
+
+  it('renders plugin description', () => {
+    render(<PluginSubtitle plugin={basePlugin} />);
+    expect(screen.getByText('Test description')).toBeInTheDocument();
+  });
+
+  it('renders links', () => {
+    render(<PluginSubtitle plugin={basePlugin} />);
+    expect(screen.getByText('Website')).toHaveAttribute('href', 'http://test.com');
+  });
+
+  it('shows error alert when installation error exists', () => {
+    jest.spyOn(runtime, 'useInstallStatus').mockReturnValueOnce({
+      error: { message: 'Install failed', error: 'Details' },
+      isInstalling: false,
+    });
+    render(<PluginSubtitle plugin={basePlugin} />);
+    expect(screen.getByText('Install failed')).toBeInTheDocument();
+  });
+
+  describe('warning when no permissions', () => {
+    beforeEach(() => {
+      jest.spyOn(contextSrv, 'hasPermission').mockReturnValue(false);
+    });
+
+    it('renders install control warning when conditions are met', () => {
+      const plugin = { ...basePlugin, isInstalled: false };
+      render(<PluginSubtitle plugin={plugin} />);
+      expect(screen.queryByText(/permission to install/i)).toBeInTheDocument();
+    });
+
+    it('renders uninstall control warning when conditions are met', () => {
+      const plugin = { ...basePlugin, isInstalled: true };
+      render(<PluginSubtitle plugin={plugin} />);
+      expect(screen.queryByText(/permission to uninstall/i)).toBeInTheDocument();
+    });
+  });
+
+  describe('no warning when has permissions', () => {
+    beforeEach(() => {
+      jest.spyOn(contextSrv, 'hasPermission').mockReturnValue(true);
+    });
+
+    it('renders install control warning when conditions are met', () => {
+      const plugin = { ...basePlugin, isInstalled: false };
+      render(<PluginSubtitle plugin={plugin} />);
+      expect(screen.queryByText(/permission to install/i)).not.toBeInTheDocument();
+    });
+
+    it('renders uninstall control warning when conditions are met', () => {
+      const plugin = { ...basePlugin, isInstalled: true };
+      render(<PluginSubtitle plugin={plugin} />);
+      expect(screen.queryByText(/permission to uninstall/i)).not.toBeInTheDocument();
+    });
+  });
+  it('renders plugin subtitle extensions', () => {
+    const TestExtension = () => <div>Extension Content</div>;
+    registerPluginSubtitleExtension(TestExtension);
+    render(<PluginSubtitle plugin={basePlugin} />);
+    expect(screen.getByText('Extension Content')).toBeInTheDocument();
+  });
+});
diff --git a/public/app/features/plugins/admin/components/PluginSubtitle.tsx b/public/app/features/plugins/admin/components/PluginSubtitle.tsx
index 53e604bd110..926d27ac198 100644
--- a/public/app/features/plugins/admin/components/PluginSubtitle.tsx
+++ b/public/app/features/plugins/admin/components/PluginSubtitle.tsx
@@ -3,7 +3,7 @@ import { Fragment } from 'react';
 
 import { GrafanaTheme2 } from '@grafana/data';
 import { config } from '@grafana/runtime';
-import { Alert, useStyles2 } from '@grafana/ui';
+import { Alert, Stack, useStyles2 } from '@grafana/ui';
 
 import { InstallControlsWarning } from '../components/InstallControls';
 import { getLatestCompatibleVersion, hasInstallControlWarning } from '../helpers';
@@ -14,6 +14,14 @@ interface Props {
   plugin?: CatalogPlugin;
 }
 
+type PluginSubtitleExtension = (props: Props) => JSX.Element | null;
+
+const pluginSubtitleExtensions: PluginSubtitleExtension[] = [];
+
+export const registerPluginSubtitleExtension = (extension: PluginSubtitleExtension) => {
+  pluginSubtitleExtensions.push(extension);
+};
+
 export const PluginSubtitle = ({ plugin }: Props) => {
   const isRemotePluginsAvailable = useIsRemotePluginsAvailable();
   const styles = useStyles2(getStyles);
@@ -35,26 +43,33 @@ export const PluginSubtitle = ({ plugin }: Props) => {
           {typeof errorInstalling === 'string' ? errorInstalling : errorInstalling.error}
         </Alert>
       )}
-      {plugin?.description && <div>{plugin?.description}</div>}
-      {!config.featureToggles.pluginsDetailsRightPanel && !!plugin?.details?.links?.length && (
-        <span>
-          {plugin.details.links.map((link, index) => (
-            <Fragment key={index}>
-              {index > 0 && ' | '}
-              <a href={link.url} className="external-link">
-                {link.name}
-              </a>
-            </Fragment>
-          ))}
-        </span>
-      )}
-      {hasInstallControlWarning(plugin, isRemotePluginsAvailable, latestCompatibleVersion) && (
-        <InstallControlsWarning
-          plugin={plugin}
-          pluginStatus={pluginStatus}
-          latestCompatibleVersion={latestCompatibleVersion}
-        />
-      )}
+      <Stack direction="row" justifyContent="space-between">
+        <div>
+          {plugin?.description && <div>{plugin?.description}</div>}
+          {!config.featureToggles.pluginsDetailsRightPanel && !!plugin?.details?.links?.length && (
+            <span>
+              {plugin.details.links.map((link, index) => (
+                <Fragment key={index}>
+                  {index > 0 && ' | '}
+                  <a href={link.url} className="external-link">
+                    {link.name}
+                  </a>
+                </Fragment>
+              ))}
+            </span>
+          )}
+          {hasInstallControlWarning(plugin, isRemotePluginsAvailable, latestCompatibleVersion) && (
+            <InstallControlsWarning
+              plugin={plugin}
+              pluginStatus={pluginStatus}
+              latestCompatibleVersion={latestCompatibleVersion}
+            />
+          )}
+        </div>
+        {pluginSubtitleExtensions.map((extension) => {
+          return <Fragment key={extension.name}>{extension({ plugin })}</Fragment>;
+        })}
+      </Stack>
     </div>
   );
 };
diff --git a/public/app/features/plugins/sandbox/sandbox_plugin_loader_registry.ts b/public/app/features/plugins/sandbox/sandbox_plugin_loader_registry.ts
index c4bc6128a54..42848ce7863 100644
--- a/public/app/features/plugins/sandbox/sandbox_plugin_loader_registry.ts
+++ b/public/app/features/plugins/sandbox/sandbox_plugin_loader_registry.ts
@@ -25,7 +25,7 @@ export async function shouldLoadPluginInFrontendSandbox({
   pluginId,
 }: SandboxEligibilityCheckParams): Promise<boolean> {
   // basic check if the plugin is eligible for the sandbox
-  if (!(await isPluginFrontendSandboxElegible({ isAngular, pluginId }))) {
+  if (!(await isPluginFrontendSandboxEligible({ isAngular, pluginId }))) {
     return false;
   }
 
@@ -36,7 +36,7 @@ export async function shouldLoadPluginInFrontendSandbox({
  * This is a basic check that checks if the plugin is eligible to run in the sandbox.
  * It does not check if the plugin is actually enabled for the sandbox.
  */
-async function isPluginFrontendSandboxElegible({
+export async function isPluginFrontendSandboxEligible({
   isAngular,
   pluginId,
 }: SandboxEligibilityCheckParams): Promise<boolean> {
@@ -61,9 +61,14 @@ async function isPluginFrontendSandboxElegible({
     return false;
   }
 
-  // don't run grafana-signed plugins in sandbox
-  const pluginMeta = await getPluginSettings(pluginId);
-  if (pluginMeta.signatureType === PluginSignatureType.grafana) {
+  try {
+    // don't run grafana-signed plugins in sandbox
+    const pluginMeta = await getPluginSettings(pluginId, { showErrorAlert: false });
+    if (pluginMeta.signatureType === PluginSignatureType.grafana) {
+      return false;
+    }
+  } catch (e) {
+    // this can fail if we are trying to fetch settings of a non-installed plugin
     return false;
   }