diff --git a/jams-common/pom.xml b/jams-common/pom.xml
index 065b4c7495ea8df8fa4e347d69376cf681f860ff..5bc99ad07fec94f340f460b601b1f2e8eda156f0 100644
--- a/jams-common/pom.xml
+++ b/jams-common/pom.xml
@@ -27,6 +27,11 @@
             <artifactId>xbean-classloader</artifactId>
             <version>${xbean.version}</version>
         </dependency>
+        <dependency>
+            <groupId>org.zeromq</groupId>
+            <artifactId>jeromq</artifactId>
+            <version>0.5.2</version>
+        </dependency>
     </dependencies>
 
 </project>
\ No newline at end of file
diff --git a/jams-common/src/main/java/module-info.java b/jams-common/src/main/java/module-info.java
index 37e5ce3059229a0f59d880bf050ae093cc3da22e..4358de73c8dc950dee314af827dfc1df62752566 100644
--- a/jams-common/src/main/java/module-info.java
+++ b/jams-common/src/main/java/module-info.java
@@ -56,5 +56,6 @@ module jams.common {
     requires java.base;
     requires java.sql;
     requires org.apache.xbean.classloader;
+    requires jeromq;
 }
 
diff --git a/jams-common/src/main/java/net/jami/jams/common/utils/LicenseUtils.java b/jams-common/src/main/java/net/jami/jams/common/utils/LicenseUtils.java
new file mode 100644
index 0000000000000000000000000000000000000000..6dda71e7b8a8ddf65e6095c9c03aef26a29b15e5
--- /dev/null
+++ b/jams-common/src/main/java/net/jami/jams/common/utils/LicenseUtils.java
@@ -0,0 +1,65 @@
+package net.jami.jams.common.utils;
+
+
+import lombok.extern.slf4j.Slf4j;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.jar.Manifest;
+
+@Slf4j
+public class LicenseUtils {
+
+
+    public static String checkVersion(String destinationDir, String jarPath) throws IOException {
+        String resp = "";
+        File file = new File(jarPath);
+        JarFile jar = new JarFile(file);
+
+        // first get all directories,
+        // then make those directory on the destination Path
+        for (Enumeration<JarEntry> enums = jar.entries(); enums.hasMoreElements(); ) {
+            JarEntry entry = (JarEntry) enums.nextElement();
+
+            String fileName = destinationDir + File.separator + entry.getName();
+            File f = new File(fileName);
+
+            if (fileName.endsWith("/")) {
+                f.mkdirs();
+            }
+        }
+
+        //now create all files
+        for (Enumeration<JarEntry> enums = jar.entries(); enums.hasMoreElements(); ) {
+            JarEntry entry = (JarEntry) enums.nextElement();
+            if (entry.toString().contains("META-INF/MANIFEST.MF")) {
+                String fileName = destinationDir + File.separator + entry.getName();
+                File f = new File(fileName);
+
+                if (!fileName.endsWith("/")) {
+                    InputStream is = jar.getInputStream(entry);
+                    FileOutputStream fos = new FileOutputStream(f);
+
+                    // write contents of 'is' to 'fos'
+                    while (is.available() > 0) {
+                        fos.write(is.read());
+                    }
+
+                    fos.close();
+                    is.close();
+                }
+            }
+        }
+
+        String manifestPath = destinationDir + "/META-INF/MANIFEST.MF";
+        Manifest manifest = new Manifest(new URL("file:///" + manifestPath).openStream());
+        resp = manifest.getMainAttributes().getValue("Implementation-Version");
+        return resp;
+    }
+}
diff --git a/jams-common/src/main/java/net/jami/jams/common/utils/UpdateInterface.java b/jams-common/src/main/java/net/jami/jams/common/utils/UpdateInterface.java
new file mode 100644
index 0000000000000000000000000000000000000000..7bfcf4499a031bca37bc558e7f506bf64edcbcd9
--- /dev/null
+++ b/jams-common/src/main/java/net/jami/jams/common/utils/UpdateInterface.java
@@ -0,0 +1,46 @@
+package net.jami.jams.common.utils;
+
+import lombok.Getter;
+import lombok.Setter;
+import org.zeromq.SocketType;
+import org.zeromq.ZMQ;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.logging.Logger;
+
+@Getter
+@Setter
+public class UpdateInterface extends Thread {
+
+    private AtomicBoolean updateAvailable = new AtomicBoolean(false);
+    private volatile String versions;
+    private ZMQ.Context context = ZMQ.context(1);
+    private ZMQ.Socket sender = context.socket(SocketType.REQ);
+    private ZMQ.Socket receiver = context.socket(SocketType.SUB);
+    private final static Logger logger = Logger.getLogger(UpdateInterface.class.getName());
+
+    public UpdateInterface() {
+        receiver.connect("tcp://localhost:4572");
+        sender.connect("tcp://localhost:4573");
+        receiver.subscribe("UPDATE");
+        this.start();
+    }
+
+    public void approveUpdate(){
+        sender.send("DO-UPDATE");
+    }
+
+    @Override
+    public void run() {
+        while(true){
+            try{
+                receiver.recv();
+                updateAvailable.set(true);
+                versions = receiver.recvStr();
+            }
+            catch (Exception e){
+                System.out.println(e.toString());
+            }
+        }
+    }
+}
diff --git a/jams-launcher/pom.xml b/jams-launcher/pom.xml
index 54ecb9f5d32d9e26da7c18bd05fb75afbe9b5883..9a63478b6d47c33f5454300045db1a48467958f2 100644
--- a/jams-launcher/pom.xml
+++ b/jams-launcher/pom.xml
@@ -36,11 +36,6 @@
             <artifactId>guava</artifactId>
             <version>20.0</version>
         </dependency>
