<chapter id="server-installation">
    <title>Installation and Configuration of Keycloak Server</title>

    <para>
        The Keycloak Server has two downloadable distributions.
    </para>
    <para>
        <itemizedlist>

            <listitem>
                keycloak-&project.version;.zip
            </listitem>

            <listitem>
                keycloak-overlay-&project.version;.zip
            </listitem>

        </itemizedlist>

    </para>
    <section id="server_install">
        <title>Server Install</title>
        <para>
            The
            <literal>keycloak-&project.version;.zip</literal>
            is quite large, but contains a complete server (backed by Wildfly)
            that runs out of the box. The only thing you'll have to enable and configure is SSL. Unzipping it, the
            directory layout looks
            something like this:
        </para>

        <para>
<programlisting>
keycloak-&project.version;/
    bin/
        standalone.sh
        standalone.bat
        standalone/configuration/
            keycloak-server.json
            themes/
    docs/
</programlisting>
        </para>
        <para>
            The
            <literal>standalone.sh</literal>
            or
            <literal>standalone.bat</literal>
            script is used to start the server.
            After executing that, log into the admin console at<ulink
                url="http://localhost:8080/auth/admin/index.html">
            http://localhost:8080/auth/admin/index.html</ulink>.
            Username: <emphasis>admin</emphasis>
            Password: <emphasis>admin</emphasis>. Keycloak will then prompt you to
            enter in a new password.
        </para>
    </section>
    <section id="WAR_distribution_installation">
        <title>Server Overlay Installation</title>
        <para>
            The
            <literal>keycloak-overlay-&project.version;.zip</literal>
            contains
            just the bits you need to install keycloak on an existing WildFly 8.2.0.Final installation.
        </para>
        <para>
            The directory structure of this distro looks like this:
        </para>
        <para>
<programlisting>
   standalone/
        configuration/
            keycloak-server.json
            themes/
            providers/
    modules
    docs/
