diff --git a/pom.xml b/pom.xml
index f68750bdf1b..ff31046789f 100755
--- a/pom.xml
+++ b/pom.xml
@@ -1706,5 +1706,13 @@
+
+
+ quarkus
+
+ quarkus
+
+
+
diff --git a/quarkus/README.md b/quarkus/README.md
new file mode 100644
index 00000000000..6f63e631e0e
--- /dev/null
+++ b/quarkus/README.md
@@ -0,0 +1,13 @@
+# Keycloak Quarkus Distribution
+
+Keycloak on Quarkus is a work in progress.
+
+## Building and running
+
+ mvn package
+ java -jar server/target/keycloak-runner.jar
+
+## Running in dev mode
+
+ cd server
+ mvn compile quarkus:dev
\ No newline at end of file
diff --git a/quarkus/extensions/pom.xml b/quarkus/extensions/pom.xml
new file mode 100644
index 00000000000..2b917f7f584
--- /dev/null
+++ b/quarkus/extensions/pom.xml
@@ -0,0 +1,18 @@
+
+
+
+ keycloak-quarkus-parent
+ org.keycloak
+ 8.0.0-SNAPSHOT
+ ../pom.xml
+
+ 4.0.0
+
+ keycloak-quarkus-extensions
+
+
+
+
+
diff --git a/quarkus/pom.xml b/quarkus/pom.xml
new file mode 100755
index 00000000000..c34a61fa21f
--- /dev/null
+++ b/quarkus/pom.xml
@@ -0,0 +1,66 @@
+
+
+
+
+ keycloak-parent
+ org.keycloak
+ 8.0.0-SNAPSHOT
+ ../pom.xml
+
+ Keycloak Quarkus Parent
+
+ 4.0.0
+
+ keycloak-quarkus-parent
+ pom
+
+
+ 2.22.0
+ 0.23.2
+ 1.5.0.Final-format-001
+ 1.8
+ UTF-8
+ 1.8
+ true
+ true
+
+
+
+
+
+ io.quarkus
+ quarkus-bom
+ ${quarkus.version}
+ pom
+ import
+
+
+ org.keycloak
+ keycloak-quarkus-extensions
+ ${project.version}
+
+
+
+
+
+ extensions
+ server
+
+
+
diff --git a/quarkus/server/pom.xml b/quarkus/server/pom.xml
new file mode 100644
index 00000000000..91fb86d196e
--- /dev/null
+++ b/quarkus/server/pom.xml
@@ -0,0 +1,240 @@
+
+
+
+ keycloak-quarkus-parent
+ org.keycloak
+ 8.0.0-SNAPSHOT
+ ../pom.xml
+
+ 4.0.0
+
+ keycloak-quarkus-server
+
+
+
+
+ io.quarkus
+ quarkus-resteasy
+
+
+ io.quarkus
+ quarkus-resteasy-jackson
+
+
+ io.quarkus
+ quarkus-jdbc-h2
+
+
+ io.quarkus
+ quarkus-jdbc-postgresql
+
+
+ io.quarkus
+ quarkus-jdbc-mariadb
+
+
+ io.quarkus
+ quarkus-junit5
+ test
+
+
+ io.rest-assured
+ rest-assured
+ test
+
+
+
+
+ org.keycloak
+ keycloak-quarkus-extensions
+
+
+ org.keycloak
+ keycloak-services
+
+
+ org.jboss.resteasy
+ resteasy-jaxrs
+
+
+ org.jboss.resteasy
+ resteasy-multipart-provider
+
+
+ org.jboss.resteasy
+ resteasy-jackson2-provider
+
+
+
+
+ org.keycloak
+ keycloak-js-adapter
+
+
+ *
+ *
+
+
+
+
+ org.keycloak
+ keycloak-common
+
+
+ org.keycloak
+ keycloak-core
+
+
+ org.keycloak
+ keycloak-server-spi
+
+
+ org.keycloak
+ keycloak-server-spi-private
+
+
+ org.keycloak
+ keycloak-themes
+
+
+ org.keycloak
+ keycloak-saml-core-public
+
+
+ org.keycloak
+ keycloak-saml-core
+
+
+ org.keycloak
+ keycloak-model-jpa
+
+
+ org.keycloak
+ keycloak-model-infinispan
+
+
+ org.keycloak
+ keycloak-authz-policy-common
+
+
+ org.keycloak
+ keycloak-kerberos-federation
+
+
+ org.keycloak
+ keycloak-sssd-federation
+
+
+ org.keycloak
+ keycloak-ldap-federation
+
+
+
+
+ org.freemarker
+ freemarker
+
+
+ com.google.guava
+ guava
+
+
+ com.googlecode.owasp-java-html-sanitizer
+ owasp-java-html-sanitizer
+
+
+ org.liquibase
+ liquibase-core
+
+
+ javax.persistence
+ javax.persistence-api
+
+
+ org.hibernate
+ hibernate-core
+
+
+ org.apache.httpcomponents
+ httpcore
+
+
+ org.apache.httpcomponents
+ httpclient
+
+
+ org.bouncycastle
+ bcpkix-jdk15on
+
+
+ org.infinispan
+ infinispan-core
+ ${infinispan.version}
+
+
+ org.infinispan
+ infinispan-commons
+ ${infinispan.version}
+
+
+ org.infinispan
+ infinispan-client-hotrod
+ ${infinispan.version}
+
+
+ org.jboss.resteasy
+ resteasy-core
+
+
+ org.jboss.resteasy
+ resteasy-core-spi
+
+
+
+
+ org.jboss.resteasy
+ resteasy-jaxb-provider
+ ${resteasy4.version}
+
+
+ org.jboss.resteasy
+ resteasy-jackson2-provider
+ ${resteasy4.version}
+
+
+ org.jboss.resteasy
+ resteasy-core-spi
+ ${resteasy4.version}
+
+
+ org.wildfly.common
+ wildfly-common
+ ${wildfly.common.formmat.version}
+
+
+
+
+ keycloak
+
+
+ io.quarkus
+ quarkus-maven-plugin
+ ${quarkus.version}
+
+ true
+ keycloak
+
+
+
+
+ build
+
+
+
+
+
+
+
+
diff --git a/quarkus/server/src/main/java/org/keycloak/services/resources/Dummy.java b/quarkus/server/src/main/java/org/keycloak/services/resources/Dummy.java
new file mode 100644
index 00000000000..2d737333515
--- /dev/null
+++ b/quarkus/server/src/main/java/org/keycloak/services/resources/Dummy.java
@@ -0,0 +1,18 @@
+package org.keycloak.services.resources;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+
+/**
+ * Quarkus doesn't pick up the Application if there's no JAX-RS endpoints
+ */
+@Path("/dummy")
+public class Dummy {
+
+ // ...and doesn't load Resteasy providers unless there is at least one resource method
+ @GET
+ public String hello() {
+ return "Hello World!";
+ }
+
+}
diff --git a/quarkus/server/src/main/resources/META-INF/keycloak-server.json b/quarkus/server/src/main/resources/META-INF/keycloak-server.json
new file mode 100755
index 00000000000..5ed3ac19af5
--- /dev/null
+++ b/quarkus/server/src/main/resources/META-INF/keycloak-server.json
@@ -0,0 +1,122 @@
+{
+
+ "hostname": {
+ "provider": "request",
+
+ "fixed": {
+ "hostname": "localhost",
+ "httpPort": "-1",
+ "httpsPort": "-1"
+ }
+ },
+
+ "admin": {
+ "realm": "master"
+ },
+
+ "eventsStore": {
+ "provider": "${keycloak.eventsStore.provider:jpa}"
+ },
+
+ "eventsListener": {
+ "jboss-logging" : {
+ "success-level": "debug",
+ "error-level": "warn"
+ }
+ },
+
+ "realm": {
+ "provider": "${keycloak.realm.provider:jpa}"
+ },
+
+ "user": {
+ "provider": "${keycloak.user.provider:jpa}"
+ },
+
+ "userFederatedStorage": {
+ "provider": "${keycloak.userFederatedStorage.provider:jpa}"
+ },
+
+ "userSessionPersister": {
+ "provider": "${keycloak.userSessionPersister.provider:jpa}"
+ },
+
+ "authorizationPersister": {
+ "provider": "${keycloak.authorization.provider:jpa}"
+ },
+
+ "userCache": {
+ "default" : {
+ "enabled": true
+ }
+ },
+
+ "timer": {
+ "provider": "basic"
+ },
+
+ "theme": {
+ "staticMaxAge": "${keycloak.theme.staticMaxAge:2592000}",
+ "cacheTemplates": "${keycloak.theme.cacheTemplates:true}",
+ "cacheThemes": "${keycloak.theme.cacheThemes:true}",
+ "folder": {
+ "dir": "${keycloak.theme.dir}"
+ }
+ },
+
+ "scheduled": {
+ "interval": 900
+ },
+
+ "connectionsHttpClient": {
+ "default": {}
+ },
+
+ "connectionsJpa": {
+ "default": {
+ "url": "${keycloak.connectionsJpa.url:jdbc:h2:mem:test;DB_CLOSE_DELAY=-1}",
+ "driver": "${keycloak.connectionsJpa.driver:org.h2.Driver}",
+ "driverDialect": "${keycloak.connectionsJpa.driverDialect:}",
+ "user": "${keycloak.connectionsJpa.user:sa}",
+ "password": "${keycloak.connectionsJpa.password:}",
+ "initializeEmpty": true,
+ "migrationStrategy": "update",
+ "showSql": "${keycloak.connectionsJpa.showSql:false}",
+ "formatSql": "${keycloak.connectionsJpa.formatSql:true}",
+ "globalStatsInterval": "${keycloak.connectionsJpa.globalStatsInterval:-1}"
+ }
+ },
+
+ "realmCache": {
+ "default" : {
+ "enabled": true
+ }
+ },
+
+ "connectionsInfinispan": {
+ "default": {
+ "jgroupsUdpMcastAddr": "${keycloak.connectionsInfinispan.jgroupsUdpMcastAddr:234.56.78.90}",
+ "nodeName": "${keycloak.connectionsInfinispan.nodeName,jboss.node.name:}",
+ "siteName": "${keycloak.connectionsInfinispan.siteName,jboss.site.name:}",
+ "clustered": "${keycloak.connectionsInfinispan.clustered:false}",
+ "async": "${keycloak.connectionsInfinispan.async:false}",
+ "sessionsOwners": "${keycloak.connectionsInfinispan.sessionsOwners:1}",
+ "l1Lifespan": "${keycloak.connectionsInfinispan.l1Lifespan:600000}",
+ "remoteStoreEnabled": "${keycloak.connectionsInfinispan.remoteStoreEnabled:false}",
+ "remoteStoreHost": "${keycloak.connectionsInfinispan.remoteStoreServer:localhost}",
+ "remoteStorePort": "${keycloak.connectionsInfinispan.remoteStorePort:11222}",
+ "hotrodProtocolVersion": "${keycloak.connectionsInfinispan.hotrodProtocolVersion}"
+ }
+ },
+
+ "scripting": {
+ },
+
+ "jta-lookup": {
+ "provider": "${keycloak.jta.lookup.provider:jboss}",
+ "jboss" : {
+ "enabled": true
+ }
+
+ }
+}
diff --git a/quarkus/server/src/main/resources/META-INF/web.xml b/quarkus/server/src/main/resources/META-INF/web.xml
new file mode 100644
index 00000000000..87c43614aca
--- /dev/null
+++ b/quarkus/server/src/main/resources/META-INF/web.xml
@@ -0,0 +1,72 @@
+
+
+
+
+
+ auth
+
+
+ Keycloak REST Interface
+ org.jboss.resteasy.plugins.server.servlet.HttpServlet30Dispatcher
+
+ javax.ws.rs.Application
+ org.keycloak.services.resources.KeycloakApplication
+
+
+ resteasy.servlet.mapping.prefix
+ /
+
+ 1
+ true
+
+
+
+ resteasy.disable.html.sanitizer
+ true
+
+
+
+
+ org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap
+
+
+
+
+ org.keycloak.services.listeners.KeycloakSessionDestroyListener
+
+
+
+ Keycloak Session Management
+ org.keycloak.services.filters.KeycloakSessionServletFilter
+ true
+
+
+
+ Keycloak Session Management
+ /*
+
+
+
+ infinispan/Keycloak
+ org.infinispan.manager.EmbeddedCacheManager
+ java:jboss/infinispan/container/keycloak
+
+
diff --git a/quarkus/server/src/main/resources/application.properties b/quarkus/server/src/main/resources/application.properties
new file mode 100644
index 00000000000..c06cf26221b
--- /dev/null
+++ b/quarkus/server/src/main/resources/application.properties
@@ -0,0 +1,5 @@
+#quarkus.log.level = DEBUG
+
+quarkus.servlet.context-path = /auth
+
+resteasy.disable.html.sanitizer = true