diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 8ec2833ac595d3a3e01e7fb8c11736ae8b3bb7dc..bb31f7258498b654f0be082d46a9aef200b9d2a5 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -13,13 +13,16 @@ Added
 ~~~~~
 
 * Provide an ``ExtensiblePolymorphicModel`` to support the features of extensible models for polymorphic models and vice-versa.
+* Implement optional Sentry integration for error and performance tracing.
 * Option to limit allowed scopes per application, including mixin to enforce that limit on OAuth resource views
+* Support trusted OAuth applications that leave out the authorisation screen.
 
 Changed
 ~~~~~~~
 
 * Replace dev.sh helper script with tox environments.
 * OAuth Grant Flows are now configured system-wide instead of per app.
+* Refactor OAuth2 application management views.
 
 `2.0`_ - 2021-10-29
 -------------------
diff --git a/aleksis/core/forms.py b/aleksis/core/forms.py
index a733925cb093312742624f7e3fd68e33a6ba8bc4..dd695cd06ea2c0dbc862be8c9989047d9934c0c3 100644
--- a/aleksis/core/forms.py
+++ b/aleksis/core/forms.py
@@ -610,4 +610,5 @@ class OAuthApplicationForm(forms.ModelForm):
             "client_type",
             "allowed_scopes",
             "redirect_uris",
+            "skip_authorization",
         )