</programlisting>
        </para>
        <para>
            Unzip this archive into the root of your WildFly installation.
        </para>
        <para>
            After booting up the Wildfly distro, you can then make sure it is installed properly
            by logging into the admin console at<ulink
                url="http://localhost:8080/auth/admin/index.html">
            http://localhost:8080/auth/admin/index.html</ulink>.
            Username: <emphasis>admin</emphasis>
            Password: <emphasis>admin</emphasis>. Keycloak will then prompt you to
            enter in a new password.
        </para>
    </section>
    <section>
        <title id="configure-server">Configuring the Server</title>
        <para>
            Although the Keycloak Server is designed to run out of the box, there's some things you'll need
            to configure before you go into production.  Specifically:
            <itemizedlist>

                <listitem>
                    Configuring Keycloak to use a production database.
                </listitem>

                <listitem>
                    Setting up SSL/HTTPS
                </listitem>

                <listitem>
                    Enforcing HTTPS connections
                </listitem>
            </itemizedlist>
        </para>
        <section>
            <title>Relational Database Configuration</title>
            <para>
                You might want to use a better relational database for Keycloak like PostgreSQL or MySQL.  You might also
                want to tweak the configuration settings of the datasource.  Please see the <ulink url="https://docs.jboss.org/author/display/WFLY8/DataSource+configuration">Wildfly</ulink>
                documentation on how to do this.
            </para>
            <para>
                Keycloak runs on a Hibernate/JPA backend which is configured in the
                <literal>standalone/configuration/keycloak-server.json</literal>.
                By default the setting is like this:
                <programlisting><![CDATA[
"connectionsJpa": {
    "default": {
        "dataSource": "java:jboss/datasources/KeycloakDS",
        "databaseSchema": "update"
    }
},
]]></programlisting>
                Possible configuration options are:
                <variablelist>
                    <varlistentry>
                        <term>dataSource</term>
                        <listitem>
                            <para>
                                JNDI name of the dataSource
                            </para>
                        </listitem>
                    </varlistentry>
                    <varlistentry>
                        <term>jta</term>
                        <listitem>
                            <para>
                                boolean property to specify if datasource is JTA capable
                            </para>
                        </listitem>
                    </varlistentry>
                    <varlistentry>
                        <term>driverDialect</term>
                        <listitem>
                            <para>
                                Value of Hibernate dialect. In most cases you don't need to specify this property as dialect will be
                                autodetected by Hibernate.
                            </para>
                        </listitem>
                    </varlistentry>
                    <varlistentry>
                        <term>databaseSchema</term>
                        <listitem>
                            <para>
                                Value of database schema (Hibernate property "hibernate.hbm2ddl.auto" ).
                            </para>
                        </listitem>
                    </varlistentry>
                    <varlistentry>
                        <term>showSql</term>
                        <listitem>
                            <para>
                                Specify whether Hibernate should show all SQL commands in the console (false by default)
                            </para>
                        </listitem>
                    </varlistentry>
                    <varlistentry>
                        <term>formatSql</term>
                        <listitem>
                            <para>
                                Specify whether Hibernate should format SQL commands (true by default)
                            </para>
                        </listitem>
                    </varlistentry>
                    <varlistentry>
                        <term>unitName</term>
                        <listitem>
                            <para>
                                Allow you to specify name of persistence unit if you want to provide your own persistence.xml file for JPA configuration.
                                If this option is used, then all other configuration options are ignored as you are expected to configure
                                all JPA/DB properties in your own persistence.xml file. Hence you can remove properties "dataSource" and "databaseSchema" in this case.
                            </para>
                        </listitem>
                    </varlistentry>
                </variablelist>
                For more info about Hibernate properties, see <ulink url="http://hibernate.org/orm/documentation/">Hibernate and JPA documentation</ulink> .
            </para>
            <section>
                <title>Tested databases</title>
                <para>
                    Here is list of RDBMS databases and corresponding JDBC drivers, which were tested with Keycloak. Note that Hibernate dialect
                    is usually set automatically according to your database, but in some cases, you must manually set the proper dialect,
                    as the default dialect may not work correctly. You can setup dialect by adding property <literal>driverDialect</literal>
                    to the <literal>keycloak-server.json</literal> into <literal>connectionsJpa</literal> section (see above).
                    <table frame='all'><title>Tested databases</title>
                        <tgroup cols='3' align='left' colsep='1' rowsep='1'>
                            <thead>
                                <row>
                                    <entry>Database</entry>
                                    <entry>JDBC driver</entry>
                                    <entry>Hibernate Dialect</entry>
                                </row>
                            </thead>
                            <tbody>
                                <row>
                                    <entry>H2 1.3.161</entry>
                                    <entry>H2 1.3.161</entry>
                                    <entry>auto</entry>
                                </row>
                                <row>
                                    <entry>MySQL 5.5</entry>
                                    <entry>MySQL Connector/J 5.1.25</entry>
                                    <entry>auto</entry>
                                </row>
                                <row>
                                    <entry>PostgreSQL 9.2</entry>
                                    <entry>JDBC4 Postgresql Driver, Version 9.3-1100</entry>
                                    <entry>auto</entry>
                                </row>
                                <row>
                                    <entry>Oracle 11g R1</entry>
                                    <entry>Oracle JDBC Driver v11.1.0.7</entry>
                                    <entry>auto</entry>
                                </row>
                                <row>
                                    <entry>Microsoft SQL Server 2012</entry>
                                    <entry>Microsoft SQL Server JDBC Driver 4.0.2206.100</entry>
                                    <entry>org.hibernate.dialect.SQLServer2008Dialect</entry>
                                </row>
                                <row>
                                    <entry>Sybase ASE 15.7</entry>
                                    <entry>JDBC(TM)/7.07 ESD #5 (Build 26792)/P/EBF20686</entry>
                                    <entry>auto</entry>
                                </row>
                            </tbody>
                        </tgroup>
                    </table>
                </para>
            </section>
        </section>
        <section>
            <title>MongoDB based model</title>
            <para>
                Keycloak provides <ulink url="http://www.mongodb.com">MongoDB</ulink> based model implementation, which means that your identity data will be saved
                in MongoDB instead of traditional RDBMS. To configure Keycloak to use Mongo open <literal>standalone/configuration/keycloak-server.json</literal>
                in your favourite editor, then change:

<programlisting><![CDATA[
"eventsStore": {
    "provider": "jpa",
    "jpa": {
        "exclude-events": [ "REFRESH_TOKEN" ]
    }
},

"realm": {
    "provider": "jpa"
},

"user": {
    "provider": "${keycloak.user.provider:jpa}"
},
]]></programlisting>

                to:

                <programlisting><![CDATA[
"eventsStore": {
    "provider": "mongo",
    "mongo": {
        "exclude-events": [ "REFRESH_TOKEN" ]
    }
},

"realm": {
    "provider": "mongo"
},

"user": {
    "provider": "mongo"
},
]]></programlisting>

                And at the end of the file add the snippet like this where you can configure details about your Mongo database:
                <programlisting><![CDATA[
"connectionsMongo": {
    "default": {
        "host": "127.0.0.1",
        "port": "27017",
        "db": "keycloak",
        "connectionsPerHost": 100,
        "databaseSchema": "update"
    }
}
]]></programlisting>

                All configuration options are optional. Default values for host and port are localhost and 27017. Default name of database
                is <literal>keycloak</literal> . You can also specify properties <literal>user</literal> and <literal>password</literal>
                if you want authenticate against your MongoDB. If user and password are not specified, Keycloak will connect
                unauthenticated to your MongoDB.
            </para>
            <para>Finally there is set of optional configuration options, which can be used to specify connection-pooling capabilities of Mongo client. Supported int options are:
                <literal>connectionsPerHost</literal>, <literal>threadsAllowedToBlockForConnectionMultiplier</literal>, <literal>maxWaitTime</literal>, <literal>connectTimeout</literal>
                <literal>socketTimeout</literal>. Supported boolean options are: <literal>socketKeepAlive</literal>, <literal>autoConnectRetry</literal>.
                Supported long option is <literal>maxAutoConnectRetryTime</literal>. See <ulink url="http://api.mongodb.org/java/2.11.4/com/mongodb/MongoClientOptions.html">Mongo documentation</ulink>
                for details about those options and their default values.
            </para>
        </section>
        
        <section>
            <title>JSON File based model</title>
            <para>
                Keycloak provides a JSON file based model implementation, which means that your identity data will be saved
                in a flat JSON text file instead of traditional RDBMS.  The performance of this implementaion is likely to
                be slower because it reads and writes the entire file with each call to the Keycloak REST API.  But it is 
                very useful in development to see exactly what is being saved.  <emphasis>It is not recommended for 
                production.</emphasis>
            </para>
            <para>
                Note that this only applies to realm and user data.  There is currently no file implementation for
                event persistence.  So you will need to use JPA or Mongo for that.
            </para>
            <para>    
                To configure Keycloak to use file persistence open <literal>standalone/configuration/keycloak-server.json</literal>
                in your favourite editor.  Change the realm and user providers and disable caching.  Change:

<programlisting><![CDATA[
"realm": {
    "provider": "jpa"
},

"user": {
    "provider": "jpa"
},
    
"userSessions": {
    "provider" : "mem"
},
    
"realmCache": {
    "provider": "mem"
},

"userCache": {
    "provider": "mem",
    "mem": {
        "maxSize": 20000
    }
},
]]></programlisting>

                to:

                <programlisting><![CDATA[
"realm": {
    "provider": "file"
},

"user": {
    "provider": "file"
},
                    
"userSessions": {
    "provider" : "mem"
},
                    
"realmCache": {
    "provider": "none"
},

"userCache": {
    "provider": "none",
},
]]></programlisting>

You can also change the location of the data file by adding a connectionsFile snippet:<programlisting><![CDATA[
"connectionsFile": {
   "default" : {
        "directory": "/mydirectory",
        "fileName": "myfilename.json"
    }
}
]]></programlisting>

