diff --git a/src/metabase/api/app.clj b/src/metabase/api/app.clj
index b9d350f4dc43c736d40f9256e726a393ab4c28ed..aaf443248344a968338064117d0337ba5e6f631a 100644
--- a/src/metabase/api/app.clj
+++ b/src/metabase/api/app.clj
@@ -16,7 +16,7 @@
 (api/defendpoint POST "/"
   "Endpoint to create an app"
   [:as {{:keys [collection dashboard_id options nav_items]
-         {:keys [name color description parent_id namespace authority_level]} :collection
+         {:keys [name color description namespace authority_level]} :collection
          :as body} :body}]
   {dashboard_id    (s/maybe su/IntGreaterThanOrEqualToZero)
    options         (s/maybe su/Map)
@@ -24,11 +24,10 @@
    name            su/NonBlankString
    color           collection/hex-color-regex
    description     (s/maybe su/NonBlankString)
-   parent_id       (s/maybe su/IntGreaterThanZero)
    namespace       (s/maybe su/NonBlankString)
    authority_level collection/AuthorityLevel}
   (db/transaction
-   (let [coll-params (select-keys collection [:name :color :description :parent_id :namespace :authority_level])
+   (let [coll-params (select-keys collection [:name :color :description :namespace :authority_level])
          collection-instance (api.collection/create-collection! coll-params)
          app-params (-> body
                         (select-keys [:dashboard_id :options :nav_items])
diff --git a/src/metabase/api/collection.clj b/src/metabase/api/collection.clj
index 01a19fddb7a0c8474086092828b0b8e70864cf37..d937f8461c16d953c17d8d6b096dfb85f6992cf9 100644
--- a/src/metabase/api/collection.clj
+++ b/src/metabase/api/collection.clj
@@ -774,6 +774,10 @@
         (api/check-403
          (perms/set-has-full-permissions-for-set? @api/*current-user-permissions-set*
            (collection/perms-for-moving collection-before-update new-parent)))
+        (when (not= new-parent collection/root-collection)
+          ;; apps are not allowed to be moved away from the root collection
+          (api/check-403
+           (nil? (:app_id (hydrate collection-before-update :app_id)))))
         ;; ok, we're good to move!
         (collection/move-collection! collection-before-update new-location)))))
 
diff --git a/test/metabase/api/app_test.clj b/test/metabase/api/app_test.clj
index e6976fb80a4386e86d825ed8583c81745c0a9f81..e8efa526a9cefca8ae03d8301d03651a098130a4 100644
--- a/test/metabase/api/app_test.clj
+++ b/test/metabase/api/app_test.clj
@@ -11,44 +11,29 @@
     (let [base-params {:name "App collection"
                        :color "#123456"}]
       (mt/test-drivers (mt/normal-drivers-with-feature :actions/custom)
-        (testing "Create app in non-root collection"
+        (testing "parent_id is ignored when creating apps"
           (mt/with-temp* [Collection [{collection-id :id}]]
             (let [coll-params (assoc base-params :parent_id collection-id)
                   response (mt/user-http-request :crowberto :post 200 "app" {:collection coll-params})]
               (is (pos-int? (:id response)))
               (is (pos-int? (:collection_id response)))
-              (is (partial= (assoc base-params :location (format "/%d/" collection-id))
+              (is (partial= (assoc base-params :location "/")
                             (:collection response))))))
-        (testing "Create aoo in the root"
+        (testing "Create app in the root"
           (let [response (mt/user-http-request :crowberto :post 200 "app" {:collection base-params})]
             (is (pos-int? (:id response)))
             (is (pos-int? (:collection_id response)))
             (is (partial= (assoc base-params :location "/")
                           (:collection response)))))
-        (testing "Collection permissions"
-          (mt/with-non-admin-groups-no-root-collection-perms
-            (mt/with-temp* [Collection [{collection-id :id}]]
-              (let [coll-params (assoc base-params :parent_id collection-id)]
-                (is (= "You don't have permissions to do that."
-                       (mt/user-http-request :rasta :post 403 "app" {:collection coll-params}))))))
-          (mt/with-temp* [Collection [{collection-id :id}]]
-            (let [coll-params (assoc base-params :parent_id collection-id)
-                  response (mt/user-http-request :rasta :post 200 "app" {:collection coll-params})]
-              (is (pos-int? (:id response)))
-              (is (pos-int? (:collection_id response)))
-              (is (partial= (assoc base-params :location (format "/%d/" collection-id))
-                            (:collection response))))))
         (testing "With initial dashboard and nav_items"
-          (mt/with-temp* [Collection [{collection-id :id}]
-                          Dashboard [{dashboard-id :id}]]
-            (let [coll-params (assoc base-params :parent_id collection-id)
-                  nav_items [{:options {:click_behavior {}}}]]
-              (is (partial= {:collection (assoc base-params :location (format "/%d/" collection-id))
+          (mt/with-temp Dashboard [{dashboard-id :id}]
+            (let [nav_items [{:options {:click_behavior {}}}]]
+              (is (partial= {:collection (assoc base-params :location "/")
                              :dashboard_id dashboard-id
                              :nav_items nav_items}
-                            (mt/user-http-request :crowberto :post 200 "app" {:collection coll-params
-                                                                              :dashboard_id dashboard-id
-                                                                              :nav_items nav_items}))))))))))
+                            (mt/user-http-request :rasta :post 200 "app" {:collection base-params
+                                                                          :dashboard_id dashboard-id
+                                                                          :nav_items nav_items}))))))))))
 
 (deftest update-test
   (mt/test-drivers (mt/normal-drivers-with-feature :actions/custom)
@@ -57,8 +42,7 @@
       (mt/with-temp* [Collection [{collection_id :id}]
                       App [{app_id :id} (assoc app-data :collection_id collection_id)]
                       Dashboard [{dashboard_id :id}]]
-        (let [expected (merge app-data {:collection_id collection_id
-                                        :dashboard_id dashboard_id})]
+        (let [expected (assoc app-data :collection_id collection_id :dashboard_id dashboard_id)]
           (testing "setting the dashboard_id doesn't affect the other fields"
             (is (partial= expected
                           (mt/user-http-request :crowberto :put 200 (str "app/" app_id) {:dashboard_id dashboard_id}))))
diff --git a/test/metabase/api/collection_test.clj b/test/metabase/api/collection_test.clj
index 9eb357391bde5a00af96d440bd973be6aaece4b3..10fdd0262a8b2309a5d87d69007e2209bbb4f831 100644
--- a/test/metabase/api/collection_test.clj
+++ b/test/metabase/api/collection_test.clj
@@ -1470,6 +1470,14 @@
                    (update :id integer?)
                    (update :entity_id string?))))))
 
+    (testing "I shouldn't be allowed to move an App away from root."
+      (mt/with-temp* [Collection [collection-a]
+                      App [_app {:collection_id (:id collection-a)}]
+                      Collection [collection-b]]
+        (is (= "You don't have permissions to do that."
+               (mt/user-http-request :rasta :put 403 (str "collection/" (u/the-id collection-a))
+                                     {:parent_id (u/the-id collection-b)})))))
+
     (testing "I shouldn't be allowed to move the Collection without proper perms."
       (testing "If I want to move A into B, I should need permissions for both A and B"
         (mt/with-non-admin-groups-no-root-collection-perms