diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..56bb82246df01d722b7830373e5985a322f6021e
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,62 @@
+
+### JetBrains template
+# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
+# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
+
+# User-specific stuff
+.idea/**/workspace.xml
+.idea/**/tasks.xml
+.idea/**/usage.statistics.xml
+.idea/**/dictionaries
+.idea/**/shelf
+
+# Sensitive or high-churn files
+.idea/**/dataSources/
+.idea/**/dataSources.ids
+.idea/**/dataSources.local.xml
+.idea/**/sqlDataSources.xml
+.idea/**/dynamic.xml
+.idea/**/uiDesigner.xml
+.idea/**/dbnavigator.xml
+
+# Gradle
+.idea/**/gradle.xml
+.idea/**/libraries
+
+# Gradle and Maven with auto-import
+# When using Gradle or Maven with auto-import, you should exclude module files,
+# since they will be recreated, and may cause churn.  Uncomment if using
+# auto-import.
+# .idea/modules.xml
+# .idea/*.iml
+# .idea/modules
+
+# CMake
+cmake-build-*/
+
+# Mongo Explorer plugin
+.idea/**/mongoSettings.xml
+
+# File-based project format
+*.iws
+
+# IntelliJ
+out/
+
+# mpeltonen/sbt-idea plugin
+.idea_modules/
+
+# JIRA plugin
+atlassian-ide-plugin.xml
+
+# Cursive Clojure plugin
+.idea/replstate.xml
+
+# Crashlytics plugin (for Android Studio and IntelliJ)
+com_crashlytics_export_strings.xml
+crashlytics.properties
+crashlytics-build.properties
+fabric.properties
+
+# Editor-based Rest Client
+.idea/httpRequests
diff --git a/.idea/Config.iml b/.idea/Config.iml
new file mode 100644
index 0000000000000000000000000000000000000000..ec3d41d41bce394ebf0eddfc367ef135fca9652c
--- /dev/null
+++ b/.idea/Config.iml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="JAVA_MODULE" version="4">
+  <component name="FacetManager">
+    <facet type="Python" name="Python">
+      <configuration sdkName="" />
+    </facet>
+  </component>
+  <component name="NewModuleRootManager">
+    <content url="file://$MODULE_DIR$" />
+    <orderEntry type="jdk" jdkName="Python 3.6 (venv)" jdkType="Python SDK" />
+    <orderEntry type="sourceFolder" forTests="false" />
+  </component>
+</module>
\ No newline at end of file
diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
new file mode 100644
index 0000000000000000000000000000000000000000..30aa626c23142d59e94cc76327172301f159b618
--- /dev/null
+++ b/.idea/codeStyles/Project.xml
@@ -0,0 +1,29 @@
+<component name="ProjectCodeStyleConfiguration">
+  <code_scheme name="Project" version="173">
+    <Objective-C-extensions>
+      <file>
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import" />
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Macro" />
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Typedef" />
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Enum" />
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Constant" />
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Global" />
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Struct" />
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="FunctionPredecl" />
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Function" />
+      </file>
+      <class>
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Property" />
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Synthesize" />
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InitMethod" />
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="StaticMethod" />
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InstanceMethod" />
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="DeallocMethod" />
+      </class>
+      <extensions>
+        <pair source="cpp" header="h" fileNamingConvention="NONE" />
+        <pair source="c" header="h" fileNamingConvention="NONE" />
+      </extensions>
+    </Objective-C-extensions>
+  </code_scheme>
+</component>
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000000000000000000000000000000000000..4994d04f3c74bbfcbc6109f586d4a592bb792074
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="JavaScriptSettings">
+    <option name="languageLevel" value="ES6" />
+  </component>
+  <component name="ProjectRootManager" version="2" project-jdk-name="Python 3.6 (venv)" project-jdk-type="Python SDK" />
+</project>
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000000000000000000000000000000000000..7423bb5a8f9cbb3bd8c293f806699f6e607f0ba0
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectModuleManager">
+    <modules>
+      <module fileurl="file://$PROJECT_DIR$/.idea/Config.iml" filepath="$PROJECT_DIR$/.idea/Config.iml" />
+    </modules>
+  </component>
+</project>
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000000000000000000000000000000000000..35eb1ddfbbc029bcab630581847471d7f238ec53
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="VcsDirectoryMappings">
+    <mapping directory="" vcs="Git" />
+  </component>
+</project>
\ No newline at end of file
diff --git a/README.md b/README.md
deleted file mode 100644
index fc011986395a4196f32fd2c44d5a73f4100e4b88..0000000000000000000000000000000000000000
--- a/README.md
+++ /dev/null
@@ -1,2 +0,0 @@
-# Config
-
diff --git a/config/jenkins/config.xml b/config/jenkins/config.xml
new file mode 100644
index 0000000000000000000000000000000000000000..32ececed6cbde1041f6b8f4150a34a4d7bb793d8
--- /dev/null
+++ b/config/jenkins/config.xml
@@ -0,0 +1,174 @@
+<?xml version='1.1' encoding='UTF-8'?>
+<hudson>
+  <disabledAdministrativeMonitors>
+    <string>jenkins.security.csrf.CSRFAdministrativeMonitor</string>
+  </disabledAdministrativeMonitors>
+  <version>2.121.2</version>
+  <installStateName>RESTART</installStateName>
+  <numExecutors>5</numExecutors>
+  <mode>NORMAL</mode>
+  <useSecurity>true</useSecurity>
+  <authorizationStrategy class="hudson.security.ProjectMatrixAuthorizationStrategy">
+    <permission>hudson.model.Hudson.Administer:{USERNAME}</permission>
+    <permission>hudson.model.Hudson.Administer:api</permission>
+    <permission>hudson.model.Hudson.Read:authenticated</permission>
+  </authorizationStrategy>
+  <securityRealm class="org.jenkinsci.plugins.oic.OicSecurityRealm" plugin="oic-auth@1.4">
+    <clientId>jenkins</clientId>
+    <clientSecret>{SECRET}</clientSecret>
+    <tokenServerUrl>{TOKEN_URL}</tokenServerUrl>
+    <authorizationServerUrl>{AUTH_URL}</authorizationServerUrl>
+    <userInfoServerUrl>{USERINFO_URL}</userInfoServerUrl>
+    <userNameField>preferred_username</userNameField>
+    <fullNameFieldName>fullName</fullNameFieldName>
+    <emailFieldName>email</emailFieldName>
+    <scopes>openid email</scopes>
+    <disableSslVerification>true</disableSslVerification>
+    <logoutFromOpenidProvider>true</logoutFromOpenidProvider>
+    <endSessionUrl>{LOGOUT_URL}</endSessionUrl>
+    <postLogoutRedirectUrl>{REDIRECT_URL}</postLogoutRedirectUrl>
+    <escapeHatchEnabled>false</escapeHatchEnabled>
+    <escapeHatchSecret>{AQAAABAAAAAQNBX0MHf+isIai4/5rlJTx3BKlSMH8wpGhqrqiubN2D4=}</escapeHatchSecret>
+  </securityRealm>
+  <disableRememberMe>false</disableRememberMe>
+  <projectNamingStrategy class="jenkins.model.ProjectNamingStrategy$DefaultProjectNamingStrategy"/>
+  <workspaceDir>${ITEM_ROOTDIR}/workspace</workspaceDir>
+  <buildsDir>${ITEM_ROOTDIR}/builds</buildsDir>
+  <markupFormatter class="hudson.markup.EscapedMarkupFormatter"/>
+  <jdks/>
+  <viewsTabBar class="hudson.views.DefaultViewsTabBar"/>
+  <myViewsTabBar class="hudson.views.DefaultMyViewsTabBar"/>
+  <clouds>
+    <org.csanchez.jenkins.plugins.kubernetes.KubernetesCloud plugin="kubernetes@1.12.2">
+      <name>openshift</name>
+      <templates>
+        <org.csanchez.jenkins.plugins.kubernetes.PodTemplate>
+          <inheritFrom></inheritFrom>
+          <name>maven</name>
+          <privileged>false</privileged>
+          <capOnlyOnAlivePods>false</capOnlyOnAlivePods>
+          <alwaysPullImage>false</alwaysPullImage>
+          <instanceCap>2147483647</instanceCap>
+          <slaveConnectTimeout>0</slaveConnectTimeout>
+          <idleMinutes>0</idleMinutes>
+          <activeDeadlineSeconds>0</activeDeadlineSeconds>
+          <label>maven</label>
+          <serviceAccount>jenkins</serviceAccount>
+          <nodeSelector></nodeSelector>
+          <customWorkspaceVolumeEnabled>false</customWorkspaceVolumeEnabled>
+          <volumes/>
+          <containers>
+            <org.csanchez.jenkins.plugins.kubernetes.ContainerTemplate>
+              <name>jnlp</name>
+              <image>docker.io/openshift/jenkins-agent-maven-35-centos7:v3.11</image>
+              <privileged>false</privileged>
+              <alwaysPullImage>true</alwaysPullImage>
+              <workingDir>/tmp</workingDir>
+              <command></command>
+              <args>${computer.jnlpmac} ${computer.name}</args>
+              <ttyEnabled>false</ttyEnabled>
+              <resourceRequestCpu></resourceRequestCpu>
+              <resourceRequestMemory></resourceRequestMemory>
+              <resourceLimitCpu></resourceLimitCpu>
+              <resourceLimitMemory></resourceLimitMemory>
+              <envVars/>
+            </org.csanchez.jenkins.plugins.kubernetes.ContainerTemplate>
+          </containers>
+          <envVars/>
+          <annotations/>
+          <imagePullSecrets/>
+        </org.csanchez.jenkins.plugins.kubernetes.PodTemplate>
+        <org.csanchez.jenkins.plugins.kubernetes.PodTemplate>
+          <inheritFrom></inheritFrom>
+          <name>nodejs</name>
+          <privileged>false</privileged>
+          <capOnlyOnAlivePods>false</capOnlyOnAlivePods>
+          <alwaysPullImage>false</alwaysPullImage>
+          <instanceCap>2147483647</instanceCap>
+          <slaveConnectTimeout>0</slaveConnectTimeout>
+          <idleMinutes>0</idleMinutes>
+          <activeDeadlineSeconds>0</activeDeadlineSeconds>
+          <label>nodejs</label>
+          <serviceAccount>jenkins</serviceAccount>
+          <nodeSelector></nodeSelector>
+          <customWorkspaceVolumeEnabled>false</customWorkspaceVolumeEnabled>
+          <volumes/>
+          <containers>
+            <org.csanchez.jenkins.plugins.kubernetes.ContainerTemplate>
+              <name>jnlp</name>
+              <image>docker.io/openshift/jenkins-agent-nodejs-8-centos7:v3.11</image>
+              <privileged>false</privileged>
+              <alwaysPullImage>true</alwaysPullImage>
+              <workingDir>/tmp</workingDir>
+              <command></command>
+              <args>${computer.jnlpmac} ${computer.name}</args>
+              <ttyEnabled>false</ttyEnabled>
+              <resourceRequestCpu></resourceRequestCpu>
+              <resourceRequestMemory></resourceRequestMemory>
+              <resourceLimitCpu></resourceLimitCpu>
+              <resourceLimitMemory></resourceLimitMemory>
+              <envVars/>
+            </org.csanchez.jenkins.plugins.kubernetes.ContainerTemplate>
+          </containers>
+          <envVars/>
+          <annotations/>
+          <imagePullSecrets/>
+        </org.csanchez.jenkins.plugins.kubernetes.PodTemplate>
+      </templates>
+      <serverUrl>https://172.30.0.1:443</serverUrl>
+      <serverCertificate>-----BEGIN CERTIFICATE-----
+MIIC6jCCAdKgAwIBAgIBATANBgkqhkiG9w0BAQsFADAmMSQwIgYDVQQDDBtvcGVu
+c2hpZnQtc2lnbmVyQDE1MzIyODU2NTUwHhcNMTgwNzIyMTg1NDE0WhcNMjMwNzIx
+MTg1NDE1WjAmMSQwIgYDVQQDDBtvcGVuc2hpZnQtc2lnbmVyQDE1MzIyODU2NTUw
+ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCpkkLXsvxCbu6SYGFpKMv/
+hYxwbY5Eai9pZf+2iL4TEtqF+hrwCgOB4oXZ+0LLcaszbbEqrKRSAbkJoeXFafii
+7IUAH02zOC7B9j3d6gTiNMJ/3Q0AjuP37bOXvjDAKaspzB2YYv3Tn/R/0Tm/qprt
+bxBxbbBBcvwkYpKbMOqtCRqv+y1WZCBVIBKRrJ89JZLn/NO3j49bHczuDPcG2qM+
+2cfTfmpdarwsoXN5OKBOGbFuQ/IaNxBqXzJCMCRHYk7r+Ug3Z1Z2WxVLjrhyvUjX
+Whk0bISWsBAQkoJbT67BeUOZ7JzgsGsHS8l8fZ948fyLyD3WpJNf0vRyz7gz5XRf
+AgMBAAGjIzAhMA4GA1UdDwEB/wQEAwICpDAPBgNVHRMBAf8EBTADAQH/MA0GCSqG
+SIb3DQEBCwUAA4IBAQAb7Rm6tvkfT1biT4uiaEzy43M/p3HEqyHc6B0t2kvOsgbD
+FjEc1lL+kbEZiWForTV19hp8VDSa3RH+9Z00+Zi8AXyRj6smdsA1TSlfn8hR55q2
+gy0JvY+z4yWN1nbOj2uj1ZVv15NCXl6UiEbV4cDq/7a3AKOM1FeOlzFQLfDPQmqA
+Or+FzCmb9qcC/4g7WyDSm8XUJljRtKFVFZdnSW1LIS18kJ+sWUqjYmJ0OP9b7q5G
+9yu4OhNe7pilJspYV+3V6wHvPblmxu3zdwTk/ELqI4dN/Llz0kRT7Ez258nAd4zo
+pO077lGdsifbJTjmMbrkOzW2o8knqjhV1ERrWT+4
+-----END CERTIFICATE-----</serverCertificate>
+      <skipTlsVerify>false</skipTlsVerify>
+      <addMasterProxyEnvVars>true</addMasterProxyEnvVars>
+      <capOnlyOnAlivePods>false</capOnlyOnAlivePods>
+      <namespace>test1</namespace>
+      <jenkinsUrl>http://172.30.26.218:80</jenkinsUrl>
+      <jenkinsTunnel>172.30.143.141:50000</jenkinsTunnel>
+      <credentialsId>1a12dfa4-7fc5-47a7-aa17-cc56572a41c7</credentialsId>
+      <containerCap>100</containerCap>
+      <retentionTimeout>5</retentionTimeout>
+      <connectTimeout>0</connectTimeout>
+      <readTimeout>0</readTimeout>
+      <usageRestricted>false</usageRestricted>
+      <maxRequestsPerHost>32</maxRequestsPerHost>
+      <podRetention class="org.csanchez.jenkins.plugins.kubernetes.pod.retention.Never"/>
+    </org.csanchez.jenkins.plugins.kubernetes.KubernetesCloud>
+  </clouds>
+  <quietPeriod>1</quietPeriod>
+  <scmCheckoutRetryCount>0</scmCheckoutRetryCount>
+  <views>
+    <hudson.model.AllView>
+      <owner class="hudson" reference="../../.."/>
+      <name>all</name>
+      <filterExecutors>false</filterExecutors>
+      <filterQueue>false</filterQueue>
+      <properties/>
+    </hudson.model.AllView>
+  </views>
+  <primaryView>all</primaryView>
+  <slaveAgentPort>50000</slaveAgentPort>
+  <disabledAgentProtocols>
+    <string>JNLP-connect</string>
+    <string>JNLP2-connect</string>
+  </disabledAgentProtocols>
+  <label>master</label>
+  <nodeProperties/>
+  <globalNodeProperties/>
+  <noUsageStatistics>true</noUsageStatistics>
+</hudson>
\ No newline at end of file
diff --git a/config/sso/jenkins.json b/config/sso/jenkins.json
new file mode 100644
index 0000000000000000000000000000000000000000..857a05371b9755eeaa2a5166096b40e4362d6c2f
--- /dev/null
+++ b/config/sso/jenkins.json
@@ -0,0 +1,132 @@
+{
+    "clientId": "jenkins",
+    "rootUrl": "https://{DOMAIN}/",
+    "adminUrl": "https://{DOMAIN}/",
+    "baseUrl": "https://{DOMAIN}/",
+    "surrogateAuthRequired": false,
+    "enabled": true,
+    "clientAuthenticatorType": "client-secret",
+    "redirectUris": [
+        "https://{DOMAIN}/*"
+    ],
+    "webOrigins": [
+        "https://{DOMAIN}"
+    ],
+    "notBefore": 0,
+    "bearerOnly": false,
+    "consentRequired": false,
+    "standardFlowEnabled": true,
+    "implicitFlowEnabled": false,
+    "directAccessGrantsEnabled": false,
+    "serviceAccountsEnabled": false,
+    "publicClient": false,
+    "frontchannelLogout": false,
+    "protocol": "openid-connect",
+    "attributes": {
+        "saml.assertion.signature": "false",
+        "saml.multivalued.roles": "false",
+        "saml.force.post.binding": "false",
+        "saml.encrypt": "false",
+        "saml_force_name_id_format": "false",
+        "saml.client.signature": "false",
+        "saml.authnstatement": "false",
+        "saml.server.signature": "false",
+        "saml.server.signature.keyinfo.ext": "false",
+        "saml.onetimeuse.condition": "false",
+        "exclude.session.state.from.auth.response": "false"
+    },
+    "fullScopeAllowed": true,
+    "nodeReRegistrationTimeout": -1,
+    "protocolMappers": [
+        {
+            "name": "family name",
+            "protocol": "openid-connect",
+            "protocolMapper": "oidc-usermodel-property-mapper",
+            "consentRequired": true,
+            "consentText": "${familyName}",
+            "config": {
+                "userinfo.token.claim": "true",
+                "user.attribute": "lastName",
+                "id.token.claim": "true",
+                "access.token.claim": "true",
+                "claim.name": "family_name",
+                "jsonType.label": "String"
+            }
+        },
+        {
+            "name": "email",
+            "protocol": "openid-connect",
+            "protocolMapper": "oidc-usermodel-property-mapper",
+            "consentRequired": true,
+            "consentText": "${email}",
+            "config": {
+                "userinfo.token.claim": "true",
+                "user.attribute": "email",
+                "id.token.claim": "true",
+                "access.token.claim": "true",
+                "claim.name": "email",
+                "jsonType.label": "String"
+            }
+        },
+        {
+            "name": "role list",
+            "protocol": "saml",
+            "protocolMapper": "saml-role-list-mapper",
+            "consentRequired": false,
+            "config": {
+                "single": "false",
+                "attribute.nameformat": "Basic",
+                "attribute.name": "Role"
+            }
+        },
+        {
+            "name": "username",
+            "protocol": "openid-connect",
+            "protocolMapper": "oidc-usermodel-property-mapper",
+            "consentRequired": true,
+            "consentText": "${username}",
+            "config": {
+                "userinfo.token.claim": "true",
+                "user.attribute": "username",
+                "id.token.claim": "true",
+                "access.token.claim": "true",
+                "claim.name": "preferred_username",
+                "jsonType.label": "String"
+            }
+        },
+        {
+            "name": "given name",
+            "protocol": "openid-connect",
+            "protocolMapper": "oidc-usermodel-property-mapper",
+            "consentRequired": true,
+            "consentText": "${givenName}",
+            "config": {
+                "userinfo.token.claim": "true",
+                "user.attribute": "firstName",
+                "id.token.claim": "true",
+                "access.token.claim": "true",
+                "claim.name": "given_name",
+                "jsonType.label": "String"
+            }
+        },
+        {
+            "name": "full name",
+            "protocol": "openid-connect",
+            "protocolMapper": "oidc-full-name-mapper",
+            "consentRequired": true,
+            "consentText": "${fullName}",
+            "config": {
+                "id.token.claim": "true",
+                "access.token.claim": "true"
+            }
+        }
+    ],
+    "useTemplateConfig": false,
+    "useTemplateScope": false,
+    "useTemplateMappers": false,
+    "access": {
+        "view": true,
+        "configure": true,
+        "manage": true
+    }
+}
\ No newline at end of file
diff --git a/config/sso/opensubmit.json b/config/sso/opensubmit.json
new file mode 100644
index 0000000000000000000000000000000000000000..53af07d94ce0bc6c05dc1e9dcce97802819d2cf4
--- /dev/null
+++ b/config/sso/opensubmit.json
@@ -0,0 +1,134 @@
+{
+    "clientId": "opensubmit",
+    "rootUrl": "https://{DOMAIN}/",
+    "adminUrl": "https://{DOMAIN}/",
+    "baseUrl": "https://{DOMAIN}/",
+    "surrogateAuthRequired": false,
+    "enabled": true,
+    "clientAuthenticatorType": "client-secret",
+    "redirectUris": [
+        "http://{DOMAIN}/*",
+        "https://{DOMAIN}/*"
+    ],
+    "webOrigins": [
+        "https://{DOMAIN}"
+    ],
+    "notBefore": 0,
+    "bearerOnly": false,
+    "consentRequired": false,
+    "standardFlowEnabled": true,
+    "implicitFlowEnabled": false,
+    "directAccessGrantsEnabled": false,
+    "serviceAccountsEnabled": false,
+    "publicClient": false,
+    "frontchannelLogout": false,
+    "protocol": "openid-connect",
+    "attributes": {
+        "saml.assertion.signature": "false",
+        "saml.force.post.binding": "false",
+        "saml.multivalued.roles": "false",
+        "saml.encrypt": "false",
+        "saml_force_name_id_format": "false",
+        "saml.client.signature": "false",
+        "saml.authnstatement": "false",
+        "saml.server.signature": "false",
+        "saml.server.signature.keyinfo.ext": "false",
+        "exclude.session.state.from.auth.response": "false",
+        "saml.onetimeuse.condition": "false"
+    },
+    "fullScopeAllowed": true,
+    "nodeReRegistrationTimeout": -1,
+    "protocolMappers": [
+        {
+            "name": "email",
+            "protocol": "openid-connect",
+            "protocolMapper": "oidc-usermodel-property-mapper",
+            "consentRequired": true,
+            "consentText": "${email}",
+            "config": {
+                "userinfo.token.claim": "true",
+                "user.attribute": "email",
+                "id.token.claim": "true",
+                "access.token.claim": "true",
+                "claim.name": "email",
+                "jsonType.label": "String"
+            }
+        },
+        {
+            "name": "role list",
+            "protocol": "saml",
+            "protocolMapper": "saml-role-list-mapper",
+            "consentRequired": false,
+            "config": {
+                "single": "false",
+                "attribute.nameformat": "Basic",
+                "attribute.name": "Role"
+            }
+        },
+        {
+            "name": "username",
+            "protocol": "openid-connect",
+            "protocolMapper": "oidc-usermodel-property-mapper",
+            "consentRequired": true,
+            "consentText": "${username}",
+            "config": {
+                "userinfo.token.claim": "true",
+                "user.attribute": "username",
+                "id.token.claim": "true",
+                "access.token.claim": "true",
+                "claim.name": "preferred_username",
+                "jsonType.label": "String"
+            }
+        },
+        {
+            "name": "family name",
+            "protocol": "openid-connect",
+            "protocolMapper": "oidc-usermodel-property-mapper",
+            "consentRequired": true,
+            "consentText": "${familyName}",
+            "config": {
+                "userinfo.token.claim": "true",
+                "user.attribute": "lastName",
+                "id.token.claim": "true",
+                "access.token.claim": "true",
+                "claim.name": "family_name",
+                "jsonType.label": "String"
+            }
+        },
+        {
+            "name": "given name",
+            "protocol": "openid-connect",
+            "protocolMapper": "oidc-usermodel-property-mapper",
+            "consentRequired": true,
+            "consentText": "${givenName}",
+            "config": {
+                "userinfo.token.claim": "true",
+                "user.attribute": "firstName",
+                "id.token.claim": "true",
+                "access.token.claim": "true",
+                "claim.name": "given_name",
+                "jsonType.label": "String"
+            }
+        },
+        {
+            "name": "full name",
+            "protocol": "openid-connect",
+            "protocolMapper": "oidc-full-name-mapper",
+            "consentRequired": true,
+            "consentText": "${fullName}",
+            "config": {
+                "id.token.claim": "true",
+                "access.token.claim": "true",
+                "userinfo.token.claim": "true"
+            }
+        }
+    ],
+    "useTemplateConfig": false,
+    "useTemplateScope": false,
+    "useTemplateMappers": false,
+    "access": {
+        "view": true,
+        "configure": true,
+        "manage": true
+    }
+}
\ No newline at end of file
diff --git a/config/sso/realm-export.json b/config/sso/realm-export.json
new file mode 100644
index 0000000000000000000000000000000000000000..b89fc451e4a1b4492b7a2f657f6ffa9b4422092f
--- /dev/null
+++ b/config/sso/realm-export.json
@@ -0,0 +1,866 @@
+{
+  "id": "hda",
+  "realm": "hda",
+  "displayNameHtml": "Hochschule Darmstadt",
+  "notBefore": 0,
+  "revokeRefreshToken": false,
+  "refreshTokenMaxReuse": 0,
+  "accessTokenLifespan": 300,
+  "accessTokenLifespanForImplicitFlow": 900,
+  "ssoSessionIdleTimeout": 1800,
+  "ssoSessionMaxLifespan": 36000,
+  "offlineSessionIdleTimeout": 2592000,
+  "accessCodeLifespan": 60,
+  "accessCodeLifespanUserAction": 300,
+  "accessCodeLifespanLogin": 1800,
+  "actionTokenGeneratedByAdminLifespan": 43200,
+  "actionTokenGeneratedByUserLifespan": 300,
+  "enabled": true,
+  "sslRequired": "external",
+  "registrationAllowed": false,
+  "registrationEmailAsUsername": false,
+  "rememberMe": false,
+  "verifyEmail": false,
+  "loginWithEmailAllowed": false,
+  "duplicateEmailsAllowed": false,
+  "resetPasswordAllowed": false,
+  "editUsernameAllowed": false,
+  "bruteForceProtected": false,
+  "permanentLockout": false,
+  "maxFailureWaitSeconds": 900,
+  "minimumQuickLoginWaitSeconds": 60,
+  "waitIncrementSeconds": 60,
+  "quickLoginCheckMilliSeconds": 1000,
+  "maxDeltaTimeSeconds": 43200,
+  "failureFactor": 30,
+  "defaultRoles": [
+    "offline_access",
+    "uma_authorization"
+  ],
+  "requiredCredentials": [
+    "password"
+  ],
+  "otpPolicyType": "totp",
+  "otpPolicyAlgorithm": "HmacSHA1",
+  "otpPolicyInitialCounter": 0,
+  "otpPolicyDigits": 6,
+  "otpPolicyLookAheadWindow": 1,
+  "otpPolicyPeriod": 30,
+  "otpSupportedApplications": [
+    "FreeOTP",
+    "Google Authenticator"
+  ],
+  "clientTemplates": [],
+  "browserSecurityHeaders": {
+    "xContentTypeOptions": "nosniff",
+    "xRobotsTag": "none",
+    "xFrameOptions": "SAMEORIGIN",
+    "xXSSProtection": "1; mode=block",
+    "contentSecurityPolicy": "frame-src 'self'; frame-ancestors 'self'; object-src 'none';",
+    "strictTransportSecurity": "max-age=31536000; includeSubDomains"
+  },
+  "smtpServer": {},
+  "eventsEnabled": false,
+  "eventsListeners": [
+    "jboss-logging"
+  ],
+  "enabledEventTypes": [],
+  "adminEventsEnabled": false,
+  "adminEventsDetailsEnabled": false,
+  "components": {
+    "org.keycloak.services.clientregistration.policy.ClientRegistrationPolicy": [
+      {
+        "id": "fd123d70-81a6-49d1-a651-6698805cde54",
+        "name": "Allowed Client Templates",
+        "providerId": "allowed-client-templates",
+        "subType": "anonymous",
+        "subComponents": {},
+        "config": {}
+      },
+      {
+        "id": "45670c55-5a70-4286-a1a0-912334f57755",
+        "name": "Full Scope Disabled",
+        "providerId": "scope",
+        "subType": "anonymous",
+        "subComponents": {},
+        "config": {}
+      },
+      {
+        "id": "df732938-a752-4ca5-9c0c-1a89fdf8f519",
+        "name": "Allowed Client Templates",
+        "providerId": "allowed-client-templates",
+        "subType": "authenticated",
+        "subComponents": {},
+        "config": {}
+      },
+      {
+        "id": "bbc22b53-9694-4c24-81c2-2c70948e14e0",
+        "name": "Consent Required",
+        "providerId": "consent-required",
+        "subType": "anonymous",
+        "subComponents": {},
+        "config": {}
+      },
+      {
+        "id": "39a84cb1-3b0e-4bec-9125-36cee3fda5aa",
+        "name": "Trusted Hosts",
+        "providerId": "trusted-hosts",
+        "subType": "anonymous",
+        "subComponents": {},
+        "config": {
+          "host-sending-registration-request-must-match": [
+            "true"
+          ],
+          "client-uris-must-match": [
+            "true"
+          ]
+        }
+      },
+      {
+        "id": "05edee15-f912-4ac8-add1-84a0072594d9",
+        "name": "Max Clients Limit",
+        "providerId": "max-clients",
+        "subType": "anonymous",
+        "subComponents": {},
+        "config": {
+          "max-clients": [
+            "200"
+          ]
+        }
+      },
+      {
+        "id": "f3056006-1b4e-42af-ad7a-35338a5167ea",
+        "name": "Allowed Protocol Mapper Types",
+        "providerId": "allowed-protocol-mappers",
+        "subType": "authenticated",
+        "subComponents": {},
+        "config": {
+          "allowed-protocol-mapper-types": [
+            "oidc-address-mapper",
+            "oidc-sha256-pairwise-sub-mapper",
+            "oidc-usermodel-attribute-mapper",
+            "saml-user-property-mapper",
+            "oidc-full-name-mapper",
+            "saml-role-list-mapper",
+            "saml-user-attribute-mapper",
+            "oidc-usermodel-property-mapper"
+          ],
+          "consent-required-for-all-mappers": [
+            "true"
+          ]
+        }
+      },
+      {
+        "id": "9c3f967b-1cec-4845-9c99-28c2a4587fb5",
+        "name": "Allowed Protocol Mapper Types",
+        "providerId": "allowed-protocol-mappers",
+        "subType": "anonymous",
+        "subComponents": {},
+        "config": {
+          "allowed-protocol-mapper-types": [
+            "oidc-sha256-pairwise-sub-mapper",
+            "saml-user-property-mapper",
+            "oidc-full-name-mapper",
+            "oidc-usermodel-attribute-mapper",
+            "saml-user-attribute-mapper",
+            "oidc-address-mapper",
+            "saml-role-list-mapper",
+            "oidc-usermodel-property-mapper"
+          ],
+          "consent-required-for-all-mappers": [
+            "true"
+          ]
+        }
+      }
+    ],
+    "org.keycloak.storage.UserStorageProvider": [
+      {
+        "id": "a460ef93-18f1-4ecd-be2f-124a748e8803",
+        "name": "ldap",
+        "providerId": "ldap",
+        "subComponents": {
+          "org.keycloak.storage.ldap.mappers.LDAPStorageMapper": [
+            {
+              "id": "b900469d-82eb-4565-8148-09d09754567a",
+              "name": "first name",
+              "providerId": "user-attribute-ldap-mapper",
+              "subComponents": {},
+              "config": {
+                "ldap.attribute": [
+                  "cn"
+                ],
+                "is.mandatory.in.ldap": [
+                  "true"
+                ],
+                "read.only": [
+                  "true"
+                ],
+                "always.read.value.from.ldap": [
+                  "true"
+                ],
+                "user.model.attribute": [
+                  "firstName"
+                ]
+              }
+            },
+            {
+              "id": "59536463-a1fe-4c9c-beed-725f52048d97",
+              "name": "MSAD account controls",
+              "providerId": "msad-user-account-control-mapper",
+              "subComponents": {},
+              "config": {}
+            },
+            {
+              "id": "2542b4d0-79d3-468f-9b99-64c3fd9657ea",
+              "name": "creation date",
+              "providerId": "user-attribute-ldap-mapper",
+              "subComponents": {},
+              "config": {
+                "ldap.attribute": [
+                  "whenCreated"
+                ],
+                "is.mandatory.in.ldap": [
+                  "false"
+                ],
+                "always.read.value.from.ldap": [
+                  "true"
+                ],
+                "read.only": [
+                  "true"
+                ],
+                "user.model.attribute": [
+                  "createTimestamp"
+                ]
+              }
+            },
+            {
+              "id": "a095064f-ddeb-4d32-a87d-e331cdb1789a",
+              "name": "last name",
+              "providerId": "user-attribute-ldap-mapper",
+              "subComponents": {},
+              "config": {
+                "ldap.attribute": [
+                  "sn"
+                ],
+                "is.mandatory.in.ldap": [
+                  "true"
+                ],
+                "always.read.value.from.ldap": [
+                  "true"
+                ],
+                "read.only": [
+                  "true"
+                ],
+                "user.model.attribute": [
+                  "lastName"
+                ]
+              }
+            },
+            {
+              "id": "7774924c-f3ac-4788-9df4-5cb8045014a6",
+              "name": "email",
+              "providerId": "user-attribute-ldap-mapper",
+              "subComponents": {},
+              "config": {
+                "ldap.attribute": [
+                  "mail"
+                ],
+                "is.mandatory.in.ldap": [
+                  "false"
+                ],
+                "always.read.value.from.ldap": [
+                  "false"
+                ],
+                "read.only": [
+                  "true"
+                ],
+                "user.model.attribute": [
+                  "email"
+                ]
+              }
+            },
+            {
+              "id": "0afe1e43-6d63-42b6-a4f2-42105376fb00",
+              "name": "modify date",
+              "providerId": "user-attribute-ldap-mapper",
+              "subComponents": {},
+              "config": {
+                "ldap.attribute": [
+                  "whenChanged"
+                ],
+                "is.mandatory.in.ldap": [
+                  "false"
+                ],
+                "read.only": [
+                  "true"
+                ],
+                "always.read.value.from.ldap": [
+                  "true"
+                ],
+                "user.model.attribute": [
+                  "modifyTimestamp"
+                ]
+              }
+            },
+            {
+              "id": "ddd3c85b-c297-4899-ac15-d0d56cc9792a",
+              "name": "username",
+              "providerId": "user-attribute-ldap-mapper",
+              "subComponents": {},
+              "config": {
+                "ldap.attribute": [
+                  "uid"
+                ],
+                "is.mandatory.in.ldap": [
+                  "true"
+                ],
+                "always.read.value.from.ldap": [
+                  "false"
+                ],
+                "read.only": [
+                  "true"
+                ],
+                "user.model.attribute": [
+                  "username"
+                ]
+              }
+            }
+          ]
+        },
+        "config": {
+          "fullSyncPeriod": [
+            "-1"
+          ],
+          "pagination": [
+            "false"
+          ],
+          "usersDn": [
+            "dc=fbi,dc=h-da,dc=de"
+          ],
+          "connectionPooling": [
+            "true"
+          ],
+          "cachePolicy": [
+            "DEFAULT"
+          ],
+          "useKerberosForPasswordAuthentication": [
+            "false"
+          ],
+          "importEnabled": [
+            "false"
+          ],
+          "enabled": [
+            "true"
+          ],
+          "changedSyncPeriod": [
+            "-1"
+          ],
+          "usernameLDAPAttribute": [
+            "uid"
+          ],
+          "vendor": [
+            "ad"
+          ],
+          "uuidLDAPAttribute": [
+            "uid"
+          ],
+          "allowKerberosAuthentication": [
+            "false"
+          ],
+          "connectionUrl": [
+            "ldap://ldap-rr.fbi.h-da.de"
+          ],
+          "syncRegistrations": [
+            "false"
+          ],
+          "authType": [
+            "none"
+          ],
+          "debug": [
+            "false"
+          ],
+          "searchScope": [
+            "2"
+          ],
+          "useTruststoreSpi": [
+            "ldapsOnly"
+          ],
+          "priority": [
+            "0"
+          ],
+          "userObjectClasses": [
+            "person,inetOrgPerson,organizationalPerson"
+          ],
+          "rdnLDAPAttribute": [
+            "uid"
+          ],
+          "editMode": [
+            "READ_ONLY"
+          ],
+          "validatePasswordPolicy": [
+            "false"
+          ],
+          "batchSizeForSync": [
+            "1000"
+          ]
+        }
+      }
+    ],
+    "org.keycloak.keys.KeyProvider": [
+      {
+        "id": "18e2a585-76bc-4f4d-b4b3-966fad48f741",
+        "name": "rsa-generated",
+        "providerId": "rsa-generated",
+        "subComponents": {},
+        "config": {
+          "priority": [
+            "100"
+          ]
+        }
+      },
+      {
+        "id": "436e930a-9ce9-47d5-8d7d-de3f733589ac",
+        "name": "aes-generated",
+        "providerId": "aes-generated",
+        "subComponents": {},
+        "config": {
+          "priority": [
+            "100"
+          ]
+        }
+      },
+      {
+        "id": "75aac2d9-5045-4fab-af58-cef7c79a829b",
+        "name": "hmac-generated",
+        "providerId": "hmac-generated",
+        "subComponents": {},
+        "config": {
+          "priority": [
+            "100"
+          ]
+        }
+      }
+    ]
+  },
+  "internationalizationEnabled": false,
+  "supportedLocales": [],
+  "authenticationFlows": [
+    {
+      "id": "21a0ba97-484d-49b3-9176-ca6882b691c4",
+      "alias": "Handle Existing Account",
+      "description": "Handle what to do if there is existing account with same email/username like authenticated identity provider",
+      "providerId": "basic-flow",
+      "topLevel": false,
+      "builtIn": true,
+      "authenticationExecutions": [
+        {
+          "authenticator": "idp-confirm-link",
+          "requirement": "REQUIRED",
+          "priority": 10,
+          "userSetupAllowed": false,
+          "autheticatorFlow": false
+        },
+        {
+          "authenticator": "idp-email-verification",
+          "requirement": "ALTERNATIVE",
+          "priority": 20,
+          "userSetupAllowed": false,
+          "autheticatorFlow": false
+        },
+        {
+          "requirement": "ALTERNATIVE",
+          "priority": 30,
+          "flowAlias": "Verify Existing Account by Re-authentication",
+          "userSetupAllowed": false,
+          "autheticatorFlow": true
+        }
+      ]
+    },
+    {
+      "id": "a14ed1f2-bbaa-4ff6-a447-2d7d9961d02d",
+      "alias": "Verify Existing Account by Re-authentication",
+      "description": "Reauthentication of existing account",
+      "providerId": "basic-flow",
+      "topLevel": false,
+      "builtIn": true,
+      "authenticationExecutions": [
+        {
+          "authenticator": "idp-username-password-form",
+          "requirement": "REQUIRED",
+          "priority": 10,
+          "userSetupAllowed": false,
+          "autheticatorFlow": false
+        },
+        {
+          "authenticator": "auth-otp-form",
+          "requirement": "OPTIONAL",
+          "priority": 20,
+          "userSetupAllowed": false,
+          "autheticatorFlow": false
+        }
+      ]
+    },
+    {
+      "id": "e8a7d787-d294-4b7e-a0c1-726c354f633f",
+      "alias": "browser",
+      "description": "browser based authentication",
+      "providerId": "basic-flow",
+      "topLevel": true,
+      "builtIn": true,
+      "authenticationExecutions": [
+        {
+          "authenticator": "auth-cookie",
+          "requirement": "ALTERNATIVE",
+          "priority": 10,
+          "userSetupAllowed": false,
+          "autheticatorFlow": false
+        },
+        {
+          "authenticator": "auth-spnego",
+          "requirement": "DISABLED",
+          "priority": 20,
+          "userSetupAllowed": false,
+          "autheticatorFlow": false
+        },
+        {
+          "authenticator": "identity-provider-redirector",
+          "requirement": "ALTERNATIVE",
+          "priority": 25,
+          "userSetupAllowed": false,
+          "autheticatorFlow": false
+        },
+        {
+          "requirement": "ALTERNATIVE",
+          "priority": 30,
+          "flowAlias": "forms",
+          "userSetupAllowed": false,
+          "autheticatorFlow": true
+        }
+      ]
+    },
+    {
+      "id": "30443520-8261-4a54-a174-64db033cf8ce",
+      "alias": "clients",
+      "description": "Base authentication for clients",
+      "providerId": "client-flow",
+      "topLevel": true,
+      "builtIn": true,
+      "authenticationExecutions": [
+        {
+          "authenticator": "client-secret",
+          "requirement": "ALTERNATIVE",
+          "priority": 10,
+          "userSetupAllowed": false,
+          "autheticatorFlow": false
+        },
+        {
+          "authenticator": "client-jwt",
+          "requirement": "ALTERNATIVE",
+          "priority": 20,
+          "userSetupAllowed": false,
+          "autheticatorFlow": false
+        }
+      ]
+    },
+    {
+      "id": "7ad50aba-4e70-4c58-953a-14d3f414c62d",
+      "alias": "direct grant",
+      "description": "OpenID Connect Resource Owner Grant",
+      "providerId": "basic-flow",
+      "topLevel": true,
+      "builtIn": true,
+      "authenticationExecutions": [
+        {
+          "authenticator": "direct-grant-validate-username",
+          "requirement": "REQUIRED",
+          "priority": 10,
+          "userSetupAllowed": false,
+          "autheticatorFlow": false
+        },
+        {
+          "authenticator": "direct-grant-validate-password",
+          "requirement": "REQUIRED",
+          "priority": 20,
+          "userSetupAllowed": false,
+          "autheticatorFlow": false
+        },
+        {
+          "authenticator": "direct-grant-validate-otp",
+          "requirement": "OPTIONAL",
+          "priority": 30,
+          "userSetupAllowed": false,
+          "autheticatorFlow": false
+        }
+      ]
+    },
+    {
+      "id": "b6b98de9-5932-4511-9661-9511428024de",
+      "alias": "docker auth",
+      "description": "Used by Docker clients to authenticate against the IDP",
+      "providerId": "basic-flow",
+      "topLevel": true,
+      "builtIn": true,
+      "authenticationExecutions": [
+        {
+          "authenticator": "docker-http-basic-authenticator",
+          "requirement": "REQUIRED",
+          "priority": 10,
+          "userSetupAllowed": false,
+          "autheticatorFlow": false
+        }
+      ]
+    },
+    {
+      "id": "e1c950fc-5ea4-4249-b5b3-d9e633a0b396",
+      "alias": "first broker login",
+      "description": "Actions taken after first broker login with identity provider account, which is not yet linked to any Keycloak account",
+      "providerId": "basic-flow",
+      "topLevel": true,
+      "builtIn": true,
+      "authenticationExecutions": [
+        {
+          "authenticatorConfig": "review profile config",
+          "authenticator": "idp-review-profile",
+          "requirement": "REQUIRED",
+          "priority": 10,
+          "userSetupAllowed": false,
+          "autheticatorFlow": false
+        },
+        {
+          "authenticatorConfig": "create unique user config",
+          "authenticator": "idp-create-user-if-unique",
+          "requirement": "ALTERNATIVE",
+          "priority": 20,
+          "userSetupAllowed": false,
+          "autheticatorFlow": false
+        },
+        {
+          "requirement": "ALTERNATIVE",
+          "priority": 30,
+          "flowAlias": "Handle Existing Account",
+          "userSetupAllowed": false,
+          "autheticatorFlow": true
+        }
+      ]
+    },
+    {
+      "id": "a1185e8b-0358-4763-8be9-5b8961b59c71",
+      "alias": "forms",
+      "description": "Username, password, otp and other auth forms.",
+      "providerId": "basic-flow",
+      "topLevel": false,
+      "builtIn": true,
+      "authenticationExecutions": [
+        {
+          "authenticator": "auth-username-password-form",
+          "requirement": "REQUIRED",
+          "priority": 10,
+          "userSetupAllowed": false,
+          "autheticatorFlow": false
+        },
+        {
+          "authenticator": "auth-otp-form",
+          "requirement": "OPTIONAL",
+          "priority": 20,
+          "userSetupAllowed": false,
+          "autheticatorFlow": false
+        }
+      ]
+    },
+    {
+      "id": "b7e68c85-3fe6-46a3-886d-855ae0a49c24",
+      "alias": "registration",
+      "description": "registration flow",
+      "providerId": "basic-flow",
+      "topLevel": true,
+      "builtIn": true,
+      "authenticationExecutions": [
+        {
+          "authenticator": "registration-page-form",
+          "requirement": "REQUIRED",
+          "priority": 10,
+          "flowAlias": "registration form",
+          "userSetupAllowed": false,
+          "autheticatorFlow": true
+        }
+      ]
+    },
+    {
+      "id": "1cf7e481-9bc3-4832-80c3-c0799e2624cb",
+      "alias": "registration form",
+      "description": "registration form",
+      "providerId": "form-flow",
+      "topLevel": false,
+      "builtIn": true,
+      "authenticationExecutions": [
+        {
+          "authenticator": "registration-user-creation",
+          "requirement": "REQUIRED",
+          "priority": 20,
+          "userSetupAllowed": false,
+          "autheticatorFlow": false
+        },
+        {
+          "authenticator": "registration-profile-action",
+          "requirement": "REQUIRED",
+          "priority": 40,
+          "userSetupAllowed": false,
+          "autheticatorFlow": false
+        },
+        {
+          "authenticator": "registration-password-action",
+          "requirement": "REQUIRED",
+          "priority": 50,
+          "userSetupAllowed": false,
+          "autheticatorFlow": false
+        },
+        {
+          "authenticator": "registration-recaptcha-action",
+          "requirement": "DISABLED",
+          "priority": 60,
+          "userSetupAllowed": false,
+          "autheticatorFlow": false
+        }
+      ]
+    },
+    {
+      "id": "7756e120-120f-4a5b-acaf-21b6bfa07273",
+      "alias": "reset credentials",
+      "description": "Reset credentials for a user if they forgot their password or something",
+      "providerId": "basic-flow",
+      "topLevel": true,
+      "builtIn": true,
+      "authenticationExecutions": [
+        {
+          "authenticator": "reset-credentials-choose-user",
+          "requirement": "REQUIRED",
+          "priority": 10,
+          "userSetupAllowed": false,
+          "autheticatorFlow": false
+        },
+        {
+          "authenticator": "reset-credential-email",
+          "requirement": "REQUIRED",
+          "priority": 20,
+          "userSetupAllowed": false,
+          "autheticatorFlow": false
+        },
+        {
+          "authenticator": "reset-password",
+          "requirement": "REQUIRED",
+          "priority": 30,
+          "userSetupAllowed": false,
+          "autheticatorFlow": false
+        },
+        {
+          "authenticator": "reset-otp",
+          "requirement": "OPTIONAL",
+          "priority": 40,
+          "userSetupAllowed": false,
+          "autheticatorFlow": false
+        }
+      ]
+    },
+    {
+      "id": "a4976482-05b8-4eb3-a284-ea21d0d59042",
+      "alias": "saml ecp",
+      "description": "SAML ECP Profile Authentication Flow",
+      "providerId": "basic-flow",
+      "topLevel": true,
+      "builtIn": true,
+      "authenticationExecutions": [
+        {
+          "authenticator": "http-basic-authenticator",
+          "requirement": "REQUIRED",
+          "priority": 10,
+          "userSetupAllowed": false,
+          "autheticatorFlow": false
+        }
+      ]
+    }
+  ],
+  "authenticatorConfig": [
+    {
+      "id": "56535c81-9bec-4471-9e3c-69abfb8bd6f1",
+      "alias": "create unique user config",
+      "config": {
+        "require.password.update.after.registration": "false"
+      }
+    },
+    {
+      "id": "ff43acf8-4840-45c2-b6ef-61cabefb2e2c",
+      "alias": "review profile config",
+      "config": {
+        "update.profile.on.first.login": "missing"
+      }
+    }
+  ],
+  "requiredActions": [
+    {
+      "alias": "CONFIGURE_TOTP",
+      "name": "Configure OTP",
+      "providerId": "CONFIGURE_TOTP",
+      "enabled": true,
+      "defaultAction": false,
+      "config": {}
+    },
+    {
+      "alias": "UPDATE_PASSWORD",
+      "name": "Update Password",
+      "providerId": "UPDATE_PASSWORD",
+      "enabled": true,
+      "defaultAction": false,
+      "config": {}
+    },
+    {
+      "alias": "UPDATE_PROFILE",
+      "name": "Update Profile",
+      "providerId": "UPDATE_PROFILE",
+      "enabled": true,
+      "defaultAction": false,
+      "config": {}
+    },
+    {
+      "alias": "VERIFY_EMAIL",
+      "name": "Verify Email",
+      "providerId": "VERIFY_EMAIL",
+      "enabled": true,
+      "defaultAction": false,
+      "config": {}
+    },
+    {
+      "alias": "terms_and_conditions",
+      "name": "Terms and Conditions",
+      "providerId": "terms_and_conditions",
+      "enabled": false,
+      "defaultAction": false,
+      "config": {}
+    }
+  ],
+  "browserFlow": "browser",
+  "registrationFlow": "registration",
+  "directGrantFlow": "direct grant",
+  "resetCredentialsFlow": "reset credentials",
+  "clientAuthenticationFlow": "clients",
+  "dockerAuthenticationFlow": "docker auth",
+  "attributes": {
+    "_browser_header.xXSSProtection": "1; mode=block",
+    "_browser_header.strictTransportSecurity": "max-age=31536000; includeSubDomains",
+    "_browser_header.xFrameOptions": "SAMEORIGIN",
+    "quickLoginCheckMilliSeconds": "1000",
+    "permanentLockout": "false",
+    "_browser_header.xRobotsTag": "none",
+    "maxFailureWaitSeconds": "900",
+    "displayNameHtml": "Hochschule Darmstadt",
+    "minimumQuickLoginWaitSeconds": "60",
+    "failureFactor": "30",
+    "actionTokenGeneratedByUserLifespan": "300",
+    "maxDeltaTimeSeconds": "43200",
+    "_browser_header.xContentTypeOptions": "nosniff",
+    "actionTokenGeneratedByAdminLifespan": "43200",
+    "bruteForceProtected": "false",
+    "_browser_header.contentSecurityPolicy": "frame-src 'self'; frame-ancestors 'self'; object-src 'none';",
+    "waitIncrementSeconds": "60"
+  },
+  "keycloakVersion": "7.2.2.GA"
+}
\ No newline at end of file
diff --git a/openshiftTemplate.yml b/openshiftTemplate.yml
new file mode 100644
index 0000000000000000000000000000000000000000..5d9fa5d4d75d9f41e4d6d1952357a80c5fe631f4
--- /dev/null
+++ b/openshiftTemplate.yml
@@ -0,0 +1,884 @@
+# generall informations
+
+apiVersion: v1
+kind: Template
+metadata:
+  name: openspace-template
+  annotations:
+    openshift.io/display-name: OpenSpace
+    description: OpenSpace for PAD1 and PAD2
+    iconClass: icon-hdalogo
+    tags: hda,hdapad
+objects:
+
+# init container definitions
+
+- apiVersion: v1
+  kind: DeploymentConfig
+  metadata:
+    name: initcontainer
+  spec:
+    replicas: 0
+    selector:
+      app: initcontainer
+      deploymentconfig: initcontainer
+    template:
+      metadata:
+        labels:
+          app: initcontainer
+          deploymentconfig: initcontainer
+      spec:
+        containers:
+        - env:
+          - name: MY_POD_NAMESPACE
+            valueFrom:
+              fieldRef:
+                fieldPath: metadata.namespace
+          - name: JENKINS_API_PASSWORD
+            value: ${JENKINS_API_PASSWORD}
+          - name: ADMIN_FIRST_NAME
+            value: ${ADMIN_FIRST_NAME}
+          - name: ADMIN_LAST_NAME
+            value: ${ADMIN_LAST_NAME}
+          - name: OPENSUBMIT_ADMIN_MAIL
+            value: ${OPENSUBMIT_ADMIN_MAIL}
+          - name: JENKINS_ADMIN
+            value: ${JENKINS_ADMIN}
+          - name: OC_URL
+            value: ${OC_URL}
+          - name: WEB_DOMAIN
+            value: web-$(MY_POD_NAMESPACE).${DOMAIN}
+          - name: JENKINS_DOMAIN
+            value: jenkins-$(MY_POD_NAMESPACE).${DOMAIN}
+          - name: SSO_USERNAME
+            value: ${SSO_ADMIN_USERNAME}
+          - name: SSO_PASSWORD
+            value: ${SSO_ADMIN_PASSWORD}
+          - name: SSO_URL
+            value: https://sso-$(MY_POD_NAMESPACE).${DOMAIN}
+          - name: GIT_URL
+            value: ${GIT_URL}
+          image: ' '
+          name: initcontainer
+    test: false
+    triggers:
+    - type: ConfigChange
+    - imageChangeParams:
+        automatic: true
+        containerNames:
+        - initcontainer
+        from:
+          kind: ImageStreamTag
+          name: initcontainer:latest
+      type: ImageChange
+
+- apiVersion: v1
+  kind: ImageStream
+  metadata:
+    name: initcontainer
+  spec:
+    tags:
+    - annotations: null
+      from:
+        kind: DockerImage
+        name: koehlerlukas/opensubmit-initcontainer:latest
+      name: latest
+
+# opensubmit definitions
+
+- kind: Route
+  apiVersion: v1
+  metadata:
+    name: web
+    annotations:
+      template.openshift.io/expose-uri: 'http://{.spec.host}{.spec.path}'
+      haproxy.router.openshift.io/timeout: 4m
+  spec:
+    to:
+      kind: Service
+      name: web
+    tls:
+      termination: edge
+      insecureEdgeTerminationPolicy: Redirect
+
+
+- apiVersion: v1
+  kind: PersistentVolumeClaim
+  metadata:
+    name: postgres-volume
+  spec:
+    accessModes:
+    - ReadWriteOnce
+    resources:
+      requests:
+        storage: ${POSTGRES_SIZE}Gi
+  status: {}
+
+- apiVersion: v1
+  kind: PersistentVolumeClaim
+  metadata:
+    name: opensubmit-volume
+  spec:
+    accessModes:
+    - ReadWriteOnce
+    resources:
+      requests:
+        storage: ${WEB_VOLUME_SIZE}Gi
+  status: {}
+
+- apiVersion: v1
+  kind: ImageStream
+  metadata:
+    name: exec
+  spec:
+    tags:
+    - annotations: null
+      from:
+        kind: DockerImage
+        name: koehlerlukas/opensubmit-exec:latest
+      name: latest
+
+- apiVersion: v1
+  kind: ImageStream
+  metadata:
+    name: web
+  spec:
+    tags:
+    - annotations: null
+      from:
+        kind: DockerImage
+        name: koehlerlukas/opensubmit-web:latest
+      name: latest
+
+- apiVersion: v1
+  kind: DeploymentConfig
+  metadata:
+    name: db
+  spec:
+    replicas: 0
+    selector:
+      app: db
+      deploymentconfig: db
+    template:
+      metadata:
+        labels:
+          app: db
+          deploymentconfig: db
+      spec:
+        containers:
+        - env:
+          - name: POSTGRESQL_USER
+            value: opensubmit
+          - name: POSTGRESQL_PASSWORD
+            value: opensubmit
+          - name: POSTGRESQL_DATABASE
+            value: opensubmit
+          image: ' '
+          name: db
+          ports:
+          - containerPort: 5432
+            protocol: TCP
+          volumeMounts:
+          - mountPath: /var/lib/pgsql/data
+            name: postgres-volume
+        volumes:
+        - name: postgres-volume
+          persistentVolumeClaim:
+            claimName: postgres-volume
+    test: false
+    triggers:
+    - type: ConfigChange
+    - imageChangeParams:
+        automatic: true
+        containerNames:
+        - db
+        from:
+          kind: ImageStreamTag
+          namespace: openshift
+          name: postgresql:9.6
+      type: ImageChange
+
+- apiVersion: v1
+  kind: DeploymentConfig
+  metadata:
+    name: web
+  spec:
+    replicas: 0
+    selector:
+      app: web
+      deploymentconfig: web
+    template:
+      metadata:
+        labels:
+          app: web
+          deploymentconfig: web
+      spec:
+        containers:
+        - env:
+          - name: MY_POD_NAMESPACE
+            valueFrom:
+              fieldRef:
+                fieldPath: metadata.namespace
+          - name: OPENSUBMIT_SERVER_URL
+            value: https://web-$(MY_POD_NAMESPACE).${DOMAIN}
+          - name: OPENSUBMIT_DATABASE_ENGINE
+            value: postgresql
+          - name: OPENSUBMIT_DATABASE_HOST
+            value: db
+          - name: OPENSUBMIT_DATABASE_NAME
+            value: opensubmit
+          - name: OPENSUBMIT_DATABASE_PASSWORD
+            value: opensubmit
+          - name: OPENSUBMIT_DATABASE_USER
+            value: opensubmit
+          - name: OPENSUBMIT_SERVER_HOSTALIASES
+            value: web
+          - name: OPENSUBMIT_SERVER_MEDIAROOT
+            value: /data/media/
+          - name: OPENSHIFT_APP_DNS
+            value: '*'
+          - name: OPENSUBMIT_LOGIN_DEMO
+            value: 'False'
+          - name: OPENSUBMIT_DEBUG
+            value: 'False'
+          - name: OPENSUBMIT_OPENSHIFT_SSO_PROVIDER
+            value: https://sso-$(MY_POD_NAMESPACE).${DOMAIN}/auth/realms/hda/protocol/openid-connect
+          - name: OPENSUBMIT_LOGIN_OPENSHIFT_SSO_TITLE
+            value: Hochschule Darmstadt
+          - name: OPENSUBMIT_LOGIN_OPENSHIFT_SSO_OIDC_VERIFY_SSL
+            value: 'False'
+          - name: OPENSUBMIT_LOGIN_OPENSHIFT_SSO_OIDC_RP_CLIENT_ID
+            value: opensubmit
+          - name: OPENSUBMIT_LOGIN_OPENSHIFT_SSO_OIDC_RP_CLIENT_SECRET
+            value: SECRET
+          image: ' '
+          name: web
+          ports:
+          volumeMounts:
+          - mountPath: /data
+            name: opensubmit-volume
+        volumes:
+        - name: opensubmit-volume
+          persistentVolumeClaim:
+            claimName: opensubmit-volume
+    test: false
+    triggers:
+    - type: ConfigChange
+    - imageChangeParams:
+        automatic: true
+        containerNames:
+        - web
+        from:
+          kind: ImageStreamTag
+          name: web:latest
+      type: ImageChange
+
+- apiVersion: v1
+  kind: DeploymentConfig
+  metadata:
+    name: exec
+  spec:
+    replicas: 0
+    selector:
+      app: exec
+      deploymentconfig: exec
+    template:
+      metadata:
+        labels:
+          app: exec
+          deploymentconfig: exec
+      spec:
+        containers:
+        - env:
+          - name: OPENSUBMIT_SERVER_HOST
+            value: http://web:8000
+          image: ' '
+          name: exec
+          volumeMounts:
+          - mountPath: /ssh
+            name: opensubmit-exec-ssh-volume
+        volumes:
+        - name: opensubmit-exec-ssh-volume
+          persistentVolumeClaim:
+            claimName: opensubmit-exec-ssh-volume
+    test: false
+    triggers:
+    - type: ConfigChange
+    - imageChangeParams:
+        automatic: true
+        containerNames:
+        - exec
+        from:
+          kind: ImageStreamTag
+          name: exec:latest
+      type: ImageChange
+
+- apiVersion: v1
+  kind: PersistentVolumeClaim
+  metadata:
+    name: opensubmit-exec-ssh-volume
+  spec:
+    accessModes:
+    - ReadWriteOnce
+    resources:
+      requests:
+        storage: 10Mi
+  status: {}
+
+- apiVersion: v1
+  kind: Service
+  metadata:
+    labels:
+      app: db
+    name: db
+  spec:
+    ports:
+    - name: db-5432
+      port: 5432
+      protocol: TCP
+      targetPort: 5432
+    selector:
+      deploymentconfig: db
+
+- apiVersion: v1
+  kind: Service
+  metadata:
+    labels:
+      app: web
+    name: web
+  spec:
+    ports:
+    - name: opensubmit-web
+      port: 8000
+      protocol: TCP
+      targetPort: 8080
+    selector:
+      app: web
+
+# Jenkins definitions
+
+- apiVersion: v1
+  kind: ImageStream
+  metadata:
+    name: jenkins
+  spec:
+    tags:
+    - annotations: null
+      from:
+        kind: DockerImage
+        name: koehlerlukas/opensubmit-jenkins:latest
+      name: latest
+
+- kind: Route
+  apiVersion: v1
+  metadata:
+    name: jenkins
+    annotations:
+      template.openshift.io/expose-uri: 'http://{.spec.host}{.spec.path}'
+      haproxy.router.openshift.io/timeout: 4m
+  spec:
+    to:
+      kind: Service
+      name: jenkins
+    tls:
+      termination: edge
+      insecureEdgeTerminationPolicy: Redirect
+
+- kind: PersistentVolumeClaim
+  apiVersion: v1
+  metadata:
+    name: jenkins-volume
+  spec:
+    accessModes:
+    - ReadWriteOnce
+    resources:
+      requests:
+        storage: ${JENKINS_VOLUME_CAPACITY}Gi
+
+- kind: DeploymentConfig
+  apiVersion: v1
+  metadata:
+    name: jenkins
+    annotations:
+      template.alpha.openshift.io/wait-for-ready: 'true'
+  spec:
+    triggers:
+    - type: ImageChange
+      imageChangeParams:
+        automatic: true
+        containerNames:
+        - jenkins
+        from:
+          kind: ImageStreamTag
+          name: jenkins:latest
+        lastTriggeredImage:
+    - type: ConfigChange
+    replicas: 0
+    selector:
+      name: jenkins
+    template:
+      metadata:
+        labels:
+          name: jenkins
+      spec:
+        serviceAccountName: jenkins
+        containers:
+        - name: jenkins
+          image: ' '
+          env:
+          - name: OPENSHIFT_ENABLE_OAUTH
+            value: 'false'
+          - name: OPENSHIFT_ENABLE_REDIRECT_PROMPT
+            value: 'false'
+          - name: DISABLE_ADMINISTRATIVE_MONITORS
+            value: 'false'
+          - name: KUBERNETES_MASTER
+            value: https://kubernetes.default:443
+          - name: KUBERNETES_TRUST_CERTIFICATES
+            value: 'true'
+          - name: JENKINS_PASSWORD
+            value: admin
+          - name: ENABLE_FATAL_ERROR_LOG_FILE
+            value: 'false'
+          volumeMounts:
+            - name: jenkins-volume
+              mountPath: /var/lib/jenkins
+          terminationMessagePath: /dev/termination-log
+          securityContext:
+            capabilities: {}
+            privileged: false
+        volumes:
+        - name: jenkins-volume
+          persistentVolumeClaim:
+            claimName: jenkins-volume
+        restartPolicy: Always
+        dnsPolicy: ClusterFirst
+
+- kind: ServiceAccount
+  apiVersion: v1
+  metadata:
+    name: jenkins
+    annotations:
+      serviceaccounts.openshift.io/oauth-redirectreference.jenkins: '{"kind":"OAuthRedirectReference","apiVersion":"v1","reference":{"kind":"Route","name":"jenkins"}}'
+
+- kind: RoleBinding
+  apiVersion: v1
+  metadata:
+    name: jenkins_edit
+  groupNames:
+  subjects:
+  - kind: ServiceAccount
+    name: jenkins
+  roleRef:
+    name: edit
+
+- kind: Service
+  apiVersion: v1
+  metadata:
+    name: jenkins-jnlp
+  spec:
+    ports:
+    - name: agent
+      protocol: TCP
+      port: 50000
+      targetPort: 50000
+      nodePort: 0
+    selector:
+      name: jenkins
+    type: ClusterIP
+    sessionAffinity: None
+
+- kind: Service
+  apiVersion: v1
+  metadata:
+    name: jenkins-ssh
+  spec:
+    ports:
+    - name: agent
+      protocol: TCP
+      port: 22
+      targetPort: 2222
+    selector:
+      name: jenkins
+
+- kind: Service
+  apiVersion: v1
+  metadata:
+    name: jenkins
+    annotations:
+      service.alpha.openshift.io/dependencies: '[{"name": "jenkins-jnlp", "namespace": "", "kind": "Service"}]'
+      service.openshift.io/infrastructure: 'true'
+  spec:
+    ports:
+    - name: web
+      protocol: TCP
+      port: 80
+      targetPort: 8080
+      nodePort: 0
+    selector:
+      name: jenkins
+    type: ClusterIP
+    sessionAffinity: None
+
+# SSO Stuff
+- kind: Service
+  apiVersion: v1
+  spec:
+    ports:
+    - port: 8443
+      targetPort: 8443
+    selector:
+      deploymentConfig: sso
+  metadata:
+    name: sso
+    labels:
+      application: sso
+    annotations:
+      description: The web server's https port.
+      service.alpha.openshift.io/serving-cert-secret-name: sso-x509-https-secret
+      service.alpha.openshift.io/dependencies: '[{"name": "sso-postgresql",
+        "kind": "Service"}]'
+
+- kind: Service
+  apiVersion: v1
+  spec:
+    ports:
+    - name: 5432-port
+      port: 5432
+      targetPort: 5432
+    selector:
+      deploymentConfig: sso-postgresql
+  metadata:
+    name: sso-postgresql
+    labels:
+      application: sso
+    annotations:
+      description: The database server's port.
+
+- kind: Service
+  apiVersion: v1
+  spec:
+    clusterIP: None
+    ports:
+    - name: ping
+      port: 8888
+    selector:
+      deploymentConfig: sso
+  metadata:
+    name: sso-ping
+    labels:
+      application: sso
+    annotations:
+      service.alpha.kubernetes.io/tolerate-unready-endpoints: 'true'
+      service.alpha.openshift.io/serving-cert-secret-name: sso-x509-jgroups-secret
+      description: The JGroups ping port for clustering.
+
+- kind: Route
+  apiVersion: v1
+  id: sso-https
+  metadata:
+    name: sso
+    labels:
+      application: sso
+    annotations:
+      description: Route for application's https service.
+  spec:
+    to:
+      name: sso
+    tls:
+      termination: reencrypt
+
+- apiVersion: v1
+  kind: ImageStream
+  metadata:
+    name: redhat-sso
+  spec:
+    tags:
+    - annotations: null
+      from:
+        kind: DockerImage
+        name: registry.access.redhat.com/redhat-sso-7/sso72-openshift:1.1
+      name: '1.1'
+
+- kind: DeploymentConfig
+  apiVersion: v1
+  metadata:
+    name: sso
+    labels:
+      application: sso
+  spec:
+    strategy:
+      type: Recreate
+    triggers:
+    - type: ImageChange
+      imageChangeParams:
+        automatic: true
+        containerNames:
+        - sso
+        from:
+          kind: ImageStreamTag
+          name: redhat-sso:1.1
+    - type: ConfigChange
+    replicas: 0
+    selector:
+      deploymentConfig: sso
+    template:
+      metadata:
+        name: sso
+        labels:
+          deploymentConfig: sso
+          application: sso
+      spec:
+        terminationGracePeriodSeconds: 75
+        containers:
+        - name: sso
+          image: sso
+          imagePullPolicy: Always
+          volumeMounts:
+          - name: sso-x509-https-volume
+            mountPath: /etc/x509/https
+            readOnly: true
+          - name: sso-x509-jgroups-volume
+            mountPath: /etc/x509/jgroups
+            readOnly: true
+          livenessProbe:
+            exec:
+              command:
+              - '/bin/bash'
+              - '-c'
+              - '/opt/eap/bin/livenessProbe.sh'
+            initialDelaySeconds: 60
+          readinessProbe:
+            exec:
+              command:
+              - '/bin/bash'
+              - '-c'
+              - '/opt/eap/bin/readinessProbe.sh'
+          ports:
+          - name: jolokia
+            containerPort: 8778
+            protocol: TCP
+          - name: http
+            containerPort: 8080
+            protocol: TCP
+          - name: https
+            containerPort: 8443
+            protocol: TCP
+          - name: ping
+            containerPort: 8888
+            protocol: TCP
+          env:
+          - name: DB_SERVICE_PREFIX_MAPPING
+            value: sso-postgresql=DB
+          - name: DB_USERNAME
+            value: ${DB_USERNAME}
+          - name: DB_PASSWORD
+            value: ${DB_PASSWORD}
+          - name: DB_DATABASE
+            value: root
+          - name: TX_DATABASE_PREFIX_MAPPING
+            value: sso-postgresql=DB
+          - name: JGROUPS_PING_PROTOCOL
+            value: openshift.DNS_PING
+          - name: OPENSHIFT_DNS_PING_SERVICE_NAME
+            value: sso-ping
+          - name: OPENSHIFT_DNS_PING_SERVICE_PORT
+            value: '8888'
+          - name: X509_CA_BUNDLE
+            value: /var/run/secrets/kubernetes.io/serviceaccount/service-ca.crt
+          - name: JGROUPS_CLUSTER_PASSWORD
+            value: ${JGROUPS_CLUSTER_PASSWORD}
+          - name: SSO_ADMIN_USERNAME
+            value: ${SSO_ADMIN_USERNAME}
+          - name: SSO_ADMIN_PASSWORD
+            value: ${SSO_ADMIN_PASSWORD}
+        volumes:
+        - name: sso-x509-https-volume
+          secret:
+            secretName: sso-x509-https-secret
+        - name: sso-x509-jgroups-volume
+          secret:
+            secretName: sso-x509-jgroups-secret
+
+- kind: DeploymentConfig
+  apiVersion: v1
+  metadata:
+    name: sso-postgresql
+    labels:
+      application: sso
+  spec:
+    strategy:
+      type: Recreate
+    triggers:
+    - type: ImageChange
+      imageChangeParams:
+        automatic: true
+        containerNames:
+        - sso-postgresql
+        from:
+          kind: ImageStreamTag
+          namespace: openshift
+          name: postgresql:9.6
+    - type: ConfigChange
+    replicas: 0
+    selector:
+      deploymentConfig: sso-postgresql
+    template:
+      metadata:
+        name: sso-postgresql
+        labels:
+          deploymentConfig: sso-postgresql
+          application: sso
+      spec:
+        terminationGracePeriodSeconds: 60
+        containers:
+        - name: sso-postgresql
+          image: postgresql
+          imagePullPolicy: Always
+          ports:
+          - containerPort: 5432
+            protocol: TCP
+          readinessProbe:
+            timeoutSeconds: 1
+            initialDelaySeconds: 5
+            exec:
+              command:
+              - '/bin/sh'
+              - '-i'
+              - '-c'
+              - psql -h 127.0.0.1 -U $POSTGRESQL_USER -q -d $POSTGRESQL_DATABASE -c
+                  'SELECT 1'
+          livenessProbe:
+            timeoutSeconds: 1
+            initialDelaySeconds: 30
+            tcpSocket:
+              port: 5432
+          volumeMounts:
+          - mountPath: /var/lib/pgsql/data
+            name: sso-postgresql-pvol
+          env:
+          - name: POSTGRESQL_USER
+            value: ${DB_USERNAME}
+          - name: POSTGRESQL_PASSWORD
+            value: ${DB_PASSWORD}
+          - name: POSTGRESQL_DATABASE
+            value: root
+        volumes:
+        - name: sso-postgresql-pvol
+          persistentVolumeClaim:
+            claimName: sso-postgresql-claim
+- apiVersion: v1
+  kind: PersistentVolumeClaim
+  metadata:
+    name: sso-postgresql-claim
+    labels:
+      application: sso
+  spec:
+    accessModes:
+    - ReadWriteOnce
+    resources:
+      requests:
+        storage: ${VOLUME_CAPACITY}Gi
+
+parameters:
+# global parameter
+- value: 'apps.ocp.fbi.h-da.de'
+  required: true
+  name: DOMAIN
+  displayName: route domain
+
+- displayName: openshift url
+  value: 'https://console.ocp.fbi.h-da.de'
+  required: true
+  name: OC_URL
+
+- displayName: git base path
+  description: this url is for the initcontainer
+  value: 'https://code.fbi.h-da.de/SS18-REP-PAD2/Config/raw/master/config'
+  required: true
+  name: GIT_URL
+
+- displayName: jenkins admin username
+  description: This user will be admin
+  required: true
+  name: JENKINS_ADMIN
+
+- displayName: jenkins admin first name
+  description: This user will be admin
+  required: true
+  name: ADMIN_FIRST_NAME
+
+- displayName: jenkins admin last name
+  description: This user will be admin
+  required: true
+  name: ADMIN_LAST_NAME
+
+- displayName: opensubmit admin email
+  description: opensubmit user with this email will be admin
+  required: true
+  name: OPENSUBMIT_ADMIN_MAIL
+
+# opensubmit parameter
+- displayName: opensubmit postgres volume size in GB
+  from: '[0-9]{4}'
+  value: '10'
+  required: true
+  name: POSTGRES_SIZE
+
+- displayName: opensubmit-web volume size in GB
+  from: '[0-9]{4}'
+  required: true
+  value: '10'
+  name: WEB_VOLUME_SIZE
+
+# jenkins parameter
+- name: JENKINS_VOLUME_CAPACITY
+  displayName: jenkins volume size in GB
+  value: '10'
+  required: true
+
+# SSO
+- displayName: sso database username
+  name: DB_USERNAME
+  from: user[a-zA-Z0-9]{3}
+  generate: expression
+  required: true
+
+- displayName: sso database password
+  name: DB_PASSWORD
+  from: '[a-zA-Z0-9]{8}'
+  generate: expression
+  required: true
+
+- displayName: sso database volume size in GB
+  name: VOLUME_CAPACITY
+  from: '[0-9]{4}'
+  value: '10'
+  required: true
+
+- displayName: JGroups cluster password
+  name: JGROUPS_CLUSTER_PASSWORD
+  from: '[a-zA-Z0-9]{8}'
+  generate: expression
+  required: true
+
+- displayName: RH-SSO administrator username
+  name: SSO_ADMIN_USERNAME
+  from: '[a-zA-Z0-9]{8}'
+  generate: expression
+  required: true
+
+- displayName: RH-SSO administrator password
+  name: SSO_ADMIN_PASSWORD
+  from: '[a-zA-Z0-9]{8}'
+  generate: expression
+  required: true
+
+- displayName: Jenkins API Password
+  name: JENKINS_API_PASSWORD
+  from: '[a-zA-Z0-9]{8}'
+  generate: expression
+  required: true
+
+
+
diff --git a/pipelines/DB-Airport/Praktikum 1/jenkinsfile.groovy b/pipelines/DB-Airport/Praktikum 1/jenkinsfile.groovy
new file mode 100644
index 0000000000000000000000000000000000000000..5018f43fbed90749c42d9db35ca802d172a48379
--- /dev/null
+++ b/pipelines/DB-Airport/Praktikum 1/jenkinsfile.groovy	
@@ -0,0 +1,50 @@
+node {
+    stage('Copy files') {
+        sh(
+                '''
+                chmod -Rf 777 ./
+                rm -rf *
+                echo $folder
+                cp -r $folder/* ./
+                rm -rf \$folder
+            '''
+        )
+    }
+    stage('Pull and compile cppunit tests') {
+        sh(
+                '''
+            mkdir git
+            '''
+        )
+        dir('git') {
+            git(
+                    credentialsId: 'codegit',
+                    url: 'https://code.fbi.h-da.de/SS18-REP-PAD2/UnitTests/Praktikum1.git',
+                    changelog: false
+            )
+        }
+        sh(
+                '''
+                cp -r git/* ./
+            '''
+        )
+        sh(
+                '''
+                cmake ./
+                make
+           '''
+        )
+    }
+    stage('Run cppunit tests') {
+        sh('./cppunitTemplate')
+        xunit(
+                thresholds: [
+                        skipped(failureThreshold: '0'),
+                        failed(failureThreshold: '0')
+                ],
+                tools: [CppUnit(
+                        pattern: 'testResults.xml',
+                )]
+        )
+    }
+}
\ No newline at end of file
diff --git a/pipelines/PipelineConfig.xml b/pipelines/PipelineConfig.xml
new file mode 100644
index 0000000000000000000000000000000000000000..561b572b42a5c3c4a068bd86b1b24ce7d4cfa72c
--- /dev/null
+++ b/pipelines/PipelineConfig.xml
@@ -0,0 +1,51 @@
+<?xml version='1.1' encoding='UTF-8'?>
+<flow-definition plugin="workflow-job@2.24">
+    <actions/>
+    <description></description>
+    <keepDependencies>false</keepDependencies>
+    <properties>
+        <hudson.security.AuthorizationMatrixProperty>
+            <inheritanceStrategy class="org.jenkinsci.plugins.matrixauth.inheritance.NonInheritingStrategy"/>
+            <permission>hudson.model.Item.Read:{USERNAME}</permission>
+            <permission>hudson.model.Item.Workspace:{USERNAME}</permission>
+        </hudson.security.AuthorizationMatrixProperty>
+        <io.fabric8.jenkins.openshiftsync.BuildConfigProjectProperty plugin="openshift-sync@1.0.25">
+            <uid></uid>
+            <namespace></namespace>
+            <name></name>
+            <resourceVersion></resourceVersion>
+        </io.fabric8.jenkins.openshiftsync.BuildConfigProjectProperty>
+        <hudson.model.ParametersDefinitionProperty>
+            <parameterDefinitions>
+                <hudson.model.StringParameterDefinition>
+                    <name>folder</name>
+                    <description></description>
+                    <defaultValue></defaultValue>
+                    <trim>false</trim>
+                </hudson.model.StringParameterDefinition>
+            </parameterDefinitions>
+        </hudson.model.ParametersDefinitionProperty>
+    </properties>
+    <definition class="org.jenkinsci.plugins.workflow.cps.CpsScmFlowDefinition" plugin="workflow-cps@2.54">
+        <scm class="hudson.plugins.git.GitSCM" plugin="git@3.9.1">
+            <configVersion>2</configVersion>
+            <userRemoteConfigs>
+                <hudson.plugins.git.UserRemoteConfig>
+                    <url>{GIT_REPO}</url>
+                </hudson.plugins.git.UserRemoteConfig>
+            </userRemoteConfigs>
+            <branches>
+                <hudson.plugins.git.BranchSpec>
+                    <name>*/master</name>
+                </hudson.plugins.git.BranchSpec>
+            </branches>
+            <doGenerateSubmoduleConfigurations>false</doGenerateSubmoduleConfigurations>
+            <submoduleCfg class="list"/>
+            <extensions/>
+        </scm>
+        <scriptPath>{GIT_JENKINSFILE_PATH}</scriptPath>
+        <lightweight>true</lightweight>
+    </definition>
+    <triggers/>
+    <disabled>false</disabled>
+</flow-definition>
\ No newline at end of file
diff --git a/validationScripts/validate.py b/validationScripts/validate.py
new file mode 100644
index 0000000000000000000000000000000000000000..671664ccd658813b5beb941fcae0aed0ed1184b1
--- /dev/null
+++ b/validationScripts/validate.py
@@ -0,0 +1,133 @@
+import os
+import time
+from urllib import parse, request
+
+import urllib3
+from jenkins import Jenkins
+from jenkins import JenkinsException
+
+DEBUG = False
+
+PIPELINE_CONFIG_URL = 'https://code.fbi.h-da.de/DB-Airport/Config/raw/master/pipelines/PipelineConfig.xml'
+
+PIPELINE_REPO = 'https://code.fbi.h-da.de/DB-Airport/Config.git'
+PIPELINE_BASE = 'pipelines'
+JENKINSFILE_NAME = 'jenkinsfile.groovy'
+
+JENKINS_URL = 'https://jenkins-open-submit.apps.ocp.fbi.h-da.de'
+JENKINS_USERNAME = 'api'
+JENKINS_SECRET = os.environ['JENKINS_API_TOKEN']
+
+# Parameter that will be filled when debug is off
+USERNAME = 'istlukoeh'
+COURSE = 'PAD1'
+ASSIGNMENT = 'Praktikum 1'
+COURSE_AND_ASSIGNMENT = COURSE + '-' + ASSIGNMENT
+JOB_NAME = COURSE + '-' + ASSIGNMENT + '-' + USERNAME
+FOLDER = '/tmp/1_3wrqhvuj/'
+
+
+def validate(job):
+    global FOLDER
+    my_init(job)
+
+    if not DEBUG:
+        for fname in os.listdir('.'):
+            if fname.endswith('Makefile'):
+                job.run_make(mandatory=True)
+
+    server = Jenkins(JENKINS_URL, JENKINS_USERNAME, JENKINS_SECRET)
+    create_pipeline(server)
+
+    paramFolder = FOLDER.split('/')[-1]
+    if paramFolder == "":
+        paramFolder = FOLDER.split('/')[-2]
+    if paramFolder == "":
+        paramFolder = FOLDER.split('/')[-3]
+    queue_number = server.build_job(JOB_NAME, {'folder': '/opensubmit/' + paramFolder})
+    queue_item = server.get_queue_item(queue_number)
+
+    while 'executable' not in queue_item or not queue_item['executable']:
+        print('Waiting for queue item . . .')
+        time.sleep(2)
+        queue_item = server.get_queue_item(queue_number)
+
+    while 'number' not in queue_item['executable'] or not queue_item['executable']['number']:
+        print('Waiting for queue item . . .')
+        time.sleep(2)
+        queue_item = server.get_queue_item(queue_number)
+
+    build_number = queue_item['executable']['number']
+
+    build_output = server.get_build_console_output(JOB_NAME, build_number)
+    while 'Finished:' not in build_output:
+        print('Waiting for complete pipeline output . . .')
+        time.sleep(2)
+        build_output = server.get_build_console_output(JOB_NAME, build_number)
+
+    print('Finished!')
+
+    job_url = JENKINS_URL + '/job/' + parse.quote(JOB_NAME) + '/' + str(build_number)
+    result = '<a href="' + job_url + '" target="_blank">Jenkins results</a>'
+    success = 'Finished: SUCCESS' in build_output
+
+    if success:
+        print('Failed!')
+    else:
+        print('Success')
+
+    print(result)
+
+    if not DEBUG:
+        if success:
+            job.send_pass_result(result)
+        else:
+            job.send_fail_result(result)
+
+
+def my_init(job):
+    global USERNAME
+    global COURSE
+    global ASSIGNMENT
+    global FOLDER
+    global COURSE_AND_ASSIGNMENT
+    global JOB_NAME
+    if not DEBUG:
+        USERNAME = job.submitter_student_id
+        COURSE = job.course
+        ASSIGNMENT = job.assignment
+        FOLDER = job.working_dir
+        COURSE_AND_ASSIGNMENT = COURSE + '-' + ASSIGNMENT
+        JOB_NAME = COURSE + '-' + ASSIGNMENT + '-' + USERNAME
+
+        fileNameList = [name for name in os.listdir(FOLDER) if
+                        '__pycache__' not in name and '.py' not in name and '.zip' not in name]
+        while len(fileNameList) == 1 and os.path.isdir(os.path.join(FOLDER, fileNameList[0])):
+            FOLDER = os.path.join(FOLDER, fileNameList[0])
+
+        job.working_dir = FOLDER
+        os.system('scp -i /ssh/key -r ' + FOLDER + ' jenkins-ssh@jenkins-ssh:/opensubmit')
+        os.system('chmod -R 777 ' + FOLDER)
+
+    os.environ['PYTHONHTTPSVERIFY'] = '0'
+    urllib3.disable_warnings()
+
+
+def create_pipeline(jenkins_server):
+    # data = request.urlopen(
+    #    PIPELINE_BASE_URL + parse.quote(COURSE) + '/' + parse.quote(ASSIGNMENT) + '.xml')
+    data = request.urlopen(PIPELINE_CONFIG_URL)
+    xml_file = data.read().decode("utf-8")
+    xml_file = xml_file.replace('{USERNAME}', USERNAME)
+    xml_file = xml_file.replace('{GIT_REPO}', PIPELINE_REPO)
+    xml_file = xml_file.replace('{GIT_JENKINSFILE_PATH}',
+                                PIPELINE_BASE + '/' + COURSE + '/' + ASSIGNMENT + '/' + JENKINSFILE_NAME)
+
+    try:
+        jenkins_server.create_job(JOB_NAME, xml_file)
+    except JenkinsException:
+        print('Pipeline already exists')
+
+
+if DEBUG:
+    validate(None)