diff --git a/briar-gtk/briar_gtk/actions/login.py b/briar-gtk/briar_gtk/actions/login.py
new file mode 100644
index 0000000000000000000000000000000000000000..549904ae42c20c96f87660a0840fb3d3be712535
--- /dev/null
+++ b/briar-gtk/briar_gtk/actions/login.py
@@ -0,0 +1,26 @@
+# Copyright (c) 2020 Nico Alt
+# SPDX-License-Identifier: AGPL-3.0-only
+# License-Filename: LICENSE.md
+
+from briar_gtk.actions.actions import Actions
+
+
+# pylint: disable=too-few-public-methods
+class LoginActions(Actions):
+
+    ACTIONS_PREFIX = "login"
+
+    def __init__(self, widget):
+        super().__init__(widget)
+        self._setup_simple_action_group(self.ACTIONS_PREFIX)
+        self._setup_actions()
+
+    def _setup_actions(self):
+        self._setup_login_action()
+
+    def _setup_login_action(self):
+        self._setup_action("login", None, self._login)
+
+    # pylint: disable=unused-argument
+    def _login(self, action, parameter):
+        self.widget._on_login_pressed()
diff --git a/briar-gtk/briar_gtk/containers/login.py b/briar-gtk/briar_gtk/containers/login.py
index 3d36f56fa5f9321b207a5a383ab791fbee52e4cd..dcc229f51e3ec28398b2f316203add5cec344c28 100644
--- a/briar-gtk/briar_gtk/containers/login.py
+++ b/briar-gtk/briar_gtk/containers/login.py
@@ -4,6 +4,7 @@
 
 from gi.repository import GLib
 
+from briar_gtk.actions.login import LoginActions
 from briar_gtk.container import Container
 from briar_gtk.define import APP
 
@@ -16,6 +17,7 @@ class LoginContainer(Container):
 
     def __init__(self, window):
         super().__init__()
+        LoginActions(self)
         self._window = window
         self._setup_view()
 
@@ -35,6 +37,7 @@ class LoginContainer(Container):
     def _setup_login_flow_headers(self):
         login_flow_headers = self.builder.get_object(self.HEADERS_NAME)
         login_flow_headers.show_all()
+        login_flow_headers.insert_action_group("login", self.get_action_group("login"))
         self._window.set_titlebar(login_flow_headers)
 
     def _setup_enter_listener(self):
@@ -43,10 +46,10 @@ class LoginContainer(Container):
 
     # pylint: disable=unused-argument
     def _on_password_enter(self, widget):
-        self.on_login_pressed(None)
+        self._on_login_pressed()
 
     # pylint: disable=unused-argument
-    def on_login_pressed(self, button):
+    def _on_login_pressed(self):
         self._show_loading_animation()
         self._login()
 
diff --git a/briar-gtk/data/ui/login.ui b/briar-gtk/data/ui/login.ui
index 3ac5a591e29a06f203d50996f794eb29de10d0b7..4a95caee83cc9f4731e69dd99252b60dda2fd9d7 100644
--- a/briar-gtk/data/ui/login.ui
+++ b/briar-gtk/data/ui/login.ui
@@ -116,7 +116,7 @@
             <property name="use_underline">True</property>
             <property name="can_focus">True</property>
             <property name="label" translatable="yes">Log in</property>
-            <signal name="clicked" handler="on_login_pressed"/>
+            <property name="action_name">login.login</property>
             <style>
               <class name="suggested-action"/>
             </style>