diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index d6581d2ecf119aab5837b24edc5c777df98087ab..bacf97396f646e980551f51321dbc57dff6a0563 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -18,6 +18,7 @@ Fixed
 * [Dev] AddressInputType missed country field.
 * Detail pages, e.g. for groups, did not work anymore.
 * The configured theme colors were not used by the frontend.
+* It wasn't possible to change icons of OAuth applications in the frontend.
 
 `4.0`_ - 2025-03-29
 -------------------
diff --git a/aleksis/core/frontend/components/oauth/OAuthApplications.vue b/aleksis/core/frontend/components/oauth/OAuthApplications.vue
index 7ff6fadb17fe09412b3c37adf906cdacacb1550b..fc89dd155a20dfe78598e659d9ca123579677150 100644
--- a/aleksis/core/frontend/components/oauth/OAuthApplications.vue
+++ b/aleksis/core/frontend/components/oauth/OAuthApplications.vue
@@ -1,5 +1,6 @@
 <script setup>
 import CRUDList from "../generic/CRUDList.vue";
+import FileField from "../generic/forms/FileField.vue";
 </script>
 
 <template>
@@ -128,6 +129,32 @@ import CRUDList from "../generic/CRUDList.vue";
         :true-value="true"
       />
     </template>
+
+    <template #icon="{ item }">
+      <v-img
+        v-if="item.icon.url"
+        :src="item.icon.url"
+        :alt="$t('oauth.application.icon')"
+        max-width="6em"
+      />
+      <span v-else>–</span>
+    </template>
+
+    <!-- eslint-disable-next-line vue/valid-v-slot -->
+    <template #icon.field="{ attrs, on }">
+      <div aria-required="false">
+        <file-field v-bind="attrs" v-on="on" accept="image/jpeg, image/png">
+          <template #append-outer="{ fileUrl }">
+            <v-img
+              v-if="fileUrl"
+              :src="fileUrl"
+              :alt="$t('oauth.application.icon')"
+              max-width="4em"
+            />
+          </template>
+        </file-field>
+      </div>
+    </template>
   </c-r-u-d-list>
 </template>
 
@@ -154,11 +181,11 @@ export default {
           value: "name",
           cols: 12,
         },
-        // {
-        //   text: this.$t("oauth.application.icon"),
-        //   value: "icon",
-        //   cols: 12,
-        // },
+        {
+          text: this.$t("oauth.application.icon"),
+          value: "icon",
+          cols: 12,
+        },
         {
           text: this.$t("oauth.application.client_id"),
           value: "clientId",
@@ -233,7 +260,7 @@ export default {
     defaultItem() {
       return {
         name: "",
-        // icon: "",
+        icon: null,
         clientId: this.initOauthApplication?.clientId,
         clientSecret: this.initOauthApplication?.clientSecret,
         clientType: "",
diff --git a/aleksis/core/frontend/components/oauth/oauthApplications.graphql b/aleksis/core/frontend/components/oauth/oauthApplications.graphql
index 6523f3ad2b28e18ece9ee90923e479f406a079a2..82df9707327383201d790ebc5367111bdedc33f9 100644
--- a/aleksis/core/frontend/components/oauth/oauthApplications.graphql
+++ b/aleksis/core/frontend/components/oauth/oauthApplications.graphql
@@ -1,7 +1,10 @@
 fragment oauthApplicationFields on OAuthApplicationType {
   id
   name
-  # icon
+  icon {
+    url
+    name
+  }
   clientId
   clientSecret
   clientType