diff --git a/files/auth/auth.service b/files/auth/auth.service
new file mode 100644
index 0000000000000000000000000000000000000000..cf6ba59421e9918bc2bee99e6bba2ab7cdf1d6d5
--- /dev/null
+++ b/files/auth/auth.service
@@ -0,0 +1,17 @@
+[Unit]
+Description=Exam System Message Broker
+After=network.target
+
+[Service]
+Type=simple
+User=auth
+WorkingDirectory=/srv/auth/
+ExecStart=/srv/auth/start.sh
+Restart=on-failure
+RestartSec=10
+
+# No limit. We won't overload the system anyway.
+StartLimitIntervalSec=0
+
+[Install]
+WantedBy=multi-user.target
diff --git a/files/auth/config.json b/files/auth/config.json
new file mode 100644
index 0000000000000000000000000000000000000000..c7d0302ec319c49130670c167861cf1f6665850a
--- /dev/null
+++ b/files/auth/config.json
@@ -0,0 +1,126 @@
+// The client strips C++-style comments from this file. There are some restrictions as follows:
+// - Only C++-style single line comments are allowed.
+// - They must be the only thing on the line, except for leading whitespace (space and tab)
+// These are in place to make it easy to strip the comments without knowledge of JSON before passing
+// it to the JSON parser.
+{
+    // Timeout for all authentications, in minutes
+    "timeout" : 1,
+
+    // All groups known to the system, and what permissions we assign each group.
+    "groups" : {
+	// Each entry consists of the group's name, followed by properties for that group.
+	"TEST" : {
+	    // Maximum message size for this group.
+	    "message_size" : 10240,
+
+	    // Allow communicating to these groups. The empty string is the broadcast "group".
+	    "groups" : [ "TEST" ]
+	},
+
+	// Admin clients.
+	"ADMC" : {
+	    "message_size" : 1024000,
+	    "groups" : [ "", "ADMC", "DB", "MS" ]
+	},
+
+	// Examiner clients.
+	"EC" : {
+	    "message_size" : 1024000,
+	    "groups" : [ "", "MS" ]
+	},
+
+	// Student clients.
+	"SC" : {
+	    "message_size" : 102400,
+	    "groups" : [ "MS" ]
+	},
+
+	// Message server.
+	"MS" : {
+	    "message_size" : 1024000,
+	    "groups" : [ "", "EC", "SC" ]
+	},
+
+	// The "large" DB server.
+	// Note: If using the kerberos authentication, the DB needs to be able to reply to AUTH-messages.
+	"DB" : {
+	    "message_size" : 1024000,
+	    "groups" : [ "", "ADMC", "MS", "AUTH" ]
+	}
+    },
+
+    // All authentication methods the auth server is going to support. Each method may appear multiple
+    // times with different configuration if different groups are to be guarded with different levels
+    // of security.
+    "methods" : [
+	{
+	    // A list of groups that we allow authenticating using this method. This is mandatory
+	    // for all elements in here.
+	    "allow" : [ "TEST" ],
+
+	    // The debug auth is the simplest. It just allows whatever the connected client
+	    // claimed. It is not good to use in production, and is always disabled unless the
+	    // "--debug" flag is given on the command line.
+	    "type" : "debug"
+	},
+	{
+	    "allow" : [ "DB", "MS" ],
+
+	    // File system authentication. This works for clients on the same system as the
+	    // authentication server (e.g. DB, ARLA, etc.), and relies on UNIX permissions. This
+	    // means we don't have to bother with certificates and the like.
+	    "type" : "fs",
+
+	    // Where to store the key files in the filesystem.
+	    "path" : "/tmp",
+
+	    // Permissions of the file.
+	    "permissions" : "0770",
+
+	    // Group of the file. If not present or null, we won't change the group.
+	    "group" : null
+	},
+	{
+	    // Slightly different requirements for ADMC.
+	    "allow" : [ "ADMC" ],
+	    "type" : "fs",
+	    "path" : "/tmp",
+	    "permissions" : "0777",
+	    "group" : null
+	},
+	{
+	    // Allow FS auth for the TEST group as well.
+	    "allow" : [ "TEST" ],
+	    "type" : "fs",
+	    "path" : "/tmp",
+	    "permissions" : "0777",
+	    "group" : null
+	},
+	{
+	    // Allow authenticating EC with Kerberos.
+	    "allow" : [ "EC" ],
+	    "type" : "kerberos",
+
+	    // What is the address of the database server we shall query for information?
+	    "db" : {
+		"group" : "DB",
+		"id" : 1
+	    },
+
+	    "user_type" : "staff"
+	},
+	{
+	    // Allow authenticating SC with Kerberos.
+	    "allow" : [ "SC" ],
+	    "type" : "kerberos",
+
+	    "db" : {
+		"group" : "DB",
+		"id" : 1
+	    },
+
+	    "user_type" : "student"
+	}
+    ]
+}
diff --git a/files/auth/on_update.sh b/files/auth/on_update.sh
new file mode 100644
index 0000000000000000000000000000000000000000..848eb18d98a071272dd245436ebba2857775a562
--- /dev/null
+++ b/files/auth/on_update.sh
@@ -0,0 +1,22 @@
+#!/bin/bash
+
+run_as_broker=$(cat <<'EOF'
+cd
+# To make sure we have a decent GCC in our path.
+source /opt/rh/devtoolset-7/enable
+cd src/auth
+make clean
+make
+
+cd
+mkdir -p bin/
+cp src/auth/auth bin/
+EOF
+)
+
+# Compile as the auth user
+sudo --user auth --group auth --set-home -- bash -c "$run_as_broker"
+
+# Then, we can restart the services.
+systemctl service restart aes_auth.service
+
diff --git a/files/auth/start.sh b/files/auth/start.sh
new file mode 100644
index 0000000000000000000000000000000000000000..435ef7e06a8b905dd40bc97cec5803dea39b17e0
--- /dev/null
+++ b/files/auth/start.sh
@@ -0,0 +1,10 @@
+#!/bin/bash
+
+if grep "aes-devel" /etc/hostname > /dev/null
+then
+    # Allow debug auth when on the devel system.
+    exec bin/auth --debug 31338 config.json
+else
+    # Not on the real system, however.
+    exec bin/auth 31338 config.json
+fi
diff --git a/files/broker/broker.service b/files/broker/broker.service
new file mode 100644
index 0000000000000000000000000000000000000000..f4f902a4c516a7fc7358f54605082d5c565b4f74
--- /dev/null
+++ b/files/broker/broker.service
@@ -0,0 +1,17 @@
+[Unit]
+Description=Exam System Message Broker
+After=network.target
+
+[Service]
+Type=simple
+User=broker
+WorkingDirectory=/srv/broker/
+ExecStart=/srv/broker/bin/broker 31337 localhost 31338
+Restart=on-failure
+RestartSec=10
+
+# No limit. We won't overload the system anyway.
+StartLimitIntervalSec=0
+
+[Install]
+WantedBy=multi-user.target
diff --git a/files/broker/on_update.sh b/files/broker/on_update.sh
new file mode 100644
index 0000000000000000000000000000000000000000..ec79273b6940fe8e71332d67f6278fd52283bbf2
--- /dev/null
+++ b/files/broker/on_update.sh
@@ -0,0 +1,22 @@
+#!/bin/bash
+
+run_as_broker=$(cat <<'EOF'
+cd
+# To make sure we have a decent GCC in our path.
+source /opt/rh/devtoolset-7/enable
+cd src/broker
+make clean
+make
+
+cd
+mkdir -p bin/
+cp src/broker/broker bin/
+EOF
+)
+
+# Compile as "broker".
+sudo --user broker --group broker --set-home -- bash -c "$run_as_broker"
+
+# Then, we can restart the services.
+systemctl service restart aes_broker.service
+
diff --git a/manifests/aes_broker.pp b/manifests/aes_broker.pp
deleted file mode 100644
index 8b7ab129dd6fa749630db8ded1192c0a6f3514f2..0000000000000000000000000000000000000000
--- a/manifests/aes_broker.pp
+++ /dev/null
@@ -1,43 +0,0 @@
-class aes::aes_broker {
-
-  $broker_user = broker
-  $broker_group = "${broker_user}"
-  $broker_home = "/srv/${broker_user}"
-  $broker_service = "${broker_user}"
-
-  # Sadly, it does not seem like we can only install asio, so we need
-  # to install the Boost as a whole.
-  # It is easiest to install just "boost", even if that is a bit older
-  # than what is available (others require modifying the include path).
-  # It is still enough for the broker.
-  package {
-    [
-	'boost',
-	'boost-devel',
-	'krb5-libs',
-	'krb5-devel',
-    ]:
-      ensure => installed,
-  }
-
-  user { "${broker_user}" :
-    ensure => present,
-    home => "${broker_home}",
-    comment => 'Message broker for AES',
-    managehome => false,
-    membership => inclusive,
-    system => true,
-    shell => '/sbin/nologin',
-  }
-
-  file { "${broker_home}" :
-    ensure => directory,
-    owner => "${broker_user}",
-    group => "${broker_group}",
-    mode => '0755',
-  }
-
-  # TODO: We still need to download the source from Git as needed and update the broker and auth service.
-  # To compile the broker, we need to do "source /opt/rh/devtoolset-7/enable" first. Otherwise, we will not get a good enough GCC.
-
-}
\ No newline at end of file
diff --git a/manifests/auth.pp b/manifests/auth.pp
new file mode 100644
index 0000000000000000000000000000000000000000..d100ee29df92c3a1832327b62bcdb78713b8460d
--- /dev/null
+++ b/manifests/auth.pp
@@ -0,0 +1,86 @@
+class aes::auth {
+
+  $auth_user = auth
+  $auth_group = "${auth_user}"
+  $auth_home = "/srv/${auth_user}"
+  $auth_service = "aes_auth"
+
+  # Sadly, it does not seem like we can only install asio, so we need
+  # to install the Boost as a whole.
+  # It is easiest to install just "boost", even if that is a bit older
+  # than what is available (others require modifying the include path).
+  # It is still enough for the auth server.
+  package {
+    [
+	'boost',
+	'boost-devel',
+	'krb5-libs',
+	'krb5-devel',
+    ]:
+      ensure => installed,
+  }
+
+  user { "${auth_user}" :
+    ensure => present,
+    home => "${auth_home}",
+    comment => 'Authentication server for AES',
+    managehome => false,
+    membership => inclusive,
+    system => true,
+    shell => '/sbin/nologin',
+  }
+
+  file { "${auth_home}" :
+    ensure => directory,
+    owner => "${auth_user}",
+    group => "${auth_group}",
+    mode => '0755',
+  }
+
+  file { "/etc/systemd/system/${auth_service}.service" :
+    ensure => present,
+    owner  => root,
+    group  => root,
+    mode   => '0644',
+    source => "puppet:///modules/${module_name}/auth/auth.service",
+  }
+
+  file { "${auth_home}/on_update.sh" :
+    ensure => present,
+    owner  => root,
+    group  => root,
+    mode   => '0700',
+    source => "puppet:///modules/${module_name}/auth/on_update.sh",
+  }
+
+  file { "${auth_home}/config.json" :
+    ensure => present,
+    owner  => auth,
+    group  => auth,
+    mode   => '0644',
+    source => "puppet:///modules/${module_name}/auth/config.json",
+  }
+
+  file { "${auth_home}/start.sh" :
+    ensure => present,
+    owner  => auth,
+    group  => auth,
+    mode   => '0755',
+    source => "puppet:///modules/${module_name}/auth/start.sh",
+  }
+
+  exec { 'update-auth-repo' :
+    command => "/opt/utils/update_repo.sh ${auth_home}/src https://oauth2:F-agHaRXCdyFy38q4c-N@gitlab.liu.se/upp-aes/communication.git production",
+    environment => [ "REPO_USER=${auth_user}", "REPO_GROUP=${auth_group}", "REPO_ON_UPDATE=${auth_home}/on_update.sh" ],
+    # This command will need to run "on_update" as root in order to restart the service.
+    user => root,
+    group => root,
+    cwd => "${auth_home}",
+    require => File["${auth_home}/on_update.sh"],
+  }
+
+  service { "${auth_service}" : 
+    ensure => "running",
+  }
+
+}
\ No newline at end of file
diff --git a/manifests/broker.pp b/manifests/broker.pp
new file mode 100644
index 0000000000000000000000000000000000000000..bd8891bbef2471c54ad1052d0c263d242e61cd23
--- /dev/null
+++ b/manifests/broker.pp
@@ -0,0 +1,68 @@
+class aes::broker {
+
+  $broker_user = broker
+  $broker_group = "${broker_user}"
+  $broker_home = "/srv/${broker_user}"
+  $broker_service = "aes_broker"
+
+  # Sadly, it does not seem like we can only install asio, so we need
+  # to install the Boost as a whole.
+  # It is easiest to install just "boost", even if that is a bit older
+  # than what is available (others require modifying the include path).
+  # It is still enough for the broker.
+  package {
+    [
+	'boost',
+	'boost-devel',
+    ]:
+      ensure => installed,
+  }
+
+  user { "${broker_user}" :
+    ensure => present,
+    home => "${broker_home}",
+    comment => 'Message broker for AES',
+    managehome => false,
+    membership => inclusive,
+    system => true,
+    shell => '/sbin/nologin',
+  }
+
+  file { "${broker_home}" :
+    ensure => directory,
+    owner => "${broker_user}",
+    group => "${broker_group}",
+    mode => '0755',
+  }
+
+  file { "/etc/systemd/system/${broker_service}.service" :
+    ensure => present,
+    owner  => root,
+    group  => root,
+    mode   => '0644',
+    source => "puppet:///modules/${module_name}/broker/broker.service",
+  }
+
+  file { "${broker_home}/on_update.sh" :
+    ensure => present,
+    owner  => root,
+    group  => root,
+    mode   => '0700',
+    source => "puppet:///modules/${module_name}/broker/on_update.sh",
+  }
+
+  exec { 'update-broker-repo' :
+    command => "/opt/utils/update_repo.sh ${broker_home}/src https://oauth2:F-agHaRXCdyFy38q4c-N@gitlab.liu.se/upp-aes/communication.git production",
+    environment => [ "REPO_USER=${broker_user}", "REPO_GROUP=${broker_group}", "REPO_ON_UPDATE=${broker_home}/on_update.sh" ],
+    # This command will need to run "on_update" as root in order to restart the service.
+    user => root,
+    group => root,
+    cwd => "${broker_home}",
+    require => File["${broker_home}/on_update.sh"],
+  }
+
+  service { "${broker_service}" : 
+    ensure => "running",
+  }
+
+}
\ No newline at end of file
diff --git a/manifests/init.pp b/manifests/init.pp
index f33e6883af58426894faf031aba62782aefbac5b..d06fa4209cf1ea522c87618796fbe5dc9c2bad9b 100644
--- a/manifests/init.pp
+++ b/manifests/init.pp
@@ -4,7 +4,8 @@ class aes {
   include aes::opendsa
   include aes::squid_filter
   include aes::latex
-  include aes::aes_broker
+  include aes::broker
+  include aes::auth
   include ::liurepo::centos_sclo_rh
 
   package {
@@ -83,14 +84,14 @@ class aes {
     service sclogin is tcp/23431
     service aesmsi is tcp/23816
     service aesmso is tcp/23817
-#    service opendsa is tcp/12000
+    service aesbroker is tcp/31337
 
     policy chain INPUT is
       accept service:squid from class:liu-nets
       accept service:sclogin from class:liu-nets
       accept service:aesmsi from class:liu-nets
       accept service:aesmso from class:liu-nets
-#      accept service:opendsa from class:liu-nets
+      accept service:aesbroker from class:liu-nets
     end policy
     |-EOF
   }
diff --git a/manifests/opendsa.pp b/manifests/opendsa.pp
index 90651f77ce7d417f65c8029265db4f456e4356af..b8f3a56fd86e14ed2ca518fc6fd565da01d75804 100644
--- a/manifests/opendsa.pp
+++ b/manifests/opendsa.pp
@@ -35,7 +35,7 @@ class aes::opendsa {
     ensure => present,
     owner  => root,
     group  => root,
-    mode => '0644',
+    mode   => '0644',
     source => "puppet:///modules/${module_name}/opendsa/opendsa.service",
   }