-        <dependency>
-            <groupId>org.zeromq</groupId>
-            <artifactId>jeromq</artifactId>
-            <version>0.5.2</version>
-        </dependency>
         <dependency>
             <groupId>com.blockfeed</groupId>
             <artifactId>messaging</artifactId>
diff --git a/jams-server/pom.xml b/jams-server/pom.xml
index 16d4bc93a882176e56580aec0eaf03f8167df009..df79a7a973d6746c7d9745a60f0c4b535f483b48 100644
--- a/jams-server/pom.xml
+++ b/jams-server/pom.xml
@@ -66,6 +66,11 @@
             <artifactId>asm</artifactId>
             <version>${asm.version}</version>
         </dependency>
+        <dependency>
+            <groupId>org.json</groupId>
+            <artifactId>json</artifactId>
+            <version>20190722</version>
+        </dependency>
     </dependencies>
 
     <build>
diff --git a/jams-server/src/main/java/module-info.java b/jams-server/src/main/java/module-info.java
index 6024a4383902e5a0f5003b4416d8271996a6bcd7..b695686d7f4179a841768289a220bac0b94f7e9f 100644
--- a/jams-server/src/main/java/module-info.java
+++ b/jams-server/src/main/java/module-info.java
@@ -14,6 +14,10 @@ module jams.server {
     requires jami.dht;
     requires nimbus.jose.jwt;
     requires java.desktop;
+    requires org.json;
+    requires java.naming;
+    requires java.logging;
+    requires javax.servlet.api;
     exports net.jami.jams.server.servlets.general to org.apache.tomcat.embed.core;
     exports net.jami.jams.server.servlets.filters to org.apache.tomcat.embed.core;
     exports net.jami.jams.server.servlets.api.auth.login to org.apache.tomcat.embed.core;
diff --git a/jams-server/src/main/java/net/jami/jams/server/Server.java b/jams-server/src/main/java/net/jami/jams/server/Server.java
index a4ae6537c442e9932961641c925a3bcf1ff7b33a..ad882a203f2578ae7a07c59057c00f6bce0cffa9 100644
--- a/jams-server/src/main/java/net/jami/jams/server/Server.java
+++ b/jams-server/src/main/java/net/jami/jams/server/Server.java
@@ -11,6 +11,7 @@ import net.jami.jams.common.jami.NameServer;
 import net.jami.jams.common.serialization.JsoniterRegistry;
 import net.jami.jams.common.server.ServerSettings;
 import net.jami.jams.common.utils.LibraryLoader;
+import net.jami.jams.common.utils.UpdateInterface;
 import net.jami.jams.nameserver.LocalNameServer;
 import net.jami.jams.nameserver.PublicNameServer;
 import net.jami.jams.server.core.TomcatLauncher;
@@ -26,6 +27,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
 public class Server {
 
     public static AtomicBoolean isInstalled = new AtomicBoolean(false);
+    private static volatile boolean activated = false;
 
     static {
         JsoniterRegistry.initCodecs();
@@ -37,6 +39,7 @@ public class Server {
     public  static AuthenticationModule userAuthenticationModule;
     public  static NameServer nameServer;
     private static TomcatLauncher tomcatLauncher = null;
+    public static final UpdateInterface updateInterface = new UpdateInterface();
 
     public static void main(String[] args) {
         //Start tomcat.
@@ -89,4 +92,12 @@ public class Server {
             log.info("Started server with empty modules waiting for setup...");
         }
     }
+
+    public static boolean isActivated() {
+        return activated;
+    }
+
+    public static void setActivated(boolean isActivated) {
+        Server.activated = isActivated;
+    }
 }
diff --git a/jams-server/src/main/java/net/jami/jams/server/licensing/LicenseService.java b/jams-server/src/main/java/net/jami/jams/server/licensing/LicenseService.java
new file mode 100644
index 0000000000000000000000000000000000000000..1e0f30935cfbc0a0deb2e834faba4d43aadafa00
--- /dev/null
+++ b/jams-server/src/main/java/net/jami/jams/server/licensing/LicenseService.java
@@ -0,0 +1,90 @@
+package net.jami.jams.server.licensing;
+
+import lombok.Getter;
+import lombok.Setter;
+import lombok.extern.slf4j.Slf4j;
+import net.jami.jams.server.Server;
+import org.json.JSONObject;
+
+import javax.naming.ldap.LdapName;
+import javax.naming.ldap.Rdn;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.util.Base64;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+@Getter
+@Setter
+@Slf4j
+public class LicenseService {
+
+    private AtomicBoolean activationStatus = new AtomicBoolean(false);
+    private String licenseType = "COMMUNITY";
+
+    //Load the license.
+    public void loadLicense() {
+        try {
+            CertificateFactory cf = CertificateFactory.getInstance("X.509");
+            //Assuming the file exists, we just read the file.
+            String b64License = new String(Files.readAllBytes(Path.of(System.getProperty("user.dir") + File.separator + "license.dat")));
+            //Since this is base64, we need to decode it.
+            String strLicense = new String(Base64.getDecoder().decode(b64License));
+            //Now we need to split it. This is actually easy.
+            int cutPoint = strLicense.indexOf("-----BEGIN PRIVATE KEY-----");
+            String publicKey = strLicense.substring(0,cutPoint);
+
+            InputStream inputStream = new ByteArrayInputStream(publicKey.getBytes(StandardCharsets.UTF_8));
+            Certificate c = cf.generateCertificate(inputStream);
+            String dn = ((X509Certificate)c).getSubjectDN().toString();
+            LdapName ln = new LdapName(dn);
+            byte[] array = null;
+            for(Rdn rdn : ln.getRdns()) {
+                try {
+                    array = Base64.getDecoder().decode(((String)rdn.getValue()).getBytes());
+                } catch (IllegalArgumentException e) {
+
+                }
+            }
+
+            //This is kept inside the resources/oem folder, this is a lot less violent than what we had before.
+            //TODO: You should re-use the same technique to validate whatever they stick in the textbox.
+            InputStream input = LicenseService.class.getClassLoader().getResourceAsStream("oem/ca.crt");
+            if (input == null) {
+                System.out.println("No CA Found... this is critical!");
+                System.exit(-1);
+            }
+            Certificate ca = cf.generateCertificate(input);
+            try{
+                ((X509Certificate) c).checkValidity();
+                c.verify(ca.getPublicKey());
+                Server.setActivated(true);
+                if (array != null) {
+                    JSONObject jsonObject = new JSONObject(new String(array));
+                    licenseType = (String) jsonObject.get("type");
+                }
+            }
+            catch (Exception e){
+                Server.setActivated(false);
+                licenseType = "COMMUNITY";
+                log.warn("Your license is no longer valid or has been tampered with - " + e.toString());
+            }
+        }
+        catch (Exception e){
+            Server.setActivated(false);
+            licenseType = "COMMUNITY";
+            //logger.warning("An exception occurred while checking your license: " + e.toString());
+        }
+    }
+
+    public String getLicenseType() {
+        loadLicense();
+        return licenseType;
+    }
+}
diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/api/update/LicenseServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/api/update/LicenseServlet.java
new file mode 100644
index 0000000000000000000000000000000000000000..de2518e1b2e002f8e5be1458852755164d38260d
--- /dev/null
+++ b/jams-server/src/main/java/net/jami/jams/server/servlets/api/update/LicenseServlet.java
@@ -0,0 +1,39 @@
+package net.jami.jams.server.servlets.api.update;
+
+import com.jsoniter.output.JsonStream;
+import net.jami.jams.ca.JamsCA;
+import net.jami.jams.common.cryptoengineapi.CertificateAuthority;
+import net.jami.jams.common.utils.LicenseUtils;
+import net.jami.jams.server.Server;
+import net.jami.jams.server.licensing.LicenseService;
+import net.jami.jams.server.startup.CryptoEngineLoader;
+
+import javax.servlet.annotation.WebServlet;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.HashMap;
+
+
+@WebServlet("/api/auth/license")
+public class LicenseServlet extends HttpServlet {
+
+
+    @Override
+    protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
+        resp.setHeader("Access-Control-Allow-Origin", JamsCA.serverDomain);
+        resp.setContentType("application/json");
+        try {
+            resp.setStatus(200);
+            HashMap<String,Object> payload = new HashMap<>();
+            payload.put("isActive", Server.isActivated());
+            payload.put("licenseType", new LicenseService().getLicenseType());
+            payload.put("currentVersion", LicenseUtils.checkVersion(System.getProperty("user.dir") + "/tmpjar/", System.getProperty("user.dir") + "/jams-server.jar"));
+            resp.getOutputStream().write(JsonStream.serialize(payload).getBytes());
+        }
+        catch (Exception e){
+            resp.setStatus(403);
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/api/update/NeedsUpdateServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/api/update/NeedsUpdateServlet.java
new file mode 100644
index 0000000000000000000000000000000000000000..cae916d93dc1f27aeb0a5e280ba50d3381d675f7
--- /dev/null
+++ b/jams-server/src/main/java/net/jami/jams/server/servlets/api/update/NeedsUpdateServlet.java
@@ -0,0 +1,46 @@
+package net.jami.jams.server.servlets.api.update;
+
+import com.jsoniter.output.JsonStream;
+import net.jami.jams.ca.JamsCA;
+import net.jami.jams.server.Server;
+
+import javax.servlet.ServletException;
+import javax.servlet.annotation.WebServlet;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.logging.Logger;
+
+@WebServlet("/api/checkupdate")
+public class NeedsUpdateServlet extends HttpServlet {
+
+    private final static Logger logger = Logger.getLogger(NeedsUpdateServlet.class.getName());
+
+    @Override
+    protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
+        resp.setHeader("Access-Control-Allow-Origin", JamsCA.serverDomain);
+        resp.setContentType("application/json");
+        try {
+            HashMap<String,Object> payload = new HashMap<>();
+            if(!Server.updateInterface.getVersions().equals("{}")) {
+                payload.put("updateAvailable", Server.updateInterface.getUpdateAvailable().get());
+                payload.put("newVersions", Server.updateInterface.getVersions());
+            }
+            else
+                payload.put("updateAvailable",false);
+
+            resp.getOutputStream().write(JsonStream.serialize(payload).getBytes());
+            resp.setStatus(200);
+        }
+        catch (Exception e){
+            resp.setStatus(500);
+        }
+    }
+
+    @Override
+    protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+
+    }
+}
diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/api/update/StartUpdateServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/api/update/StartUpdateServlet.java
new file mode 100644
index 0000000000000000000000000000000000000000..52b1e38be8fd68afd411a3c070d54a2b812abe71
--- /dev/null
+++ b/jams-server/src/main/java/net/jami/jams/server/servlets/api/update/StartUpdateServlet.java
@@ -0,0 +1,29 @@
+package net.jami.jams.server.servlets.api.update;
+
+import net.jami.jams.ca.JamsCA;
+import net.jami.jams.server.Server;
+
+import javax.servlet.annotation.WebServlet;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.logging.Logger;
+
+@WebServlet("/api/startupdate")
+public class StartUpdateServlet extends HttpServlet {
+
+    private final static Logger logger = Logger.getLogger(StartUpdateServlet.class.getName());
+
+    @Override
+    protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
+        resp.setHeader("Access-Control-Allow-Origin", JamsCA.serverDomain);
+        resp.setContentType("application/json");
+        try {
+            Server.updateInterface.approveUpdate();
+            resp.setStatus(200);
+        }
+        catch (Exception e){
+            resp.setStatus(500);
+        }
+    }
+}