All configuration options are optional. Default value for directory is <literal>${jboss.server.data.dir}</literal>. Default file name
                is <literal>keycloak-model.json</literal>.
            </para>
        </section>

        <section id="ssl_modes">
            <title>SSL/HTTPS Requirement/Modes</title>
            <warning>
                <para>
                    Keycloak is not set up by default to handle SSL/HTTPS in either the
                    war distribution or appliance.  It is highly recommended that you either enable SSL on the Keycloak server
                    itself or on a reverse proxy in front of the Keycloak server.
                </para>
            </warning>
            <para>
                Keycloak can run out of the box without SSL so long as you stick to private IP addresses like
                localhost, 127.0.0.1, 10.0.x.x, 192.168.x.x, and 172..16.x.x.  If you try to access Keycloak from a
                non-IP adress you will get an error.
            </para>
            <para>
                Keycloak has 3 SSL/HTTPS modes which you can set up in the admin console under the Settings->Login page
                and the <literal>Require SSL</literal> select box.  Each adapter config should mirror this server-side
                setting.  See adapter config section for more details.
                <variablelist>
                    <varlistentry>
                        <term>external</term>
                        <listitem>
                            <para>
                                Keycloak can run out of the box without SSL so long as you stick to private IP addresses like
                                localhost, 127.0.0.1, 10.0.x.x, 192.168.x.x, and 172..16.x.x.  If you try to access Keycloak from a
                                non-IP adress you will get an error.
                            </para>
                        </listitem>
                    </varlistentry>
                    <varlistentry>
                        <term>none</term>
                        <listitem>
                            <para>
                                Keycloak does not require SSL.
                            </para>
                        </listitem>
                    </varlistentry>
                    <varlistentry>
                        <term>all</term>
                        <listitem>
                            <para>
                                Keycloak requires SSL for all IP addresses.
                            </para>
                        </listitem>
                    </varlistentry>
                </variablelist>
            </para>
        </section>
        <section>
            <title>SSL/HTTPS Setup</title>

            <para>
                First enable SSL on Keycloak or on a reverse proxy in front of Keycloak. Then configure the Keycloak Server to enforce HTTPS connections.
            </para>

            <section>
                <title>Enable SSL on Keycloak</title>
                <para>
                    The following things need to be done
                    <itemizedlist>

                        <listitem>
                            Generate a self signed or third-party signed certificate and import it into a Java keystore
                            using <literal>keytool</literal>.
                        </listitem>

                        <listitem>
                            Enable Wildfly to use this certificate and turn on SSL/HTTPS.
                        </listitem>
                    </itemizedlist>
                </para>
                <section>
                    <title>Creating the Certificate and Java Keystore</title>
                    <para>
                        In order to allow HTTPS connections, you need to obtain a self signed or third-party signed certificate
                        and import it into a Java keystore before you can enable HTTPS in the web container you are deploying
                        the Keycloak Server to.
                    </para>
                    <section>
                        <title>Self Signed Certificate</title>
                        <para>
                            In development, you will probably not have a third party signed certificate available to test
                            a Keycloak deployment so you'll need to generate a self-signed on.  Generate one is very easy
                            to do with the <literal>keytool</literal> utility that comes with the Java jdk.
                        </para>
                        <para>
    <programlisting>
    $ keytool -genkey -alias localhost -keyalg RSA -keystore keycloak.jks -validity 10950
        Enter keystore password: secret
        Re-enter new password: secret
        What is your first and last name?
        [Unknown]:  localhost
        What is the name of your organizational unit?
        [Unknown]:  Keycloak
        What is the name of your organization?
        [Unknown]:  Red Hat
        What is the name of your City or Locality?
        [Unknown]:  Westford
        What is the name of your State or Province?
        [Unknown]:  MA
        What is the two-letter country code for this unit?
        [Unknown]:  US
        Is CN=localhost, OU=Keycloak, O=Test, L=Westford, ST=MA, C=US correct?
        [no]:  yes
    </programlisting>
                        </para>
                        <para>
                            You should answer <literal>What is your first and last name ?</literal> question with
                            the DNS name of the machine you're installing the server on.  For testing purposes,
                            <literal>localhost</literal> should be used.  After executing this command, the
                            <literal>keycloak.jks</literal> file will be generated in the same directory as you executed
                            the <literal>keytool</literal> command in.
                        </para>
                        <para>
                            If you want a third-party signed certificate, but don't have one, you can obtain one for free
                            at <ulink url="http://cacert.org">cacert.org</ulink>.  You'll have to do a little set up first
                            before doing this though.
                        </para>
                        <para>
                            The first thing to do is generate a Certificate Request:
    <programlisting>
    $ keytool -certreq -alias yourdomain -keystore keycloak.jks > keycloak.careq
    </programlisting>
                        </para>
                        <para>
                             Where <literal>yourdomain</literal> is a DNS name for which this certificate is generated for.
                             Keytool generates the request:
    <programlisting>
    -----BEGIN NEW CERTIFICATE REQUEST-----
    MIIC2jCCAcICAQAwZTELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAk1BMREwDwYDVQQHEwhXZXN0Zm9y
    ZDEQMA4GA1UEChMHUmVkIEhhdDEQMA4GA1UECxMHUmVkIEhhdDESMBAGA1UEAxMJbG9jYWxob3N0
    MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr7kck2TaavlEOGbcpi9c0rncY4HhdzmY
    Ax2nZfq1eZEaIPqI5aTxwQZzzLDK9qbeAd8Ji79HzSqnRDxNYaZu7mAYhFKHgixsolE3o5Yfzbw1
    29Rvy+eUVe+WZxv5oo9wolVVpdSINIMEL2LaFhtX/c1dqiqYVpfnvFshZQaIg2nL8juzZcBjj4as
    H98gIS7khql/dkZKsw9NLvyxgJvp7PaXurX29fNf3ihG+oFrL22oFyV54BWWxXCKU/GPn61EGZGw
    Ft2qSIGLdctpMD1aJR2bcnlhEjZKDksjQZoQ5YMXaAGkcYkG6QkgrocDE2YXDbi7GIdf9MegVJ35
    2DQMpwIDAQABoDAwLgYJKoZIhvcNAQkOMSEwHzAdBgNVHQ4EFgQUQwlZJBA+fjiDdiVzaO9vrE/i
    n2swDQYJKoZIhvcNAQELBQADggEBAC5FRvMkhal3q86tHPBYWBuTtmcSjs4qUm6V6f63frhveWHf
    PzRrI1xH272XUIeBk0gtzWo0nNZnf0mMCtUBbHhhDcG82xolikfqibZijoQZCiGiedVjHJFtniDQ
    9bMDUOXEMQ7gHZg5q6mJfNG9MbMpQaUVEEFvfGEQQxbiFK7hRWU8S23/d80e8nExgQxdJWJ6vd0X
    MzzFK6j4Dj55bJVuM7GFmfdNC52pNOD5vYe47Aqh8oajHX9XTycVtPXl45rrWAH33ftbrS8SrZ2S
    vqIFQeuLL3BaHwpl3t7j2lMWcK1p80laAxEASib/fAwrRHpLHBXRcq6uALUOZl4Alt8=
    -----END NEW CERTIFICATE REQUEST-----
     </programlisting>
                        </para>
                        <para>
                            Send this ca request to your CA.  The CA will issue you a signed certificate and send it to you.
                            Before you import your new cert, you must obtain and import the root certificate of the CA.
                            You can download the cert from CA (ie.: root.crt) and import as follows:
    <programlisting>
    $ keytool -import -keystore keycloak.jks -file root.crt -alias root
    </programlisting>
                        </para>
                        <para>
                            Last step is import your new CA generated certificate to your keystore:
    <programlisting>
    $ keytool -import -alias yourdomain -keystore keycloak.jks -file your-certificate.cer
    </programlisting>
                        </para>
                    </section>
                </section>
                <section>
                    <title>Installing the keystore to WildFly</title>
                    <para>
                        Now that you have a Java keystore with the appropriate certificates, you need to configure your
                        Wildfly installation to use it.  First step is to move the keystore file to a directory
                        you can reference in configuration.  I like to put it in <literal>standalone/configuration</literal>.
                        Then you need to edit <literal>standalone/configuration/standalone.xml</literal> to enable SSL/HTTPS.
                    </para>
                    <para>
                        To the <literal>security-realms</literal> element add:
                        <programlisting><![CDATA[<security-realm name="UndertowRealm">
        <server-identities>
            <ssl>
                <keystore path="keycloak.jks" relative-to="jboss.server.config.dir" keystore-password="secret" />
            </ssl>
        </server-identities>
    </security-realm>]]></programlisting>
                    </para>
                    <para>
                        Find the element <literal>&lt;server name="default-server"&gt;</literal> (it's a child element of <literal>&lt;subsystem xmlns="urn:jboss:domain:undertow:1.0"&gt;</literal>) and add:
                        <programlisting><![CDATA[<https-listener name="https" socket-binding="https" security-realm="UndertowRealm"/>
    ]]></programlisting>
                    </para>
                    <para>
                        Check the <ulink url="https://docs.jboss.org/author/display/WFLY8/Undertow+(web)+subsystem+configuration">Wildfly Undertow</ulink> documentation for more information on fine tuning the socket connections.
                    </para>
                </section>
            </section>

            <section>
                <title>Enable SSL on a Reverse Proxy</title>
                <para>
                    Follow the documentation for your web server to enable SSL and configure reverse proxy for Keycloak.
                    It is important that you make sure the web server sets the <literal>X-Forwarded-For</literal> and
                    <literal>X-Forwarded-Proto</literal> headers on the requests made to Keycloak. Next you need to enable
                    <literal>proxy-address-forwarding</literal> on the Keycloak http connector. Assuming that your reverse
                    proxy doesn't use port 8443 for SSL you also need to configure what port http traffic is redirected to.
                </para>

                <section>
                    <title>Configure WildFly</title>

                    <para>
                        Open <literal>standalone/configuration/standalone.xml</literal> in your favorite editor.
                    </para>

                    <para>
                        First add <literal>proxy-address-forwarding</literal> and <literal>redirect-socket</literal> to
                        the <literal>http-listener</literal> element:
<programlisting><![CDATA[<subsystem xmlns="urn:jboss:domain:undertow:1.1">
    ...
    <http-listener name="default" socket-binding="http"
        proxy-address-forwarding="true" redirect-socket="proxy-https"/>
    ...
</subsystem>
]]></programlisting>
                    </para>
                    <para>
                        Then add a new <literal>socket-binding</literal> element to the <literal>socket-binding-group</literal> element:
<programlisting><![CDATA[
<socket-binding-group name="standard-sockets" default-interface="public"
    port-offset="${jboss.socket.binding.port-offset:0}">
    ...
    <socket-binding name="proxy-https" port="443"/>
    ...
</socket-binding-group>
]]></programlisting>
                    </para>
                    <para>
                        Check the <ulink url="https://docs.jboss.org/author/display/WFLY8/Undertow+(web)+subsystem+configuration">WildFly</ulink> documentation for more information.
                    </para>
                </section>
            </section>

        </section>

    </section>

    <section>
        <title>Adding Keycloak server in Domain Mode</title>
        <para>
            In domain mode, you start the server with the "domain" command instead of the "standalone" command.  In this case, the Keycloak subsystem is
            defined in domain/configuration/domain.xml instead of standalone/configuration.standalone.xml.  Inside domain.xml, you will see more than one
            profile.  A Keycloak subsystem can be defined in zero or more of those profiles.
        </para>
        <para>
            To enable Keycloak for a server profile edit domain/configuration/domain.xml. To the <literal>extensions</literal>
            element add the Keycloak extension:
<programlisting><![CDATA[
<extensions>
    ...
    <extension module="org.keycloak.keycloak-subsystem"/>
</extensions>
]]></programlisting>
            Then you need to add the server to the required server profiles. By default WildFly starts two servers
            in the main-server-group which uses the full profile. To add Keycloak for this profile add the Keycloak
            subsystem to the <literal>profile</literal> element with <literal>name</literal> full:
<programlisting><![CDATA[
<profile name="full">
    ...
    <subsystem xmlns="urn:jboss:domain:keycloak:1.0">
        <auth-server name="main-auth-server">
            <enabled>true</enabled>
            <web-context>auth</web-context>
        </auth-server>
    </subsystem>
]]></programlisting>
        </para>
        <para>
            To configure the server copy <literal>standalone/configuration/keycloak-server.json</literal> to
            <literal>domain/servers/&lt;SERVER NAME&gt;/configuration</literal>. The configuration should be identical
            for all servers in a group.
        </para>
        <para>
            Follow the <link linkend='clustering'>Clustering</link> section of the documentation to configure Keycloak
            for clustering. In domain mode it doesn't make much sense to not configure Keycloak in cluster mode.
        </para>
        <para>
            To deploy custom providers and themes you should deploys these as modules and make sure the modules are
            available to all servers in the group. See <link linkend='providers'>Providers</link> and
            <link linkend='themes'>Themes</link> sections for more information on how to do this.
        </para>
    </section>
    
    <section>
        <title>Installing Keycloak Server as Root Context</title>
        <para>
            The Keycloak server can be installed as the default web application.  This way, instead of referencing
            the server as <literal>http://mydomain.com/auth</literal>, it would be 
            <literal>http://mydomain.com/</literal>.
        </para>
        <para>
            To do this, you need to add a <literal>default-web-module</literal> attribute in the Undertow subystem in standalone.xml.
            <programlisting><![CDATA[
<subsystem xmlns="urn:jboss:domain:undertow:1.2">
            <server name="default-server">
                <host name="default-host" alias="localhost" default-web-module="main-auth-server.war">
                    <location name="/" handler="welcome-content"/>
                </host>
]]></programlisting>
        </para>
        <para>
            <literal>main-auth-server</literal> is the name of the Keycloak server as defined in the Keycloak subsystem.
        </para>
        <para>
             <note>
                 If you have already run your server before changing to the root context then your database
                 will contain references to the old /auth context.  And, your clients may also have incorrect
                 references.  To fix this on the server side, you will need to <link linkend="export-import">export 
                 your database to json, make corrections, and then import.</link>  Client-side keycloak.json 
                 files will need to be updated manually as well.
             </note>
        </para>
        
    </section>
</chapter>
