== Advanced Concepts These cover additional configuration topics, such as seting up keystores and a truststore for the {project_name} server, creating an administrator account, an overview of available {project_name} client registration methods, and guidance on configuring clustering. === Requirements and Deploying xref:../introduction/introduction.adoc#passthrough-templates[Passthrough TLS Termination] {project_name} Templates ==== Preparing the Deployment Log in to the OpenShift CLI with a user that holds the _cluster:admin_ role. . Create a new project: + [source,bash,subs="attributes+,macros+"] ---- $ oc new-project sso-app-demo ---- . Add the `view` role to the link:https://docs.openshift.com/container-platform/latest/dev_guide/service_accounts.html#default-service-accounts-and-roles[`default`] service account. This enables the service account to view all the resources in the sso-app-demo namespace, which is necessary for managing the cluster. + [source,bash,subs="attributes+,macros+"] ---- $ oc policy add-role-to-user view system:serviceaccount:$(oc project -q):default ---- [[advanced-concepts-Configuring-Keystores]] ==== Creating HTTPS and JGroups Keystores, and Truststore for the {project_name} Server The {project_name} application templates using xref:../introduction/introduction.adoc#passthrough-templates[passthrough TLS termination] require: * An xref:create-https-keystore[HTTPS keystore] used for encryption of https traffic, * The xref:create-jgroups-keystore[JGroups keystore] used for encryption of JGroups communications between nodes in the cluster, and * xref:create-server-truststore[{project_name} server truststore] used for securing the {project_name} requests the {project_openshift_product_name} image to be deployed properly. [IMPORTANT] ==== The {project_name} application templates using xref:../introduction/introduction.adoc#reencrypt-templates[re-encryption TLS termination] do not *require* or *expect* the aforementioned HTTPS and JGroups keystores and {project_name} server truststore to be prepared beforehand. The templates use OpenShift's internal link:https://docs.openshift.com/container-platform/latest/dev_guide/secrets.html#service-serving-certificate-secrets[service serving x509 certificate secrets] to automatically create the HTTPS and JGroups keystores. The {project_name} server truststore is also created automatically, containing the */var/run/secrets/kubernetes.io/serviceaccount/service-ca.crt* CA certificate file, which is used to create these cluster certificates. Moreover, the truststore for the {project_name} server is pre-populated with the all known, trusted CA certificate files found in the Java system path. ==== The *_openssl_* toolkit is used in the following example to generate a CA certificate to sign the HTTPS keystore, and create a truststore for the {project_name} server. *_keytool_*, a package *included with the Java Development Kit*, is then utilized to the generate self-signed certificates for these keystores. [WARNING] ==== For production environments Red Hat recommends that you use your own SSL certificate purchased from a verified Certificate Authority (CA) for SSL-encrypted connections (HTTPS). See the https://access.redhat.com/documentation/en-us/jboss_enterprise_application_platform/6.1/html-single/security_guide/index#Generate_a_SSL_Encryption_Key_and_Certificate[JBoss Enterprise Application Platform Security Guide] for more information on how to create a keystore with self-signed or purchased SSL certificates. ==== [[create-https-keystore]] *_Create the HTTPS keystore:_* [[generate-ca-certificate]] .. Generate a CA certificate. Pick and remember the password. Provide identical password, when xref:signing-csr-with-ca-certificate[signing the certificate sign request with the CA certificate] below: + [source,bash,subs="attributes+,macros+"] ---- $ openssl req -new -newkey rsa:4096 -x509 -keyout xpaas.key -out xpaas.crt -days 365 -subj "/CN=xpaas-sso-demo.ca" ---- .. Generate a CA certificate for the HTTPS keystore. Provide `mykeystorepass` as the keystore password: + [source,bash,subs="attributes+,macros+"] ---- $ keytool -genkeypair -keyalg RSA -keysize 2048 -dname "CN=secure-sso-sso-app-demo.openshift.example.com" -alias jboss -keystore keystore.jks ---- .. Generate a certificate sign request for the HTTPS keystore. Provide `mykeystorepass` as the keystore password: + [source,bash,subs="attributes+,macros+"] ---- $ keytool -certreq -keyalg rsa -alias jboss -keystore keystore.jks -file sso.csr ---- [[signing-csr-with-ca-certificate]] [start=4] .. Sign the certificate sign request with the CA certificate. Provide the same password that was used to xref:generate-ca-certificate[generate the CA certificate]: + [source,bash,subs="attributes+,macros+"] ---- $ openssl x509 -req -CA xpaas.crt -CAkey xpaas.key -in sso.csr -out sso.crt -days 365 -CAcreateserial ---- .. Import the CA certificate into the HTTPS keystore. Provide `mykeystorepass` as the keystore password. Reply `yes` to `Trust this certificate? [no]:` question: + [source,bash,subs="attributes+,macros+"] ---- $ keytool -import -file xpaas.crt -alias xpaas.ca -keystore keystore.jks ---- .. Import the signed certificate sign request into the HTTPS keystore. Provide `mykeystorepass` as the keystore password: + [source,bash,subs="attributes+,macros+"] ---- $ keytool -import -file sso.crt -alias jboss -keystore keystore.jks ---- [[create-jgroups-keystore]] *_Generate a secure key for the JGroups keystore:_* Provide `password` as the keystore password: [source,bash,subs="attributes+,macros+"] ---- $ keytool -genseckey -alias secret-key -storetype JCEKS -keystore jgroups.jceks ---- [[create-server-truststore]] *_Import the CA certificate into a new {project_name} server truststore:_* Provide `mykeystorepass` as the truststore password. Reply `yes` to `Trust this certificate? [no]:` question: [source,bash,subs="attributes+,macros+"] ---- $ keytool -import -file xpaas.crt -alias xpaas.ca -keystore truststore.jks ---- [[Configuring-Secrets]] ==== Secrets OpenShift uses objects called link:https://docs.openshift.com/container-platform/latest/dev_guide/secrets.html[secrets] to hold sensitive information, such as passwords or keystores. . Create the secrets for the HTTPS and JGroups keystores, and {project_name} server truststore, generated in the xref:Configuring-Keystores[previous section]. + [source,bash,subs="attributes+,macros+"] ---- $ oc secret new sso-app-secret keystore.jks jgroups.jceks truststore.jks ---- . Link these secrets to the link:https://docs.openshift.com/container-platform/latest/dev_guide/service_accounts.html#default-service-accounts-and-roles[default] service account, which is used to run {project_name} pods. + [source,bash,subs="attributes+,macros+"] ---- $ oc secrets link default sso-app-secret ---- ==== Deploying the Chosen {project_name} Passthrough TLS Template via OpenShift CLI After the aforementioned xref:Configuring-Keystores[keystores] and xref:Configuring-Secrets[secrets] are created, deploy some of the available xref:../introduction/introduction.adoc#passthrough-templates[passthrough TLS termination] as follows: [WARNING] ==== For simplicity, the values of *_SSO_ADMIN_USERNAME_*, *_SSO_ADMIN_PASSWORD_*, *_HTTPS_PASSWORD_*, *_JGROUPS_ENCRYPT_PASSWORD_*, and *_SSO_TRUSTSTORE_PASSWORD_* variables xref:advanced-topics-deploy-{project_templates_version}-https-template[in the following command] have been chosen to match the default values of the respective parameters of the *_{project_templates_version}-https_* {project_name} application template. For production environments, Red Hat recommends that you consult the on-site policy, specific to your organization for guidance on how to generate sufficiently strong user name and password for the administrator user account of the {project_name} server, and passwords for the HTTPS and JGroups keystores, and the truststore of the {project_name} server. Be aware that *the passwords provided when provisioning the template need to match the passwords provided when creating the keystores*. If using different username and passwords, modify the values of respective xref:advanced-topics-deploy-{project_templates_version}-https-template[template parameters] as appropriate for your environment. ==== [NOTE] ==== The following commands using the *_keytool_*, a package *included with the Java Development Kit*, can be used to determine the names associated with the certificate: [source,bash,subs="attributes+,macros+"] ---- $ keytool -v -list -keystore keystore.jks | grep Alias Enter keystore password: mykeystorepass Alias name: xpaas.ca Alias name: jboss ---- [source,bash,subs="attributes+,macros+"] ---- $ keytool -v -list -keystore jgroups.jceks -storetype jceks | grep Alias Enter keystore password: password Alias name: secret-key ---- Finally, the *_SSO_ADMIN_USERNAME_*, *_SSO_ADMIN_PASSWORD_*, and the *_SSO_REALM_* template parameters in the following command are optional. ==== [[advanced-topics-deploy-{project_templates_version}-https-template]] [source,bash,subs="attributes+,macros+"] ---- $ oc new-app --template={project_templates_version}-https \ -p HTTPS_SECRET="sso-app-secret" \ -p HTTPS_KEYSTORE="keystore.jks" \ -p HTTPS_NAME="jboss" \ -p HTTPS_PASSWORD="mykeystorepass" \ -p JGROUPS_ENCRYPT_SECRET="sso-app-secret" \ -p JGROUPS_ENCRYPT_KEYSTORE="jgroups.jceks" \ -p JGROUPS_ENCRYPT_NAME="secret-key" \ -p JGROUPS_ENCRYPT_PASSWORD="password" \ -p SSO_ADMIN_USERNAME="admin" \ -p SSO_ADMIN_PASSWORD="redhat" \ -p SSO_REALM="demorealm" \ -p SSO_TRUSTSTORE="truststore.jks" \ -p SSO_TRUSTSTORE_PASSWORD="mykeystorepass" \ -p SSO_TRUSTSTORE_SECRET="sso-app-secret" --> Deploying template "openshift/{project_templates_version}-https" to project sso-app-demo {project_name} {project_version} (Ephemeral with passthrough TLS) --------- An example {project_name} 7 application. For more information about using this template, see \https://github.com/jboss-openshift/application-templates. A new {project_name} service has been created in your project. The admin username/password for accessing the master realm via the {project_name} console is admin/redhat. Please be sure to create the following secrets: "sso-app-secret" containing the keystore.jks file used for serving secure content; "sso-app-secret" containing the jgroups.jceks file used for securing JGroups communications; "sso-app-secret" containing the truststore.jks file used for securing {project_name} requests. * With parameters: * Application Name=sso * Custom http Route Hostname= * Custom https Route Hostname= * Server Keystore Secret Name=sso-app-secret * Server Keystore Filename=keystore.jks * Server Keystore Type= * Server Certificate Name=jboss * Server Keystore Password=mykeystorepass * Datasource Minimum Pool Size= * Datasource Maximum Pool Size= * Datasource Transaction Isolation= * JGroups Secret Name=sso-app-secret * JGroups Keystore Filename=jgroups.jceks * JGroups Certificate Name=secret-key * JGroups Keystore Password=password * JGroups Cluster Password=yeSppLfp # generated * ImageStream Namespace=openshift * {project_name} Administrator Username=admin * {project_name} Administrator Password=redhat * {project_name} Realm=demorealm * {project_name} Service Username= * {project_name} Service Password= * {project_name} Trust Store=truststore.jks * {project_name} Trust Store Password=mykeystorepass * {project_name} Trust Store Secret=sso-app-secret * Container Memory Limit=1Gi --> Creating resources ... service "sso" created service "secure-sso" created service "sso-ping" created route "sso" created route "secure-sso" created deploymentconfig "sso" created --> Success Run 'oc status' to view your app. ---- ==== Accessing the Administrator Console of the {project_name} Pod After the template got deployed, identify the available routes: [source,bash,subs="attributes+,macros+"] ---- $ oc get routes ---- [cols="7",options="header"] |=== |NAME |HOST/PORT |PATH |SERVICES |PORT |TERMINATION |WILDCARD |secure-sso |secure-sso-sso-app-demo.openshift.example.com | |secure-sso | |passthrough |None |sso |sso-sso-app-demo.openshift.example.com | |sso | | |None |=== and access the {project_name} administrator console at: * *\https://secure-sso-sso-app-demo.openshift.example.com/auth/admin* * *\http://sso-sso-app-demo.openshift.example.com/auth/admin* using the xref:sso-administrator-setup[administrator account]. [[advanced-concepts-sso-hostname-spi-setup]] === Customizing Hostname for the {project_name} Server The hostname SPI introduced a flexible way to configure the hostname for the {project_name} server. There are two built-in providers. The first is `request`, which uses the request headers to determine the hostname. This is the *default setting* for {project_openshift_product_name} image. The second is `fixed`, which allows configuring a fixed hostname. The latter makes sure that only valid hostnames can be used and allows internal applications to invoke {project_name} server through an alternative URL. Run the following commands to set the `fixed` hostname SPI provider for the {project_name} server: . Deploy the {project_openshift_product_name} image with *_SSO_HOSTNAME_* environment variable set to the desired hostname of the {project_name} server. + ---- $ oc new-app --template=sso-cd-x509-https \ -p SSO_HOSTNAME="rh-sso-server.openshift.example.com" ---- . Identify the name of the route for the {project_name} service. + ---- $ oc get routes ---- + [cols="7",options="header"] |=== |NAME |HOST/PORT |PATH |SERVICES |PORT |TERMINATION |WILDCARD |sso |sso-sso-app-demo.openshift.example.com | |sso | |reencrypt |None |=== . Change the `host:` field to match the hostname specified as the value of the *_SSO_HOSTNAME_* environment variable above. + [NOTE] ==== Adjust the `rh-sso-server.openshift.example.com` value in the following command as necessary. ==== + ---- $ oc patch route/sso --type=json -p '[{"op": "replace", "path": "/spec/host", "value": "rh-sso-server.openshift.example.com"}]' ---- + If successful, the previous command will return the following output: + ---- route "sso" patched ---- [[sso-administrator-setup]] === Creating the Administrator Account for {project_name} Server {project_name} does not provide any pre-configured management account out of the box. This administrator account is necessary for logging into the `master` realm's management console and perform server maintenance operations such as, creating realms or users, or registering applications intended to be secured by {project_name}. The administrator account can be created: * By providing values for the xref:sso-admin-template-parameters[*_SSO_ADMIN_USERNAME_* and *_SSO_ADMIN_PASSWORD_* parameters], when deploying the {project_name} application template, or * By xref:sso-admin-remote-shell[a remote shell session to particular {project_name} pod], if the {project_openshift_product_name} image is deployed without an application template. [NOTE] ==== {project_name} allows an initial administrator account to be created via the link:https://access.redhat.com/documentation/en-us/red_hat_single_sign-on/7.2/html-single/getting_started_guide/#creating_the_admin_account[Welcome Page] web form, but only if the Welcome Page is accessed from localhost; this method of administrator account creation is not applicable for the {project_openshift_product_name} image. ==== [[sso-admin-template-parameters]] ==== Creating the Administrator Account Using Template Parameters When deploying {project_name} application template, the *_SSO_ADMIN_USERNAME_* and *_SSO_ADMIN_PASSWORD_* parameters denote the username and password of the {project_name} server's administrator account to be created for the `master` realm. [NOTE] ==== *Both of these parameters are required.* If not specified, they are auto generated and displayed as an OpenShift instructional message when the template is instantiated. ==== [IMPORTANT] ==== The lifespan of the {project_name} server's administrator account depends upon the storage type used to store the {project_name} server's database: * For an in-memory database mode (*_{project_templates_version}-https_* and *_{project_templates_version}-x509-https_* templates) the account exists throughout the lifecycle of the particular {project_name} pod (stored account data is lost upon pod destruction), * For an ephemeral database mode (*_{project_templates_version}-mysql_* and *_{project_templates_version}-postgresql_* templates) the account exists throughout the lifecycle of the database pod (even if the {project_name} pod is destructed, the stored account data is preserved under the assumption that the database pod is still running), * For persistent database mode (*_{project_templates_version}-mysql-persistent_*, *_{project_templates_version}-x509-mysql-persistent_*, *_{project_templates_version}-postgresql-persistent_*, and *_{project_templates_version}-x509-postgresql-persistent_* templates) the account exists throughout the lifecycle of the persistent medium used to hold the database data. This means that the stored account data is preserved even when both the {project_name} and the database pods are destructed. It is a common practice to deploy an {project_name} application template to get the corresponding OpenShift deployment config for the application, and then reuse that deployment config multiple times (every time a new {project_name} application needs to be instantiated). ==== [WARNING] ==== In the case of *ephemeral or persistent database mode*, after creating the RH_SSO server's administrator account, remove the *_SSO_ADMIN_USERNAME_* and *_SSO_ADMIN_PASSWORD_* variables from the deployment config before deploying new {project_name} applications. ==== [IMPORTANT] ==== Run the following commands to prepare the previously created deployment config of the {project_name} application for reuse after the administrator account has been created: . Identify the deployment config of the {project_name} application. + [source,bash,subs="attributes+,macros+"] ---- $ oc get dc -o name deploymentconfig/sso deploymentconfig/sso-mysql ---- . Clear the *_SSO_ADMIN_USERNAME_* and *_SSO_ADMIN_PASSWORD_* variables setting. + [source,bash,subs="attributes+,macros+"] ---- $ oc set env dc/sso \ -e SSO_ADMIN_USERNAME="" \ -e SSO_ADMIN_PASSWORD="" ---- ==== [[sso-admin-remote-shell]] ==== Creating the Administrator Account via Remote Shell Session to {project_name} Pod Run following commands to create an administrator account for the `master` realm of the {project_name} server, when deploying the {project_openshift_product_name} image directly from the image stream (without the xref:../introduction/introduction.adoc#sso-templates[template]), after the {project_name} application pod has been started: . Identify the {project_name} application pod. + [source,bash,subs="attributes+,macros+"] ---- $ oc get pods NAME READY STATUS RESTARTS AGE sso-12-pt93n 1/1 Running 0 1m sso-mysql-6-d97pf 1/1 Running 0 2m ---- . Open a remote shell session to the {project_openshift_product_name} container. + [source,bash,subs="attributes+,macros+"] ---- $ oc rsh sso-12-pt93n sh-4.2$ ---- . Create the {project_name} server administrator account for the `master` realm at the command line with the `add-user-keycloak.sh` script. + [source,bash,subs="attributes+,macros+"] ---- sh-4.2$ cd /opt/eap/bin/ sh-4.2$ ./add-user-keycloak.sh \ -r master \ -u sso_admin \ -p sso_password Added 'sso_admin' to '/opt/eap/standalone/configuration/keycloak-add-user.json', restart server to load user ---- + [NOTE] ==== The 'sso_admin' / 'sso_password' credentials in the example above are for demonstration purposes only. Refer to the password policy applicable within your organization for guidance on how to create a secure user name and password. ==== . Restart the underlying JBoss EAP server instance to load the newly added user account. Wait for the server to restart properly. + [source,bash,subs="attributes+,macros+"] ---- sh-4.2$ ./jboss-cli.sh --connect ':reload' { "outcome" => "success", "result" => undefined } ---- + [WARNING] ==== When restarting the server it is important to restart just the JBoss EAP process within the running {project_name} container, and not the whole container. This is because restarting the whole container will recreate it from scratch, without the {project_name} server administration account for the `master` realm. ==== . Log in to the `master` realm's administration console of the {project_name} server using the credentials created in the steps above. In the browser, navigate to *\http://sso-./auth/admin* for the {project_name} web server, or to *\https://secure-sso-./auth/admin* for the encrypted {project_name} web server, and specify the user name and password used to create the administrator user. === Deployment Process Once deployed, the *_{project_templates_version}-https_* and *_{project_templates_version}-x509-https_* templates create a single pod that contains both the database and the {project_name} servers. The *_{project_templates_version}-mysql_*, *_{project_templates_version}-mysql-persistent_*, *_{project_templates_version}-x509-mysql-persistent_*, *_{project_templates_version}-postgresql_*, *_{project_templates_version}-postgresql-persistent_*, and *_{project_templates_version}-x509-postgresql-persistent_* templates create two pods, one for the database server and one for the {project_name} web server. After the {project_name} web server pod has started, it can be accessed at its custom configured hostnames, or at the default hostnames: * *\http://sso-__.__/auth/admin*: for the {project_name} web server, and * *\https://secure-sso-__.__/auth/admin*: for the encrypted {project_name} web server. Use the xref:sso-administrator-setup[administrator user credentials] to log in into the `master` realm’s administration console. [[SSO-Clients]] === {project_name} Clients Clients are {project_name} entities that request user authentication. A client can be an application requesting {project_name} to provide user authentication, or it can be making requests for access tokens to start services on behalf of an authenticated user. See the link:https://access.redhat.com/documentation/en-us/red_hat_single_sign-on/7.2/html/server_administration_guide/clients[Managing Clients chapter of the {project_name} documentation] for more information. {project_name} provides link:https://access.redhat.com/documentation/en-us/red_hat_single_sign-on/7.2/html/server_administration_guide/clients#oidc_clients[OpenID-Connect] and link:https://access.redhat.com/documentation/en-us/red_hat_single_sign-on/7.2/html/server_administration_guide/clients#saml_clients[SAML] client protocols. + OpenID-Connect is the preferred protocol and utilizes three different access types: - *public*: Useful for JavaScript applications that run directly in the browser and require no server configuration. - *confidential*: Useful for server-side clients, such as EAP web applications, that need to perform a browser login. - *bearer-only*: Useful for back-end services that allow bearer token requests. It is required to specify the client type in the ** key of the application *web.xml* file. This file is read by the image at deployment. Set the value of ** element to: * *KEYCLOAK* for the OpenID Connect client. * *KEYCLOAK-SAML* for the SAML client. The following is an example snippet for the application *web.xml* to configure an OIDC client: [source,bash,subs="attributes+,macros+"] ---- ... KEYCLOAK ... ---- [[Auto-Man-Client-Reg]] ==== Automatic and Manual {project_name} Client Registration Methods A client application can be automatically registered to an {project_name} realm by using credentials passed in variables specific to the *_eap64-sso-s2i_*, *_eap71-sso-s2i_*, and *_datavirt63-secure-s2i_* templates. Alternatively, you can manually register the client application by configuring and exporting the {project_name} client adapter and including it in the client application configuration. ===== Automatic {project_name} Client Registration Automatic {project_name} client registration is determined by {project_name} environment variables specific to the *_eap64-sso-s2i_*, *_eap71-sso-s2i_*, and *_datavirt63-secure-s2i_* templates. The {project_name} credentials supplied in the template are then used to register the client to the {project_name} realm during deployment of the client application. The {project_name} environment variables included in the *_eap64-sso-s2i_*, *_eap71-sso-s2i_*, and *_datavirt63-secure-s2i_* templates are: [cols="2*", options="header"] |=== |Variable |Description |*_HOSTNAME_HTTP_* |Custom hostname for http service route. Leave blank for default hostname of .. |*_HOSTNAME_HTTPS_* |Custom hostname for https service route. Leave blank for default hostname of .. |*_SSO_URL_* |The {project_name} web server authentication address: $$https://secure-sso-$$__.__/auth |*_SSO_REALM_* |The {project_name} realm created for this procedure. |*_SSO_USERNAME_* |The name of the _realm management user_. |*_SSO_PASSWORD_* | The password of the user. |*_SSO_PUBLIC_KEY_* |The public key generated by the realm. It is located in the *Keys* tab of the *Realm Settings* in the {project_name} console. |*_SSO_BEARER_ONLY_* |If set to *true*, the OpenID Connect client is registered as bearer-only. |*_SSO_ENABLE_CORS_* |If set to *true*, the {project_name} adapter enables Cross-Origin Resource Sharing (CORS). |=== If the {project_name} client uses the SAML protocol, the following additional variables need to be configured: [cols="2*", options="header"] |=== |Variable |Description |*_SSO_SAML_KEYSTORE_SECRET_* |Secret to use for access to SAML keystore. The default is _sso-app-secret_. |*_SSO_SAML_KEYSTORE_* |Keystore filename in the SAML keystore secret. The default is _keystore.jks_. |*_SSO_SAML_KEYSTORE_PASSWORD_* |Keystore password for SAML. The default is _mykeystorepass_. |*_SSO_SAML_CERTIFICATE_NAME_* |Alias for keys/certificate to use for SAML. The default is _jboss_. |=== See xref:Example-EAP-Auto[Example Workflow: Automatically Registering EAP Application in {project_name} with OpenID-Connect Client] for an end-to-end example of the automatic client registration method using an OpenID-Connect client. ===== Manual {project_name} Client Registration Manual {project_name} client registration is determined by the presence of a deployment file in the client application's _../configuration/_ directory. These files are exported from the client adapter in the {project_name} web console. The name of this file is different for OpenID-Connect and SAML clients: [horizontal] *OpenID-Connect*:: _../configuration/secure-deployments_ *SAML*:: _../configuration/secure-saml-deployments_ These files are copied to the {project_name} adapter configuration section in the _standalone-openshift.xml_ at when the application is deployed. There are two methods for passing the {project_name} adapter configuration to the client application: * Modify the deployment file to contain the {project_name} adapter configuration so that it is included in the _standalone-openshift.xml_ file at deployment, or * Manually include the OpenID-Connect _keycloak.json_ file, or the SAML _keycloak-saml.xml_ file in the client application's *../WEB-INF* directory. See xref:Example-EAP-Manual[Example Workflow: Manually Configure an Application to Use {project_name} Authentication, Using SAML Client] for an end-to-end example of the manual {project_name} client registration method using a SAML client. === Limitations OpenShift does not currently accept OpenShift role mapping from external providers. If {project_name} is used as an authentication gateway for OpenShift, users created in {project_name} must have the roles added using the OpenShift Administrator `oc adm policy` command. For example, to allow an {project_name}-created user to view a project namespace in OpenShift: [source,bash,subs="attributes+,macros+"] ---- $ oc adm policy add-role-to-user view -n ----