diff --git a/e2e/test/scenarios/collections/instance-analytics.cy.spec.js b/e2e/test/scenarios/collections/instance-analytics.cy.spec.js
index dcbe3cf3aed651b16f9e1f35a1305dd29d95ec1e..d73e0c0fcb5235347277ae0ade18a8543c3f0933 100644
--- a/e2e/test/scenarios/collections/instance-analytics.cy.spec.js
+++ b/e2e/test/scenarios/collections/instance-analytics.cy.spec.js
@@ -1,3 +1,7 @@
+import {
+  ORDERS_DASHBOARD_ID,
+  ORDERS_QUESTION_ID,
+} from "e2e/support/cypress_sample_instance_data";
 import {
   restore,
   setTokenFeatures,
@@ -6,6 +10,8 @@ import {
   modal,
   visitDashboard,
   visitModel,
+  visitQuestion,
+  describeOSS,
 } from "e2e/support/helpers";
 
 const ANALYTICS_COLLECTION_NAME = "Metabase analytics";
@@ -251,6 +257,108 @@ describeEE("scenarios > Metabase Analytics Collection (AuditV2) ", () => {
   });
 });
 
+describe("question and dashboard links", () => {
+  describeEE("ee", () => {
+    beforeEach(() => {
+      restore();
+      cy.signInAsAdmin();
+      setTokenFeatures("all");
+    });
+
+    it("should show a analytics link for questions", () => {
+      visitQuestion(ORDERS_QUESTION_ID);
+
+      cy.intercept("GET", "/api/collection/**").as("collection");
+
+      cy.findByTestId("qb-header-action-panel")
+        .button(/\.\.\./)
+        .click();
+      popover().findByText("Usage insights").click();
+
+      cy.wait("@collection");
+
+      cy.findByDisplayValue("Question overview").should("exist");
+
+      cy.findByRole("button", { name: /Question ID/ }).should(
+        "contain.text",
+        ORDERS_QUESTION_ID,
+      );
+
+      cy.findAllByTestId("dashcard")
+        .contains("[data-testid=dashcard]", "Question metadata")
+        .within(() => {
+          cy.findByText("Entity ID");
+          cy.findByText(ORDERS_QUESTION_ID);
+          cy.findByText("Name");
+          cy.findByText("Orders");
+          cy.findByText("Entity Type");
+          cy.findByText("question");
+        });
+    });
+
+    it("should show a analytics link for dashboards", () => {
+      visitDashboard(ORDERS_DASHBOARD_ID);
+      cy.intercept("GET", "/api/collection/**").as("collection");
+      cy.button("dashboard-menu-button").click();
+      popover().findByText("Usage insights").click();
+
+      cy.wait("@collection");
+
+      cy.findByDisplayValue("Dashboard overview").should("exist");
+
+      cy.findByRole("button", { name: /Dashboard ID/ }).should(
+        "contain.text",
+        ORDERS_DASHBOARD_ID,
+      );
+
+      cy.findAllByTestId("dashcard")
+        .contains("[data-testid=dashcard]", "Dashboard metadata")
+        .within(() => {
+          cy.findByText("Entity ID");
+          cy.findByText(ORDERS_DASHBOARD_ID);
+          cy.findByText("Name");
+          cy.findByText("Orders in a dashboard");
+          cy.findByText("Entity Type");
+          cy.findByText("dashboard");
+        });
+    });
+
+    it("should not show option for users with no access to Metabase Analytics", () => {
+      cy.signInAsNormalUser();
+      visitQuestion(ORDERS_QUESTION_ID);
+
+      cy.findByTestId("qb-header-action-panel")
+        .button(/\.\.\./)
+        .click();
+      popover().findByText("Usage insights").should("not.exist");
+
+      visitDashboard(ORDERS_DASHBOARD_ID);
+
+      cy.button("dashboard-menu-button").click();
+      popover().findByText("Usage insights").should("not.exist");
+    });
+  });
+  describeOSS("oss", { tags: "@OSS" }, () => {
+    beforeEach(() => {
+      restore();
+      cy.signInAsAdmin();
+    });
+    it("should never appear in OSS", () => {
+      visitQuestion(ORDERS_QUESTION_ID);
+
+      cy.findByTestId("qb-header-action-panel")
+        .button(/\.\.\./)
+        .click();
+      popover().findByText("Usage insights").should("not.exist");
+
+      visitDashboard(ORDERS_DASHBOARD_ID);
+
+      cy.button("dashboard-menu-button").click();
+      popover().findByText("Usage insights").should("not.exist");
+    });
+  });
+});
+
 function getCollectionId(collectionName) {
   return cy.request("GET", "/api/collection").then(({ body }) => {
     const collection = body.find(({ name }) => name === collectionName);
diff --git a/enterprise/backend/src/metabase_enterprise/audit_app/api/user.clj b/enterprise/backend/src/metabase_enterprise/audit_app/api/user.clj
index 095337ff5754724fa95e652b9e827978488cf9af..67122333ffa6aa5a85436d5a745d40647bed0d83 100644
--- a/enterprise/backend/src/metabase_enterprise/audit_app/api/user.clj
+++ b/enterprise/backend/src/metabase_enterprise/audit_app/api/user.clj
@@ -1,14 +1,32 @@
 (ns metabase-enterprise.audit-app.api.user
   "`/api/ee/audit-app/user` endpoints. These only work if you have a premium token with the `:audit-app` feature."
   (:require
-   [compojure.core :refer [DELETE]]
+   [compojure.core :refer [DELETE GET]]
+   [metabase-enterprise.audit-db :as audit-db]
    [metabase.api.common :as api]
    [metabase.api.user :as api.user]
+   [metabase.models.interface :as mi]
    [metabase.models.pulse :refer [Pulse]]
    [metabase.models.pulse-channel-recipient :refer [PulseChannelRecipient]]
+   [metabase.util :as u]
    [metabase.util.malli.schema :as ms]
    [toucan2.core :as t2]))
 
+(api/defendpoint GET "/audit-info"
+  "Gets audit info for the current user if he has permissions to access the audit collection.
+  Otherwise return an empty map."
+  []
+  (let [custom-reports     (audit-db/default-custom-reports-collection)
+        question-overview  (audit-db/entity-id->object :model/Dashboard audit-db/default-question-overview-entity-id)
+        dashboard-overview (audit-db/entity-id->object :model/Dashboard audit-db/default-dashboard-overview-entity-id)]
+    (merge
+     {}
+     (when (mi/can-read? (audit-db/default-custom-reports-collection))
+       {(:slug custom-reports) (:id custom-reports)})
+     (when (mi/can-read? (audit-db/default-audit-collection))
+       {(u/slugify (:name question-overview)) (:id question-overview)
+        (u/slugify (:name dashboard-overview)) (:id dashboard-overview)}))))
+
 (api/defendpoint DELETE "/:id/subscriptions"
   "Delete all Alert and DashboardSubscription subscriptions for a User (i.e., so they will no longer receive them).
   Archive all Alerts and DashboardSubscriptions created by the User. Only allowed for admins or for the current user."
diff --git a/enterprise/backend/src/metabase_enterprise/audit_db.clj b/enterprise/backend/src/metabase_enterprise/audit_db.clj
index 9e692439da9242898895424c34d4bbf74cfbfb71..281c4026b929d118630a54254e39af939e564848 100644
--- a/enterprise/backend/src/metabase_enterprise/audit_db.clj
+++ b/enterprise/backend/src/metabase_enterprise/audit_db.clj
@@ -76,24 +76,33 @@
   "Default custom reports entity id."
   "okNLSZKdSxaoG58JSQY54")
 
-(defn collection-entity-id->collection
-  "Returns the collection from entity id for collections. Memoizes from entity id."
-  [entity-id]
+(def default-question-overview-entity-id
+  "Default Question Overview (this is a dashboard) entity id."
+  "jm7KgY6IuS6pQjkBZ7WUI")
+
+(def default-dashboard-overview-entity-id
+  "Default Dashboard Overview (this is a dashboard) entity id."
+  "bJEYb0o5CXlfWFcIztDwJ")
+
+(defn entity-id->object
+  "Returns the object from entity id and model. Memoizes from entity id.
+  Should only be used for audit/pre-loaded objects."
+  [model entity-id]
   ((mdb.connection/memoize-for-application-db
     (fn [entity-id]
-      (t2/select-one :model/Collection :entity_id entity-id))) entity-id))
+      (t2/select-one model :entity_id entity-id))) entity-id))
 
 (defenterprise default-custom-reports-collection
   "Default custom reports collection."
   :feature :none
   []
-  (collection-entity-id->collection default-custom-reports-entity-id))
+  (entity-id->object :model/Collection default-custom-reports-entity-id))
 
 (defenterprise default-audit-collection
   "Default audit collection (instance analytics) collection."
   :feature :none
   []
-  (collection-entity-id->collection default-audit-collection-entity-id))
+  (entity-id->object :model/Collection default-audit-collection-entity-id))
 
 (defn- install-database!
   "Creates the audit db, a clone of the app db used for auditing purposes.
diff --git a/enterprise/backend/test/metabase_enterprise/audit_app/api/user_test.clj b/enterprise/backend/test/metabase_enterprise/audit_app/api/user_test.clj
index 9c61a124061055766f05867711635f298ba24811..19e5d8ec604f0b2e9e316233c70a9d4e94b1b13f 100644
--- a/enterprise/backend/test/metabase_enterprise/audit_app/api/user_test.clj
+++ b/enterprise/backend/test/metabase_enterprise/audit_app/api/user_test.clj
@@ -1,7 +1,12 @@
 (ns ^:mb/once metabase-enterprise.audit-app.api.user-test
   (:require
    [clojure.test :refer :all]
-   [metabase.models :refer [Card Dashboard DashboardCard Pulse PulseCard PulseChannel PulseChannelRecipient User]]
+   [metabase-enterprise.audit-app.permissions-test :as ee-perms-test]
+   [metabase-enterprise.audit-db :as audit-db]
+   [metabase.models :refer [Card Dashboard DashboardCard Pulse PulseCard
+                            PulseChannel PulseChannelRecipient User]]
+   [metabase.models.permissions :as perms]
+   [metabase.models.permissions-group :as perms-group]
    [metabase.test :as mt]
    [toucan2.core :as t2]
    [toucan2.tools.with-temp :as t2.with-temp]))
@@ -83,3 +88,30 @@
                           :alert-archived?                  true
                           :dashboard-subscription-archived? true}
                          (describe-objects))))))))))))