diff --git a/aleksis/core/menus.py b/aleksis/core/menus.py
index d9fd84b0f78a1ce141537725d233f57b43a4fbea..99928d34f80b3138700005078c9dbd0ea9b25293 100644
--- a/aleksis/core/menus.py
+++ b/aleksis/core/menus.py
@@ -214,7 +214,7 @@ MENUS = {
                 },
                 {
                     "name": _("OAuth2 Applications"),
-                    "url": "oauth_list",
+                    "url": "oauth2_applications",
                     "icon": "touch_app",
                     "validators": [
                         (
diff --git a/aleksis/core/models.py b/aleksis/core/models.py
index 5c590e612a0459127d868991fd8847f9f2b4c0c0..a78bfcc141d5539479983a50bbd257e6b7b7e5b1 100644
--- a/aleksis/core/models.py
+++ b/aleksis/core/models.py
@@ -983,11 +983,6 @@ class GlobalPermissions(GlobalPermissionModel):
             ("change_site_preferences", _("Can change site preferences")),
             ("change_person_preferences", _("Can change person preferences")),
             ("change_group_preferences", _("Can change group preferences")),
-            ("add_oauth_applications", _("Can add oauth applications")),
-            ("list_oauth_applications", _("Can list oauth applications")),
-            ("view_oauth_applications", _("Can view oauth applications")),
-            ("update_oauth_applications", _("Can update oauth applications")),
-            ("delete_oauth_applications", _("Can delete oauth applications")),
             ("test_pdf", _("Can test PDF generation")),
         )
 
diff --git a/aleksis/core/rules.py b/aleksis/core/rules.py
index e8e5443e15396554befa1f14c2536c66231c76cf..51a4fb07bf69085b454079aad10aebb0ece9f420 100644
--- a/aleksis/core/rules.py
+++ b/aleksis/core/rules.py
@@ -319,17 +319,17 @@ can_change_password_predicate = is_site_preference_set(section="auth", pref="all
 rules.add_perm("core.can_change_password", can_change_password_predicate)
 
 # OAuth2 permissions
-add_oauth_applications_predicate = has_person & has_global_perm("core.add_oauth_applications")
-rules.add_perm("core.add_oauth_applications_rule", add_oauth_applications_predicate)
+create_oauthapplication_predicate = has_person & has_global_perm("core.add_oauthapplication")
+rules.add_perm("core.create_oauthapplication_rule", create_oauthapplication_predicate)
 
-list_oauth_applications_predicate = has_person & has_global_perm("core.list_oauth_applications")
-rules.add_perm("core.list_oauth_applications_rule", list_oauth_applications_predicate)
+view_oauth_applications_predicate = has_person & has_global_perm("core.view_oauthapplication")
+rules.add_perm("core.view_oauthapplications_rule", view_oauth_applications_predicate)
 
-view_oauth_applications_predicate = has_person & has_global_perm("core.view_oauth_applications")
-rules.add_perm("core.view_oauth_applications_rule", view_oauth_applications_predicate)
+view_oauth_application_predicate = has_person & has_global_perm("core.view_oauthapplication")
+rules.add_perm("core.view_oauthapplication_rule", view_oauth_application_predicate)
 
-update_oauth_applications_predicate = has_person & has_global_perm("core.update_oauth_applications")
-rules.add_perm("core.update_oauth_applications_rule", update_oauth_applications_predicate)
+edit_oauth_application_predicate = has_person & has_global_perm("core.change_oauthapplication")
+rules.add_perm("core.edit_oauthapplication_rule", edit_oauth_application_predicate)
 
 delete_oauth_applications_predicate = has_person & has_global_perm("core.delete_oauth_applications")
 rules.add_perm("core.delete_oauth_applications_rule", delete_oauth_applications_predicate)
diff --git a/aleksis/core/settings.py b/aleksis/core/settings.py
index 7a733c13983ba1ca7602f9661ef458b64414db8e..9a0a8b5f2e7de5ff23ddd738db1b8974d32430d1 100644
--- a/aleksis/core/settings.py
+++ b/aleksis/core/settings.py
@@ -486,6 +486,7 @@ YARN_INSTALLED_APPS = [
     "paper-css",
     "jquery-sortablejs",
     "sortablejs",
+    "@sentry/tracing",
 ]
 
 merge_app_settings("YARN_INSTALLED_APPS", YARN_INSTALLED_APPS, True)
@@ -516,6 +517,7 @@ ANY_JS = {
     "Roboto500": {"css_url": JS_URL + "/@fontsource/roboto/500.css"},
     "Roboto700": {"css_url": JS_URL + "/@fontsource/roboto/700.css"},
     "Roboto900": {"css_url": JS_URL + "/@fontsource/roboto/900.css"},
+    "Sentry": {"js_url": JS_URL + "/@sentry/tracing/build/bundle.tracing.js"},
 }
 
 merge_app_settings("ANY_JS", ANY_JS, True)
@@ -859,5 +861,31 @@ else:
 
 SASS_PROCESSOR_STORAGE = DEFAULT_FILE_STORAGE
 
+SENTRY_ENABLED = _settings.get("health.sentry.enabled", False)
+if SENTRY_ENABLED:
+    import sentry_sdk
+    from sentry_sdk.integrations.celery import CeleryIntegration
+    from sentry_sdk.integrations.django import DjangoIntegration
+    from sentry_sdk.integrations.redis import RedisIntegration
+
+    from aleksis.core import __version__
+
+    SENTRY_SETTINGS = {
+        "dsn": _settings.get("health.sentry.dsn"),
+        "environment": _settings.get("health.sentry.environment"),
+        "traces_sample_rate": _settings.get("health.sentry.traces_sample_rate", 1.0),
+        "send_default_pii": _settings.get("health.sentry.send_default_pii", False),
+        "release": f"aleksis-core@{__version__}",
+        "in_app_include": "aleksis",
+    }
+    sentry_sdk.init(
+        integrations=[
+            DjangoIntegration(transaction_style="function_name"),
+            RedisIntegration(),
+            CeleryIntegration(),
+        ],
+        **SENTRY_SETTINGS,
+    )
+
 # Add django-cleanup after all apps to ensure that it gets all signals as last app
 INSTALLED_APPS.append("django_cleanup.apps.CleanupConfig")
diff --git a/aleksis/core/templates/core/base.html b/aleksis/core/templates/core/base.html
index 80e6ee8d7cae0837b1c6b91ce4b258bd2608f22b..0dd75f2c6f237dea1ecac47b010abfac9453000f 100644
--- a/aleksis/core/templates/core/base.html
+++ b/aleksis/core/templates/core/base.html
@@ -35,6 +35,24 @@
   <script src="{% url "calendarweek_i18n_js" %}?first_day=6&amp;locale={{ LANGUAGE_CODE }}"
           type="text/javascript"></script>
 
+  {% if SENTRY_ENABLED %}
+    {% if SENTRY_TRACE_ID %}
+      <meta name="sentry-trace" content="{{ SENTRY_TRACE_ID }}" />
+    {% endif %}
+    {% include_js "Sentry" %}
+    {{ SENTRY_SETTINGS|json_script:"sentry_settings" }}
+    <script type="text/javascript">
+      const sentry_settings = JSON.parse(document.getElementById('sentry_settings').textContent);
+
+      Sentry.init({
+        dsn: sentry_settings.dsn,
+        environment: sentry_settings.environment,
+        tracesSampleRate: sentry_settings.traces_sample_rate,
+        integrations: [new Sentry.Integrations.BrowserTracing()]
+      });
+    </script>
+  {% endif %}
+
   {# Include jQuery early to provide $(document).ready #}
   {% include_js "jQuery" %}
 
diff --git a/aleksis/core/templates/oauth2_provider/application/create.html b/aleksis/core/templates/oauth2_provider/application/create.html
index 38b9a8d02e52b977223cfffdcb8d3c9165c42a71..d81489e922a76de8d7a8e92a7f48686714a3b3a7 100644
--- a/aleksis/core/templates/oauth2_provider/application/create.html
+++ b/aleksis/core/templates/oauth2_provider/application/create.html
@@ -10,7 +10,7 @@
     {% csrf_token %}
     {% form form=form %}{% endform %}
     {% include "core/partials/save_button.html" %}
-    <a class="btn waves-effect red waves-light" href="{% url "oauth_list" %}">
+    <a class="btn waves-effect red waves-light" href="{% url "oauth2_applications" %}">
       <i class="material-icons left">clear</i> {% trans "Cancel" %}
     </a>
   </form>
diff --git a/aleksis/core/templates/oauth2_provider/application/detail.html b/aleksis/core/templates/oauth2_provider/application/detail.html
new file mode 100644
index 0000000000000000000000000000000000000000..8e55f91122debafbb0a86984a8166768cf879457
--- /dev/null
+++ b/aleksis/core/templates/oauth2_provider/application/detail.html
@@ -0,0 +1,67 @@
+{% extends "core/base.html" %}
+
+{% load i18n %}
+
+{% block browser_title %}{% blocktrans %}OAuth2 Application{% endblocktrans %}{% endblock %}
+{% block page_title %}
+  <a href="{% url "oauth2_applications" %}"
+     class="btn-flat primary-color-text waves-light waves-effect">
+    <i class="material-icons left">chevron_left</i> {% trans "Back" %}
+  </a>
+  {{ application.name }}
+{% endblock %}
+
+{% block content %}
+  <a class="btn orange waves-effect waves-light btn-margin" href="{% url "edit_oauth2_application" application.id %}">
+    <i class="material-icons left">edit</i>
+    {% trans "Edit" %}
+  </a>
+  <a class="btn red waves-effect waves-light btn-margin" href="{% url "delete_oauth2_application" application.id %}">
+    <i class="material-icons left">delete</i>
+    {% trans "Delete" %}
+  </a>
+  <table class="responsive-table">
+    <tbody>
+    <tr>
+      <th>
+        {% trans "Client id" %}
+      </th>
+      <td>
+        <code class="break-word">{{ application.client_id }}</code>
+      </td>
+    </tr>
+    <tr>
+      <th>
+        {% trans "Client secret" %}
+      </th>
+      <td>
+        <code class="break-word">{{ application.client_secret }}</code>
+      </td>
+    </tr>
+    <tr>
+      <th>
+        {% trans "Client type" %}
+      </th>
+      <td>
+        {{ application.client_type }}
+      </td>
+    </tr>
+    <tr>
+      <th>
+        {% trans "Allowed scopes" %}
+      </th>
+      <td>
+        {{ application.allowed_scopes|join:", " }}
+      </td>
+    </tr>
+    <tr>
+      <th>
+        {% trans "Redirect URIs" %}
+      </th>
+      <td>
+        {{ application.redirect_uris }}
+      </td>
+    </tr>
+    </tbody>
+  </table>
+{% endblock %}
diff --git a/aleksis/core/templates/oauth2_provider/application/edit.html b/aleksis/core/templates/oauth2_provider/application/edit.html
index ac2b7d3468c114d7d3739c8fec9729b6d4c7ab54..6755d2420fb6a181f671b825475afb4ec9581521 100644
--- a/aleksis/core/templates/oauth2_provider/application/edit.html
+++ b/aleksis/core/templates/oauth2_provider/application/edit.html
@@ -10,7 +10,7 @@
     {% csrf_token %}
     {% form form=form %}{% endform %}
     {% include "core/partials/save_button.html" %}
-    <a class="btn waves-effect red waves-light" href="{% url "oauth_detail" application.id %}">
+    <a class="btn waves-effect red waves-light" href="{% url "oauth2_application" application.id %}">
       <i class="material-icons left">clear</i> {% trans "Cancel" %}
     </a>
   </form>
diff --git a/aleksis/core/templates/oauth2_provider/application_list.html b/aleksis/core/templates/oauth2_provider/application/list.html
similarity index 53%
rename from aleksis/core/templates/oauth2_provider/application_list.html
rename to aleksis/core/templates/oauth2_provider/application/list.html
index 894315940ffe8a8faaa1d93e26e06c76e1226fc8..06f1a95c4e05c14dcb5efe69f2416040d184f0bb 100644
--- a/aleksis/core/templates/oauth2_provider/application_list.html
+++ b/aleksis/core/templates/oauth2_provider/application/list.html
@@ -3,24 +3,22 @@
 {% load i18n %}
 
 {% block browser_title %}{% blocktrans %}OAuth2 Applications{% endblocktrans %}{% endblock %}
+{% block page_title %}{% blocktrans %}OAuth2 Applications{% endblocktrans %}{% endblock %}
 
 {% block content %}
-  <h1>{% blocktrans %}OAuth2 applications{% endblocktrans %}</h1>
   <a href="{% url "register_oauth_application" %}" class="btn green waves-effect waves-light">
     <i class="material-icons left">add</i>
     {% blocktrans %}Register new application{% endblocktrans %}
   </a>
-  <ul class="collection">
-  {% for application in applications %}
-      <li class="collection-item">
-        <div>
-          <a href="{% url "oauth_detail" application.id %}">{{ application.name }}</a>
-        </div>
-      </li>
-  {% empty %}
-      <li class="collection-item flow-text">
+  <div class="collection">
+    {% for application in applications %}
+      <a class="collection-item" href="{% url "oauth2_application" application.id %}">
+        {{ application.name }}
+      </a>
+      {% empty %}
+      <div class="collection-item flow-text">
         {% blocktrans %}No applications defined.{% endblocktrans %}
-      </li>
-  {% endfor %}
-  </ul>
+      </div>
+    {% endfor %}
+  </div>
 {% endblock %}
diff --git a/aleksis/core/templates/oauth2_provider/application_confirm_delete.html b/aleksis/core/templates/oauth2_provider/application_confirm_delete.html
deleted file mode 100644
index f72a5be615700ee32326eda2982964e3e8de3e52..0000000000000000000000000000000000000000
--- a/aleksis/core/templates/oauth2_provider/application_confirm_delete.html
+++ /dev/null
@@ -1,27 +0,0 @@
-{% extends "core/base.html" %}
-
-{% load i18n %}
-
-{% block browser_title %}{% trans "Delete application" %}{% endblock %}
-{% block page_title %}{% trans "Delete application" %}{% endblock %}
-
-{% block content %}
-  <div class="alert info">
-    <p>
-      <i class="material-icons left">warning</i>
-      {% blocktrans with application_name=application.name %}Are you sure to delete the application {{ application_name }}?{% endblocktrans %}
-    </p>
-  </div>
-
-  <form method="post" action="{% url 'oauth2_provider:delete' application.pk %}">
-    {% csrf_token %}
-    <button type="submit" class="btn waves-effect waves-light red">
-      <i class="material-icons left">delete</i>
-      {% trans "Delete" %}
-    </button>
-    <a class="btn waves-effect waves-light" href="{% url "oauth2_provider:list" %}">
-      <i class="material-icons left">close</i>
-      {% trans "Cancel" %}
-    </a>
-  </form>
-{% endblock %}
diff --git a/aleksis/core/templates/oauth2_provider/application_detail.html b/aleksis/core/templates/oauth2_provider/application_detail.html
deleted file mode 100644
index f7e02ff62ca65cb41692a8155c28906a9900fc2b..0000000000000000000000000000000000000000
--- a/aleksis/core/templates/oauth2_provider/application_detail.html
+++ /dev/null
@@ -1,71 +0,0 @@
-{% extends "core/base.html" %}
-
-{% load i18n %}
-
-{% block browser_title %}{% blocktrans %}OAuth2 Applications{% endblocktrans %}{% endblock %}
-{% block page_title %}
-    <a href="{% url "oauth_list" %}"
-       class="btn-flat primary-color-text waves-light waves-effect">
-      <i class="material-icons left">chevron_left</i> {% trans "Back" %}
-    </a>
-    {{ application.name }}
-{% endblock %}
-
-{% block content %}
-  <a class="btn waves-effect waves-light btn-margin" href="{% url "edit_oauth_application" application.id %}">
-    <i class="material-icons left">edit</i>
-    {% trans "Edit" %}
-  </a>
-  <a class="btn red waves-effect waves-light btn-margin" href="{% url "oauth_delete" application.id %}">
-    <i class="material-icons left">delete_forever</i>
-    {% trans "Delete" %}
-  </a>
-  <table class="responsive-table">
-    <tbody>
-      <tr>
-        <th>
-          {% trans "Client id" %}
-        </td>
-        <td>
-          <code class="break-word">{{ application.client_id }}</code>
-        </td>
-      </tr>
-      <tr>
-        <th>
-          {% trans "Client secret"%}
-        </td>
-        <td>
-          <code class="break-word">{{ application.client_secret }}</code>
-        </td>
-      </tr>
-      <tr>
-        <th>
-          {% trans "Client type"%}
-        </td>
-        <td>
-          {{ application.client_type }}
-        </td>
-      </tr>
-      <tr>
-        <th>
-          {% trans "Allowed scopes"%}
-        </th>
-        <td>
-          <ul>
-            {% for scope in application.allowed_scopes %}
-              <li>{{ scope }}</li>
-            {% endfor %}
-          </ul>
-        </td>
-      </tr>
-      <tr>
-        <th>
-          {% trans "Redirect URIs"%}
-        </td>
-        <td>
-          {{ application.redirect_uris }}
-        </td>
-      </tr>
-    </tbody>
-  </table>
-{% endblock %}
diff --git a/aleksis/core/templates/oauth2_provider/authorize.html b/aleksis/core/templates/oauth2_provider/authorize.html
index 5eaf3151021c27fd24b8e19e195a4a2e14d5279a..48b996837b8721ef6ba74337d286236e91729f5b 100644
--- a/aleksis/core/templates/oauth2_provider/authorize.html
+++ b/aleksis/core/templates/oauth2_provider/authorize.html
@@ -32,7 +32,7 @@
             <button type="submit" class="btn green waves-effect waves-light btn-margin">
               <i class="material-icons left">done_all</i> {% trans "Allow" %}
             </button>
-            <a class="btn red waves-effect waves-light btn-margin" href="{% block app-form-back-url %}{% url "oauth_detail" application.id %}{% endblock app-form-back-url %}">
+            <a class="btn red waves-effect waves-light btn-margin" href="{% block app-form-back-url %}{% url "oauth2_application" application.id %}{% endblock app-form-back-url %}">
               <i class="material-icons left">cancel</i> {% trans "Disallow" %}
             </a>
           </form>
diff --git a/aleksis/core/templates/oauth2_provider/authorized-token-delete.html b/aleksis/core/templates/oauth2_provider/authorized-token-delete.html
index f658822980bda161890060fb9002cec8fb317297..7f6f25920bebcbbaad7bb93fd486db617f25d662 100644
--- a/aleksis/core/templates/oauth2_provider/authorized-token-delete.html
+++ b/aleksis/core/templates/oauth2_provider/authorized-token-delete.html
@@ -15,11 +15,11 @@
 
   <form method="post">
     {% csrf_token %}
-    <a class="btn waves-effect waves-light red" href="{% url "oauth_list" %}">
+    <a class="btn waves-effect waves-light red" href="{% url "oauth2_applications" %}">
       <i class="material-icons left">delete</i>
       {% trans "Revoke" %}
     </a>
-    <a class="btn waves-effect waves-light" href="{% url "oauth_list" %}">
+    <a class="btn waves-effect waves-light" href="{% url "oauth2_applications" %}">
       <i class="material-icons left">cancel</i>
       {% trans "Cancel" %}
     </a>
diff --git a/aleksis/core/urls.py b/aleksis/core/urls.py
index 85f91a2ccd5aa2f0f11f5d905a1d8ed5d5a61a1e..22bbdd344fef8a9082edd2cf4df589627597d3f0 100644
--- a/aleksis/core/urls.py
+++ b/aleksis/core/urls.py
@@ -102,20 +102,26 @@ urlpatterns = [
         ConnectDiscoveryInfoView.as_view(),
         name="oidc_configuration",
     ),
-    path("oauth/applications/", views.OAuth2List.as_view(), name="oauth_list"),
+    path("oauth2/applications/", views.OAuth2ListView.as_view(), name="oauth2_applications"),
     path(
-        "oauth/applications/register/",
+        "oauth2/applications/register/",
         views.OAuth2RegisterView.as_view(),
         name="register_oauth_application",
     ),
-    path("oauth/applications/<int:pk>/detail", views.OAuth2Detail.as_view(), name="oauth_detail"),
-    path("oauth/applications/<int:pk>/delete", views.OAuth2Delete.as_view(), name="oauth_delete"),
     path(
-        "oauth/applications/<int:pk>/edit/",
+        "oauth2/applications/<int:pk>/", views.OAuth2DetailView.as_view(), name="oauth2_application"
+    ),
+    path(
+        "oauth2/applications/<int:pk>/delete/",
+        views.OAuth2DeleteView.as_view(),
+        name="delete_oauth2_application",
+    ),
+    path(
+        "oauth2/applications/<int:pk>/edit/",
         views.OAuth2EditView.as_view(),
-        name="edit_oauth_application",
+        name="edit_oauth2_application",
     ),
-    path("oauth/", include("oauth2_provider.urls", namespace="oauth2_provider")),
+    path("oauth2/", include("oauth2_provider.urls", namespace="oauth2_provider")),
     path("__i18n__/", include("django.conf.urls.i18n")),
     path(
         "ckeditor/upload/",
diff --git a/aleksis/core/util/core_helpers.py b/aleksis/core/util/core_helpers.py
index 2c40caf51d41045685a74b67800cc9575d3cf2de..5871fd8dd7f568d463c8f672373fa60b708caddf 100644
--- a/aleksis/core/util/core_helpers.py
+++ b/aleksis/core/util/core_helpers.py
@@ -208,12 +208,24 @@ def custom_information_processor(request: HttpRequest) -> dict:
         regrouped_pwa_icons.setdefault(pwa_icon.rel, {})
         regrouped_pwa_icons[pwa_icon.rel][pwa_icon.size] = pwa_icon
 
-    return {
+    context = {
         "FOOTER_MENU": CustomMenu.get_default("footer"),
         "ADMINS": settings.ADMINS,
         "PWA_ICONS": regrouped_pwa_icons,
+        "SENTRY_ENABLED": settings.SENTRY_ENABLED,
     }
 
+    if settings.SENTRY_ENABLED:
+        context["SENTRY_SETTINGS"] = settings.SENTRY_SETTINGS
+
+        import sentry_sdk
+
+        span = sentry_sdk.Hub.current.scope.span
+        if span is not None:
+            context["SENTRY_TRACE_ID"] = span.to_traceparent()
+
+    return context
+
 
 def now_tomorrow() -> datetime:
     """Return current time tomorrow."""
diff --git a/aleksis/core/views.py b/aleksis/core/views.py
index 1a73deee1773edc55b53f83663931b6006109993..e0135bda5d713c11619de0aeff9528e6234b6aca 100644
--- a/aleksis/core/views.py
+++ b/aleksis/core/views.py
@@ -1033,44 +1033,44 @@ class EditDashboardView(PermissionRequiredMixin, View):
         return render(request, "core/edit_dashboard.html", context=context)
 
 
-class OAuth2List(PermissionRequiredMixin, ListView):
+class OAuth2ListView(PermissionRequiredMixin, ListView):
     """List view for all the applications."""
 
-    permission_required = "core.list_oauth_applications_rule"
+    permission_required = "core.view_oauthapplications_rule"
     context_object_name = "applications"
-    template_name = "oauth2_provider/application_list.html"
+    template_name = "oauth2_provider/application/list.html"
 
     def get_queryset(self):
         return OAuthApplication.objects.all()
 
 
-class OAuth2Detail(PermissionRequiredMixin, DetailView):
+class OAuth2DetailView(PermissionRequiredMixin, DetailView):
     """Detail view for an application instance."""
 
     context_object_name = "application"
-    permission_required = "core.view_oauth_applications_rule"
-    template_name = "oauth2_provider/application_detail.html"
+    permission_required = "core.view_oauthapplication_rule"
+    template_name = "oauth2_provider/application/detail.html"
 
     def get_queryset(self):
         return OAuthApplication.objects.all()
 
 
-class OAuth2Delete(PermissionRequiredMixin, DeleteView):
+class OAuth2DeleteView(PermissionRequiredMixin, AdvancedDeleteView):
     """View used to delete an application."""
 
-    permission_required = "core.delete_oauth_applications_rule"
+    permission_required = "core.delete_oauthapplication_rule"
     context_object_name = "application"
-    success_url = reverse_lazy("oauth_list")
-    template_name = "oauth2_provider/application_confirm_delete.html"
+    success_url = reverse_lazy("oauth2_applications")
+    template_name = "core/pages/delete.html"
 
     def get_queryset(self):
         return OAuthApplication.objects.all()
 
 
 class OAuth2EditView(PermissionRequiredMixin, AdvancedEditView):
-    """View used to update an application."""
+    """View used to edit an application."""
 
-    permission_required = "core.update_oauth_applications_rule"
+    permission_required = "core.edit_oauthapplication_rule"
     context_object_name = "application"
     template_name = "oauth2_provider/application/edit.html"
     form_class = OAuthApplicationForm
@@ -1082,7 +1082,7 @@ class OAuth2EditView(PermissionRequiredMixin, AdvancedEditView):
 class OAuth2RegisterView(PermissionRequiredMixin, AdvancedCreateView):
     """View used to register an application."""
 
-    permission_required = "core.add_oauth_applications_rule"
+    permission_required = "core.create_oauthapplication_rule"
     context_object_name = "application"
     template_name = "oauth2_provider/application/create.html"
     form_class = OAuthApplicationForm
diff --git a/poetry.lock b/poetry.lock
index c9d4b0e2db4557925a052ed17ac3f3958a389ee9..5b8035e59280dcc14adefa0cb88178c007ced081 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -2269,6 +2269,40 @@ python-versions = "*"
 [package.dependencies]
 urllib3 = "*"
 
+[[package]]
+name = "sentry-sdk"
+version = "1.4.3"
+description = "Python client for Sentry (https://sentry.io)"
+category = "main"
+optional = true
+python-versions = "*"
+
+[package.dependencies]
+certifi = "*"
+urllib3 = ">=1.10.0"
+
+[package.extras]
+aiohttp = ["aiohttp (>=3.5)"]
+beam = ["apache-beam (>=2.12)"]
+bottle = ["bottle (>=0.12.13)"]
+celery = ["celery (>=3)"]
+chalice = ["chalice (>=1.16.0)"]
+django = ["django (>=1.8)"]
+falcon = ["falcon (>=1.4)"]
+flask = ["flask (>=0.11)", "blinker (>=1.1)"]
+httpx = ["httpx (>=0.16.0)"]
+pure_eval = ["pure-eval", "executing", "asttokens"]
+pyspark = ["pyspark (>=2.4.4)"]
+rq = ["rq (>=0.6)"]
+sanic = ["sanic (>=0.8)"]
+sqlalchemy = ["sqlalchemy (>=1.2)"]
+tornado = ["tornado (>=5)"]
+
+[package.source]
+type = "legacy"
+url = "https://edugit.org/api/v4/projects/461/packages/pypi/simple"
+reference = "gitlab"
+
 [[package]]
 name = "six"
 version = "1.16.0"
@@ -2647,11 +2681,12 @@ pycryptodome = "*"
 [extras]
 ldap = ["django-auth-ldap"]
 s3 = ["boto3", "django-storages"]
+sentry = []
 
 [metadata]
 lock-version = "1.1"
 python-versions = "^3.9"
-content-hash = "9117742426e175d6402dac268ed74f7e72e084fe020e5ebf22e97915ff7acd0d"
+content-hash = "d15f5a57e0a3e887cfe411829b19459af4ebfc9aadc6e2a0468b11f4fc03e6b4"
 
 [metadata.files]
 alabaster = [
@@ -3770,6 +3805,10 @@ selenium = [
     {file = "selenium-3.141.0-py2.py3-none-any.whl", hash = "sha256:2d7131d7bc5a5b99a2d9b04aaf2612c411b03b8ca1b1ee8d3de5845a9be2cb3c"},
     {file = "selenium-3.141.0.tar.gz", hash = "sha256:deaf32b60ad91a4611b98d8002757f29e6f2c2d5fcaf202e1c9ad06d6772300d"},
 ]
+sentry-sdk = [
+    {file = "sentry-sdk-1.4.3.tar.gz", hash = "sha256:b9844751e40710e84a457c5bc29b21c383ccb2b63d76eeaad72f7f1c808c8828"},
+    {file = "sentry_sdk-1.4.3-py2.py3-none-any.whl", hash = "sha256:c091cc7115ff25fe3a0e410dbecd7a996f81a3f6137d2272daef32d6c3cfa6dc"},
+]
 six = [
     {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},
     {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"},
diff --git a/pyproject.toml b/pyproject.toml
index 7de56924b6d76c659ab4da8762e25e6815b9f435..044f77bfbf8d6f1c1e45923525274aa81d2a0f0b 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -113,10 +113,12 @@ Whoosh = "^2.7.4"
 django-titofisto = "^0.1.0"
 haystack-redis = "^0.0.1"
 python-gnupg = "^0.4.7"
+sentry-sdk = {version = "^1.4.3", optional = true}
 
 [tool.poetry.extras]
 ldap = ["django-auth-ldap"]
 s3 = ["boto3", "django-storages"]
+sentry = ["sentry"]
 
 [tool.poetry.dev-dependencies]
 aleksis-builddeps = "*"