diff --git a/enterprise/backend/src/metabase_enterprise/audit_db.clj b/enterprise/backend/src/metabase_enterprise/audit_db.clj
index 65a8cf10ae54e7f081cd028805e7e4e72f092a53..b3b8bd6157030560e78d3dd452dc900174ad7c86 100644
--- a/enterprise/backend/src/metabase_enterprise/audit_db.clj
+++ b/enterprise/backend/src/metabase_enterprise/audit_db.clj
@@ -4,7 +4,7 @@
             [metabase.config :as config]
             [metabase.db.env :as mdb.env]
             [metabase.models.database :refer [Database]]
-            [metabase.public-settings.premium-features :refer [defenterprise]]
+            [metabase.public-settings.premium-features :refer [defenterprise] :as premium-features]
             [metabase.sync.sync-metadata :as sync-metadata]
             [metabase.util :as u]
             [metabase.util.log :as log]
@@ -77,7 +77,9 @@
     ;; load instance analytics content (collections/dashboards/cards/etc.) when the resource exists:
     (when analytics-root-dir-resource
       (log/info (str "Loading Analytics Content from: " analytics-root-dir-resource))
-      (let [report (log/with-no-logs (serialization.cmd/v2-load analytics-root-dir-resource {}))]
+      ;; The EE token might not have :serialization enabled, but audit features should still be able to use it.
+      (let [report (premium-features/with-premium-feature-overrides [:serialization]
+                     (log/with-no-logs (serialization.cmd/v2-load analytics-root-dir-resource {})))]
         (if (not-empty (:errors report))
           (log/info (str "Error Loading Analytics Content: " (pr-str report)))
           (log/info (str "Loading Analytics Content Complete (" (count (:seen report)) ") entities synchronized.")))))))
diff --git a/src/metabase/public_settings/premium_features.clj b/src/metabase/public_settings/premium_features.clj
index f109b4c94b5d8d59dddd7d3042489ed07af3211c..022254c15cbbcb0d12d577d63fe8c4b4fd1816c0 100644
--- a/src/metabase/public_settings/premium_features.clj
+++ b/src/metabase/public_settings/premium_features.clj
@@ -236,13 +236,32 @@
   []
   (boolean (seq (token-features))))
 
+(def ^:dynamic *premium-feature-overrides*
+  "Dynamic var holding a set of tokens which are temporarily considered to be enabled, even if the user's token does
+  not have that feature.
+
+  This allows eg. `:audit-app` functionality to use `:serialization` internally, even if the token only has
+  `:audit-app`.
+
+  Don't touch this directly - prefer to use [[with-premium-feature-overrides]]."
+  #{})
+
+(defmacro with-premium-feature-overrides
+  "Helper to dynamically override [[*premium-feature-overrides*]] and properly merge any existing value.
+
+  Used like `(with-premium-feature-overrides [:serialization] (something-using-serdes ...))`."
+  [features & body]
+  `(binding [*premium-feature-overrides* (into *premium-feature-overrides* ~features)]
+     ~@body))
+
 (defn has-feature?
   "Does this instance's premium token have `feature`?
 
     (has-feature? :sandboxes)          ; -> true
     (has-feature? :toucan-management)  ; -> false"
   [feature]
-  (contains? (token-features) (name feature)))
+  (or (contains? (token-features) (name feature))
+      (*premium-feature-overrides* feature)))
 
 (defn- default-premium-feature-getter [feature]
   (fn []
diff --git a/test/metabase/public_settings/premium_features_test.clj b/test/metabase/public_settings/premium_features_test.clj
index 2852e32559725b58129b9bd48532378bf33a9412..d0565406ac46ee60f575fb524bebdecbd7354a40 100644
--- a/test/metabase/public_settings/premium_features_test.clj
+++ b/test/metabase/public_settings/premium_features_test.clj
@@ -125,6 +125,26 @@
           (is (:valid result))
           (is (contains? (set (:features result)) "test")))))))
 
+(deftest feature-overrides-test
+  (let [token (random-token)]
+    (mt/with-temporary-raw-setting-values [:premium-embedding-token token]
+      (is (and (not (premium-features/has-feature? :serialization))
+               (not (premium-features/has-feature? :audit-app)))
+          "serialization and auditing are not enabled")
+      (testing "with-premium-feature-overrides works"
+        (premium-features/with-premium-feature-overrides [:serialization]
+          (is (premium-features/has-feature? :serialization))
+          (is (not (premium-features/has-feature? :audit-app)))
+
+          (testing "when nested"
+            (premium-features/with-premium-feature-overrides [:audit-app]
+              (is (premium-features/has-feature? :serialization))
+              (is (premium-features/has-feature? :audit-app))))))
+
+      (testing "and doesn't persist outside its scope"
+        (is (not (premium-features/has-feature? :serialization)))
+        (is (not (premium-features/has-feature? :audit-app)))))))
+
 (deftest not-found-test
   (mt/with-log-level :fatal
     ;; `partial=` here in case the Cloud API starts including extra keys... this is a "dangerous" test since changes