+
+(deftest get-audit-info-test
+  (testing "GET /api/ee/audit-app/user/audit-info"
+    (mt/with-premium-features #{:audit-app}
+      (ee-perms-test/install-audit-db-if-needed!)
+      (testing "None of the ids show up when perms aren't given"
+        (perms/revoke-collection-permissions! (perms-group/all-users) (audit-db/default-custom-reports-collection))
+        (perms/revoke-collection-permissions! (perms-group/all-users) (audit-db/default-audit-collection))
+        (is (= #{}
+               (->>
+                (mt/user-http-request :rasta :get 200 "/ee/audit-app/user/audit-info")
+                keys
+                (into #{})))))
+      (testing "Custom reports collection shows up when perms are given"
+        (perms/grant-collection-read-permissions! (perms-group/all-users) (audit-db/default-custom-reports-collection))
+        (is (= #{:custom_reports}
+               (->>
+                (mt/user-http-request :rasta :get 200 "/ee/audit-app/user/audit-info")
+                keys
+                (into #{})))))
+      (testing "Everything shows up when all perms are given"
+        (perms/grant-collection-read-permissions! (perms-group/all-users) (audit-db/default-audit-collection))
+        (is (= #{:question_overview :dashboard_overview :custom_reports}
+               (->>
+                (mt/user-http-request :rasta :get 200 "/ee/audit-app/user/audit-info")
+                keys
+                (into #{}))))))))
diff --git a/enterprise/backend/test/metabase_enterprise/audit_app/permissions_test.clj b/enterprise/backend/test/metabase_enterprise/audit_app/permissions_test.clj
index 6a409bbbdf0f2031180c505f8420155c7ab35600..d80c4d9a24d62a791c9faf4fbc4bc734842beb0a 100644
--- a/enterprise/backend/test/metabase_enterprise/audit_app/permissions_test.clj
+++ b/enterprise/backend/test/metabase_enterprise/audit_app/permissions_test.clj
@@ -116,7 +116,7 @@
                (update-graph! (assoc-in (graph :clear-revisions? true) [:groups group-id (:id collection)] :write)))))))))
 
 ;; TODO: re-enable these tests once they're no longer flaky
-(defn- install-audit-db-if-needed!
+(defn install-audit-db-if-needed!
   "Checks if there's an audit-db. if not, it will create it and serialize audit content, including the
   `default-audit-collection`. If the audit-db is there, this does nothing."
   []
diff --git a/enterprise/frontend/src/metabase-enterprise/audit_app/components/InstanceAnalyticsButton/InstanceAnalyticsButton.tsx b/enterprise/frontend/src/metabase-enterprise/audit_app/components/InstanceAnalyticsButton/InstanceAnalyticsButton.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..897e418c3f6e58b94c2a25d8e3bba6b392cafb5f
--- /dev/null
+++ b/enterprise/frontend/src/metabase-enterprise/audit_app/components/InstanceAnalyticsButton/InstanceAnalyticsButton.tsx
@@ -0,0 +1,46 @@
+import { t } from "ttag";
+import { useEffect } from "react";
+import { push } from "react-router-redux";
+import { loadInfo } from "metabase-enterprise/audit_app/reducer";
+import EntityMenuItem from "metabase/components/EntityMenuItem";
+import { useDispatch, useSelector } from "metabase/lib/redux";
+import type { AuditInfoState } from "metabase-enterprise/audit_app/types/state";
+import type { DashboardId } from "metabase-types/api";
+
+interface InstanceAnalyticsButtonProps {
+  entitySelector: (state: AuditInfoState) => number;
+  linkQueryParams: { dashboard_id: DashboardId } | { question_id: number };
+}
+
+export const InstanceAnalyticsButton = ({
+  entitySelector,
+  linkQueryParams,
+}: InstanceAnalyticsButtonProps) => {
+  const dispatch = useDispatch();
+  const entityId = useSelector(state =>
+    entitySelector(state as AuditInfoState),
+  );
+
+  useEffect(() => {
+    dispatch(loadInfo());
+  }, [dispatch]);
+
+  if (entityId !== undefined) {
+    return (
+      <EntityMenuItem
+        icon="audit"
+        title={t`Usage insights`}
+        action={() => {
+          dispatch(
+            push({
+              pathname: `/dashboard/${entityId}`,
+              query: linkQueryParams,
+            }),
+          );
+        }}
+      />
+    );
+  } else {
+    return null;
+  }
+};
diff --git a/enterprise/frontend/src/metabase-enterprise/audit_app/index.js b/enterprise/frontend/src/metabase-enterprise/audit_app/index.js
index e7cf09827e4583fa49a6e97a72b858fd8bce6077..328ea47a596c455bfb0889126c53e3eba4ccb3d4 100644
--- a/enterprise/frontend/src/metabase-enterprise/audit_app/index.js
+++ b/enterprise/frontend/src/metabase-enterprise/audit_app/index.js
@@ -4,9 +4,16 @@ import {
   PLUGIN_ADMIN_ROUTES,
   PLUGIN_ADMIN_USER_MENU_ITEMS,
   PLUGIN_ADMIN_USER_MENU_ROUTES,
+  PLUGIN_REDUCERS,
+  PLUGIN_DASHBOARD_HEADER,
+  PLUGIN_QUERY_BUILDER_HEADER,
 } from "metabase/plugins";
 import { hasPremiumFeature } from "metabase-enterprise/settings";
 import getAuditRoutes, { getUserMenuRotes } from "./routes";
+import { auditInfo } from "./reducer";
+import { getDashboardOverviewId, getQuestionOverviewId } from "./selectors";
+
+import { InstanceAnalyticsButton } from "./components/InstanceAnalyticsButton/InstanceAnalyticsButton";
 
 if (hasPremiumFeature("audit_app")) {
   PLUGIN_ADMIN_NAV_ITEMS.push({
@@ -24,4 +31,34 @@ if (hasPremiumFeature("audit_app")) {
   ]);
 
   PLUGIN_ADMIN_USER_MENU_ROUTES.push(getUserMenuRotes);
+
+  PLUGIN_REDUCERS.auditInfo = auditInfo;
+
+  PLUGIN_DASHBOARD_HEADER.extraButtons = dashboard => {
+    return [
+      {
+        key: "Usage insights",
+        component: (
+          <InstanceAnalyticsButton
+            entitySelector={getDashboardOverviewId}
+            linkQueryParams={{ dashboard_id: dashboard.id }}
+          />
+        ),
+      },
+    ];
+  };
+
+  PLUGIN_QUERY_BUILDER_HEADER.extraButtons = question => {
+    return [
+      {
+        key: "Usage insights",
+        component: (
+          <InstanceAnalyticsButton
+            entitySelector={getQuestionOverviewId}
+            linkQueryParams={{ question_id: question.id() }}
+          />
+        ),
+      },
+    ];
+  };
 }
diff --git a/enterprise/frontend/src/metabase-enterprise/audit_app/reducer.ts b/enterprise/frontend/src/metabase-enterprise/audit_app/reducer.ts
new file mode 100644
index 0000000000000000000000000000000000000000..135113c8a4e7b9d05aab163c91d01d284afc23e5
--- /dev/null
+++ b/enterprise/frontend/src/metabase-enterprise/audit_app/reducer.ts
@@ -0,0 +1,40 @@
+import { createReducer } from "@reduxjs/toolkit";
+import { createAsyncThunk } from "metabase/lib/redux";
+
+import { GET } from "metabase/lib/api";
+import { isAuditInfoComplete } from "./selectors";
+import type { AuditInfoState } from "./types/state";
+
+const getAuditInfo = GET("/api/ee/audit-app/user/audit-info");
+
+const LOAD_AUDIT_INFO = "metabase-enterprise/audit/FETCH_AUDIT_INFO";
+
+export const loadInfo = createAsyncThunk(
+  LOAD_AUDIT_INFO,
+  async (_, { getState }) => {
+    const state = getState() as AuditInfoState;
+    const isComplete = isAuditInfoComplete(state);
+    if (!isComplete) {
+      const data = await getAuditInfo();
+      return data;
+    }
+  },
+);
+
+const initialState = {
+  isLoading: false,
+  isComplete: false,
+  data: undefined,
+};
+
+export const auditInfo = createReducer(initialState, builder => {
+  builder.addCase(loadInfo.pending, state => {
+    state.isLoading = true;
+  });
+
+  builder.addCase(loadInfo.fulfilled, (state, { payload }) => {
+    state.isLoading = false;
+    state.isComplete = true;
+    state.data = payload || state.data;
+  });
+});
diff --git a/enterprise/frontend/src/metabase-enterprise/audit_app/selectors.ts b/enterprise/frontend/src/metabase-enterprise/audit_app/selectors.ts
new file mode 100644
index 0000000000000000000000000000000000000000..817be82a2c9ca7014c9c41478479e5beba244fb7
--- /dev/null
+++ b/enterprise/frontend/src/metabase-enterprise/audit_app/selectors.ts
@@ -0,0 +1,20 @@
+import type { AuditInfoState } from "./types/state";
+
+export const isAuditInfoLoading = (state: AuditInfoState) => {
+  const {
+    plugins: { auditInfo },
+  } = state;
+  return auditInfo.isLoading;
+};
+
+export const isAuditInfoComplete = (state: AuditInfoState) => {
+  const {
+    plugins: { auditInfo },
+  } = state;
+  return auditInfo.isComplete;
+};
+
+export const getDashboardOverviewId = (state: AuditInfoState) =>
+  state.plugins.auditInfo.data?.dashboard_overview ?? undefined;
+export const getQuestionOverviewId = (state: AuditInfoState) =>
+  state.plugins.auditInfo.data?.question_overview ?? undefined;
diff --git a/enterprise/frontend/src/metabase-enterprise/audit_app/types/state.ts b/enterprise/frontend/src/metabase-enterprise/audit_app/types/state.ts
new file mode 100644
index 0000000000000000000000000000000000000000..dd889e59a8d2955d4a2a6ce44c6a2134f486be09
--- /dev/null
+++ b/enterprise/frontend/src/metabase-enterprise/audit_app/types/state.ts
@@ -0,0 +1,15 @@
+import type { DashboardId } from "metabase-types/api";
+import type { State } from "metabase-types/store";
+
+export interface AuditInfoState extends State {
+  plugins: {
+    auditInfo: {
+      isLoading: boolean;
+      isComplete: boolean;
+      data: {
+        dashboard_overview: DashboardId;
+        question_overview: number;
+      };
+    };
+  };
+}
diff --git a/frontend/src/metabase/components/EntityMenu/EntityMenu.jsx b/frontend/src/metabase/components/EntityMenu/EntityMenu.jsx
index 087fe0f01428ba67f0148ec4cd78045d58d56276..5ec73f8bd695530d5853703b256b5e8765f11efc 100644
--- a/frontend/src/metabase/components/EntityMenu/EntityMenu.jsx
+++ b/frontend/src/metabase/components/EntityMenu/EntityMenu.jsx
@@ -107,6 +107,12 @@ class EntityMenu extends Component {
                       />
                     </li>
                   );
+                } else if (item.component) {
+                  return (
+                    <li key={item.title} data-testid={item.testId}>
+                      {item.component}
+                    </li>
+                  );
                 } else {
                   return (
                     <li key={item.title} data-testid={item.testId}>
diff --git a/frontend/src/metabase/dashboard/components/DashboardHeader/DashboardHeader.tsx b/frontend/src/metabase/dashboard/components/DashboardHeader/DashboardHeader.tsx
index 99a9793b7c5f39f211431376024ec7c0f2dcc8ad..16ddadc46a428ba501ccba640762a637830a67d0 100644
--- a/frontend/src/metabase/dashboard/components/DashboardHeader/DashboardHeader.tsx
+++ b/frontend/src/metabase/dashboard/components/DashboardHeader/DashboardHeader.tsx
@@ -4,7 +4,7 @@ import { connect } from "react-redux";
 import { push } from "react-router-redux";
 import { msgid, ngettext, t } from "ttag";
 import _ from "underscore";
-import type { Location } from "history";
+import type { Location, LocationDescriptor } from "history";
 
 import { trackExportDashboardToPDF } from "metabase/dashboard/analytics";
 
@@ -73,6 +73,7 @@ import type {
   State,
 } from "metabase-types/store";
 
+import { PLUGIN_DASHBOARD_HEADER } from "metabase/plugins";
 import type { UiParameter } from "metabase-lib/parameters/types";
 import { ExtraEditButtonsMenu } from "../ExtraEditButtonsMenu/ExtraEditButtonsMenu";
 import { DashboardButtonTooltip } from "../DashboardButtonTooltip";
@@ -162,7 +163,7 @@ interface DispatchProps {
   deleteBookmark: (args: { id: DashboardId }) => void;
   fetchPulseFormInput: () => void;
   toggleSidebar: (sidebarName: DashboardSidebarName) => void;
-  onChangeLocation: (location: Location) => void;
+  onChangeLocation: (location: LocationDescriptor) => void;
   addActionToDashboard: (
     opts: NewDashCardOpts & {
       action: Partial<WritebackAction>;
@@ -591,6 +592,8 @@ class DashboardHeaderContainer extends Component<DashboardHeaderProps> {
           link: `${location.pathname}/archive`,
           event: "Dashboard;Archive",
         });
+
+        extraButtons.push(...PLUGIN_DASHBOARD_HEADER.extraButtons(dashboard));
       }
     }
 
diff --git a/frontend/src/metabase/plugins/index.ts b/frontend/src/metabase/plugins/index.ts
index 70337e44511e37ecd9da7d477d1f9b86d8a43372..8795442dd9c6b268bc4836ee265f659817138291 100644
--- a/frontend/src/metabase/plugins/index.ts
+++ b/frontend/src/metabase/plugins/index.ts
@@ -15,6 +15,7 @@ import type {
   Collection,
   CollectionAuthorityLevelConfig,
   CollectionInstanceAnaltyicsConfig,
+  Dashboard,
   Dataset,
   Group,
   GroupPermissions,
@@ -130,6 +131,7 @@ export const PLUGIN_SELECTORS = {
   getIsWhiteLabeling: (_state: State) => false,
   getApplicationName: (_state: State) => "Metabase",
   getShowMetabaseLinks: (_state: State) => true,
+  getDashboardOverviewId: (_state: State) => undefined,
 };
 
 export const PLUGIN_FORM_WIDGETS: Record<string, ComponentType<any>> = {};
@@ -251,10 +253,12 @@ export const PLUGIN_REDUCERS: {
   applicationPermissionsPlugin: any;
   sandboxingPlugin: any;
   shared: any;
+  auditInfo: any;
 } = {
   applicationPermissionsPlugin: () => null,
   sandboxingPlugin: () => null,
   shared: () => null,
+  auditInfo: () => null,
 };
 
 export const PLUGIN_ADVANCED_PERMISSIONS = {
@@ -323,3 +327,11 @@ export const PLUGIN_EMBEDDING = {
 export const PLUGIN_CONTENT_VERIFICATION = {
   VerifiedFilter: {} as SearchFilterComponent<"verified">,
 };
+
+export const PLUGIN_DASHBOARD_HEADER = {
+  extraButtons: (_dashboard: Dashboard) => [],
+};
+
+export const PLUGIN_QUERY_BUILDER_HEADER = {
+  extraButtons: (_question: Question) => [],
+};
diff --git a/frontend/src/metabase/query_builder/components/view/ViewHeader/components/QuestionActions/QuestionActions.tsx b/frontend/src/metabase/query_builder/components/view/ViewHeader/components/QuestionActions/QuestionActions.tsx
index d8125849ee78bb0e00340af918b8129e6082b868..ffcfb548eb5ba4c6c2fce0cc33020100a9efdce7 100644
--- a/frontend/src/metabase/query_builder/components/view/ViewHeader/components/QuestionActions/QuestionActions.tsx
+++ b/frontend/src/metabase/query_builder/components/view/ViewHeader/components/QuestionActions/QuestionActions.tsx
@@ -7,7 +7,11 @@ import Button from "metabase/core/components/Button";
 import Tooltip from "metabase/core/components/Tooltip";
 import EntityMenu from "metabase/components/EntityMenu";
 
-import { PLUGIN_MODERATION, PLUGIN_MODEL_PERSISTENCE } from "metabase/plugins";
+import {
+  PLUGIN_MODERATION,
+  PLUGIN_MODEL_PERSISTENCE,
+  PLUGIN_QUERY_BUILDER_HEADER,
+} from "metabase/plugins";
 
 import { MODAL_TYPES } from "metabase/query_builder/constants";
 
@@ -224,6 +228,8 @@ export const QuestionActions = ({
     });
   }
 
+  extraButtons.push(...PLUGIN_QUERY_BUILDER_HEADER.extraButtons(question));
+
   const fileInputRef = useRef<HTMLInputElement>(null);
 
   const handleUploadClick = () => {