Security
Configure and Test Mail Server
When identity is added, an email is sent with randomly generated password to the user. When a user wants to change the email or password, a verification is sent via email as well.
If you have not set up an email server, the default behaviour is to store the emails in the “/mail” folder within the software. This is usually for diagnosis or debugging purposes. It is recommended to set up a mail server at the start.
Below are two examples of how to set up a mail server.
Example 1: Uses Gmail
-
Gmail allows only OAuth2 authentication without weakening security. Visit https://console.developers.google.com/apis/credentails to set up a “clientID” and “clientSecret”. Use these to generate a “refreshToken”.
-
In the software root folder, navigate to the “/etc” folder. Open the application.conf file using a text editor. In the elixir.mail section, edit the following with the information obtained earlier accordingly.
elixir.mail { smtp = "gmail" gmail { host = "smtp.gmail.com" port = 587 debug = true oauth2 { userName = "xxx@gmail.com" clientId = "XXXX" clientSecret = "YYYY" refreshToken = "ZZZZ" } } } -
Save the above edits in the application.conf file and start the server. New users with valid email addresses can now be created in the Identities module.
Example 2: Uses AWS
-
In the software root folder, navigate to the “/etc” folder. Open the application.conf file using a text editor. In the “elixir.mail” section, edit the following:
elixir.mail { smtp = "aws" aws { from = "<user@example.com>" host = "<hostname>" dnsResolver = "" port = 465 user = "XXXX" password = "YYYY" connectionTimeout = 30000 tls = true ssl = true authMechanism = "" debug = false } } -
Save the above edits in the application.conf file and start the server. New users with valid email addresses can now be created in the Identities module.
Use GitLab As Authentication
The Identities module in Ambience software provides a simple mechanism for authentication (determining who is logging in). If you already have an authentication system, such as an SSO, LDAP or Active Directory, then it is possible to use that as the authentication mechanism. This identity management system is built upon OAuth2, which is what makes it possible to plug in alternate authentication providers.
If an external authentication system is used, the Identities module is not needed and should be removed to avoid confusion.
This section describes the steps to set up GitLab as the authentication method to log into the software.
The steps are as follows:
-
Create an account in GitLab.
-
In GitLab, add the software as an application under your user.
Note: The URL callback should be http://hostname:1740/authclient for Ambience. Use port 1730 for Repertoire. This is consistent with the setting in the application.conf file.
-
Change the hostname on your machine to point to the proper endpoint (i.e., the added application).
-
Add the user into Users module with the same name that was created in the GitLab server.
-
Go to the software root directory and go to the “/etc” folder. Open the application.conf file using a text editor.
-
Make the following changes in the elixir.sso.client section.
elixir.sso.client { cookie-name = "elx-amb" cookie-same-site = "Lax" openid-field = "name" openid-scope = "openid email" service-definition { elxsso { authorization = "https://<gitlab-host>/oauth/authorize" token = "https://<gitlab-host>/oauth/token" userinfo = "https://<gitlab-host>/oauth/userinfo" logout = ${sso-server-baseurl}"/simple-sso/logout" debug = false client { id = "[Your Application ID]" secret = "[Your secret]" endpoint = ${sso-client-baseurl}"/authclient" } } } } -
Save the application.conf file.
-
Restart the software server. Open a browser and key in “Localhost 1740” in the address bar and hit the enter key.
For Repertoire, key in “localhost:1730” in the address bar.
-
Log into the software using the GitLab account.
Two-factor Authentication
Ambience/Repertoire software supports Time-based One-time Password (TOTP) Two-factor Authentication (2FA). By default, 2FA is disabled in the application.conf file. To enable 2FA, edit the application.conf file in two areas:
-
Under the simple-server section, change show-totp = false to true. This is to allow the login dialog to include 2FA.
simple-server { clients { ambience { secret = "171ccf22-670a-43c2-ac79-05c44bf305e3" redirect = ${sso-client-baseurl}"/authclient" #login-page = "" # set resource file here to use a custom login page for this client landing-page = "http://${host}:${port}/" name = "Elixir Ambience" show-totp = true } } } -
Add a new line in the application.conf file. This will allow User Settings module to include 2FA setup, in which users can set up their own 2FA.
ambience.user-settings.enable-panel.totp = true
Passwords
For First Login
When the user logs in with the randomly generated password (i.e., first login), they will be forced to change the password immediately. This can be disabled by editing the setting in the application.conf file. In the elixir.identity section, edit the changePassword: true to false.
elixir.identity {
...
on-reset {
changePassword: true
}
}
The above applies to all users. To allow certain users not to force change their password, grant them mod-no-password-change privilege using the Users module.
Using Login Dialog
Any user can reset their own password using the login dialog. The new password will be sent to the user’s email.
Login Failure Delay
When there is an error during login, an error message will appear in the login dialog box immediately, allowing user to re-login again.
To delay the login, in the application.conf file, add the following line:
Ambience.simple-sso.delay-failed-login : 0 seconds
Change the value to the desired value. A spinner will appear in the login dialog box till the delayed time is up, allowing the user to login again.
Password Policy
Strong password protects your system from hackers and malicious software. Some passwords may appear strong but are relatively easily guessed. Key aspects of a strong password are length (the longer the better), a mix of letters (upper and lower case), numbers and symbols, and no ties to your personal or corporate information.
The elixir.identity.password-policy section in application.conf file allows administrators to define the policy of the password to be used in the software suite.
elixir.identity {
...
password-policy {
minLength: 1
maxLength: 0
...
mustHaveSymbolSet: ""
...
disallowedRegex: []
}
}
The minimum and maximum length of the password, whether to use upper and/or lower case characters, wheether to include digit or symbol, and disallow certain regular expressions, etc. can be defined in this section.
It may be advisable to disallow common passwords based on regular expressions, so that users are not able to set common passwords. A common password for one organisation may be very different from the next. Rather than a fixed list of regular expressions, administrators can decide in the list of regular expressions that should be disallowed.
The disallowedRegex field is empty by default. You can add your desired regular expression to disallow in the brackets.
Below is an example to disallow both “password” and “passw0rd” (with a zero instead if an o), as well as any password that starts with “e1” (a common elixir easily guessed example).
disallowedRegex: ["passw[o0]rd", "e1.*"]
Customise Password Email
You can customise the content of the email to be sent to the user when the user resets his/her password or when new user is added.
In the application.conf file, add the following:
elixir.simple-identity {
email (
subject = "Elixir Password"
add-account = "<html><p>An account has been created for you in toolTitle at <a href=`${landingPage}`>localhost:1740</a>.</p><p>Your user name is ${name}, your password is ${password}</p><p>Please login and change it.</p></html>"
reset-account = "<html><p>Your password has been reset in toolTitle at <a href=`${landingPage}`>localhost:1740</a>.</p><p>Your user name is ${name}, your password is ${password}</p><p>Please login and change it.</p></html>"
)
}
For Repertoire, change the port to 1730.
Customise Password Verification Email
You can customise the content of the email to be sent to the user when the user changes his/her password or email address.
In the application.conf file, add the following:
ambience.user-settings.email.password-change {
subject = "Customised Password Change Verification"
body = "<h2>Elixir Ambience Password Change</h2><p>A change of password has been requested by ${name}.</p><p>Please enter this approval code on the change password page:</p><p>${code}</p><p>If you are an Elixir user and did not request this change, please contact your administrator.</p><p>If you take no further action, the password change will be rejected.</p>"
}
ambience.user-settings.email.password-change {
subject = "Customised Address Verification"
body = "<h2>Elixir Ambience Email Change</h2><p>A change of email address has been requested by ${name}.</p><p>Changed from ${oldEmail} to ${newEmail}.</p><p>Please enter this approval code on the change email page:</p><p>${code}</p><p>If you are an Elixir user and did not request this change, please contact your administrator.</p><p>If you take no further action, the password change will be rejected.</p>"
}
Customise Password Reset Email
You can customise the content of the email to be sent to the user when the user resets his/her password.
In the application.conf file, add the following:
elixir.sso.server {
email.password-reset {
subject = "Elixir Password Reset Request: ${clientTitle} user: ${name}"
body = "<html><p>${clientTitle} Password Reset Request for user ${name}</p><p>If you have requested a password reset, please click the following link:</p><p><a href=`${resetPage}`>${resetPage}</a></p><p>If you have not requested a password reset, you can choose to ignore this mail, no change has been made yet, or report to your administrator as someone has requested a reset for an account with this email address.</p></html>"
}
}
Localise Password Reset Request Information
The password reset request information by default is in English. This information can be localised to the language of the user.
To do so, add the i18n localisation file onto the “etc/i18n/” folder.
The i18n localisation file has the filename simple-sso_XX.properties. where “Xx” is the abbreviation of the language.
Below is a sample of the i18n localisation file simple-sso_zh.properties.
PasswordResetRequestAccepted = 密码重置已提交,请查阅邮件。
CannotResetPassword = 所提供信息不足重置密码。请联系系统管理员。
PasswordResetEmail = 您的密码已重置。请查阅邮件。
InvalidConfirmationCode = 确认码无效。
CookieMismatch = 不匹配,请再试一次。
RequestDenied = 请求拒绝,请联系您的系统管理员。
Restart the server and change the browser default language to the language desired. When the user resets his/her password, if the new password does not conform to the password policy, the appropriate error message will appear.
Localise Password Policy Message
To localise the language of the password policy messages, perform the following:
-
Add the i18n localised file onto the “etc/i18n/” folder. The i18n file should have a filename user-settings_XX.properties, where XX is the abbreviation of the language. Below is an example of the content of a i18n file.
PasswordPolicy.6001 = DEPasswordPolicy DatabaseError PasswordPolicy.6020 = DEPasswordPolicy passwort muss mindestens ${minLength} Zeichen enthalten PasswordPolicy.6021 = DEPasswordPolicy passwort darf nicht mehr als ${maxLength} Zeichen enthanlten PasswordPolicy.6022 = DEPasswordPolicy passwort enthält ein unzulässiges Symbol: ${mustNotHaveSymbolSet} PasswordPolicy.6023 = DEPasswordPolicy passwort muss eine Ziffer enthalten PasswordPolicy.6024 = DEPasswordPolicy passwort muss einen Großbuchstaben enthalten PasswordPolicy.6025 = DEPasswordPolicy passwort muss einen Kleinbuchstaben enthalten PasswordPolicy.6026 = DEPasswordPolicy passwort muss ein Symbol aus enthalten: ${mustHaveSymbolSet} PasswordPolicy.6027 = DEPasswordPolicy passwörter dürfen nicht mit dem Benutzernamen identisch sein PasswordPolicy.6028 = DEPasswordPolicy Dieses Passwort wurde bereits verwendet PasswordPolicy.6029 = DEPasswordPolicy Dieses Passwort gilt als unsicher -
In the application.conf file, edit the following to match the conditions above:
elixir.identity { user-collection: "Identities" password-policy { minLength:3 maxLength:8 notSameAsLogon:true maxPasswordExpiresDays:0 differentPasswordCount:0 mustHaveDigit:true mustHaveUpperCase:true mustHaveLowerCase:true mustHaveSymbolSet:"" mustNotHaveSymbolSet:"" retryAttemptLockoutCount:0 disallowedRegex:["passw[o0]rd","e1.*"] } on-add { changePassword:false } on-reset { changePassword:false } } -
Restart the server and change the language settings to the desired language in the browser.
-
To test the localisation, login to the server and change the password that conflict one of the conditions in the i18n file. A message should appear.
Password Reset Confirmation URL Expiry Time
The password confirmation URL expiry time can be customised to suit each system’s requirements. The expiry time can be customised in the application.conf file. There are three scenarios:
- Request password reset
- Change password
- Forget password
In the application.conf file, add the following line in the elixir.sso.server session:
elixir.sso.server {
cookie-name = "elxsso"
...
reset-link-expiry = 10 minutes
...
}
This sets the expiry time of the reset link. Change the value to the desired value.
To customise reset code expiry time, add the following in the application.conf file.
ambience.user-settings.reset-code-expiry = 10 minutes
This will set the expiry code sent to expire in 10 minutes.
For the “Forgot password” scenario, both are used.
Password Validation Code
Each time a password reset is requested, a code will be sent to the user’s email.
This code has an expiry time of five minutes (default). Depending on your system, this timing may not be long enough. This timing can be changed in the application.conf file.
ambience.user-settings.reset-code-expiry = x minutes
where x is the desired value.
To turn off the email that sends this code, set reset-code-expiry to 0.
This will allow the password to be changed immediately upon request with no further verification. Thus, providing a workaround for very laggy email systems (e.g., spam quarantine, etc).
User Name Case Sensitivity
The user names created in the Users module are by default case sensitive. This is embedded in the elixir.sso.client section in the application.conf file as below:
elixir.sso.client {
...
openid-case = ""
...
}
The default value for openid-case is empty (""), which indicates case sensitive.
The other values that can be used are “UPPER” (for upper case) and “lower” (for lower case)
For example, if the usernames are uppercase, then change the openid-case value to “UPPER”, and any MixedCase strings from the Identity module will become MIXEDCASE.
Deploy Server With Customised Initial User
When a server is deployed, a customised initial user may be setup. This can be done using either one of the following methods.
Hard-coding Initial User
This method “hard-code” the initial user in the application.conf file. To do so, perform the following:
-
Ensure the server does not have any existing Users and Identities.
-
In the application.conf file, add the following:
ambience.initial-user { name = "not-admin" password = "not-sa" }
Use “bin/ambience-cli” to encrypt the above if desired.
- Then start the server and login with the above credentials.
Parameterised Initial User
This method uses parameters in a docker to customise the initial user. To do so, perform the following:
-
Ensure the server does not have any existing Users and Identities.
-
In the application.conf file, add the following:
ambience.initial-user { name = $[?AMBIENCE_INITIAL_USERNAME] password = $[?AMBIENCE_INITIAL_PASSWORD] } -
In the “docker-compose.yml” file, add the following environment values under the Ambience portion:
- AMBIENCE_NITIAL_USERNAME=not-admin - AMBIENCE_NITIAL_PASSWORD=not-sa -
Then restart the docker and login with the above credentials.
Enforce Single Session
Some systems may prefer to allow only single session log in.
To do so, perform the following to enforce single session login.
-
In the application.conf file, add the line in bold in the ambience.web session:
ambience.web { ... session-timeout = 15 minutes enforce-single-session = true ... } -
In the elixir.sso.server session, change the session-length to a short value.
elixir.sso.server { ... # this controls how long the sso cookie remains active -- it should # be short if enforce-single-session is enabled, else the expired # embience session will be immediately and silently re-approved, # circumventing enforce-single-session session-length = 1 seconds ... } -
Restart the server for the single session to take effect.
Configure Server With Client Certificate And Local Extension
The following steps allow you to configure Ambience with HTTPS using a self-signed certificate. This example uses localhost as the server name.
Generate the Self-Signed Certificate and Keystore
- Open a terminal window and generate the certificate files. This example uses
qa.comas the domain name:openssl req -newkey rsa:4096 -keyout qa_key.pem -out qa_csr.pem -nodes -days 3650 -subj "/CN=qa.com" openssl x509 -req -in qa_csr.pem -signkey qa_key.pem -out qa_cert.pem -days 3650 openssl pkcs12 -export -in qa_cert.pem -inkey qa_key.pem -out qa.pkcs12This creates three files: -
qa_key.pem— the private key -qa_cert.pem— the self-signed certificate -qa.pkcs12— the keystore file (PKCS12 format) combining bothReplace
qawith your server name if using a different hostname.
Deploy the Keys
- Deploy the certificate files:
a. Add the certificate to your browser (Chrome, Firefox, etc.): - Import qa_cert.pem into your browser’s certificate store - For Chrome: Settings → Privacy and Security → Manage Certificates → Import
b. Copy the qa.pkcs12 file and rename it as truststore.pkcs12
c. Place the renamed file (truststore.pkcs12) in the Ambience etc/https/ directory
d. Copy/rename qa.pkcs12 as server-keystore.p12 and place it in the etc/https/ directory as well
Setup in application.conf
- Edit the
application.conffile in the “etc” folder and add/update the following configuration:## How browsers communicate with Ambience - this may be a load balancer external-protocol = "https:" external-host = "qa.com" external-port = 1740 ## How Ambience instances communicate internally - which may be a different (firewalled) IP range than the public (load balanced) name internal-protocol = "https:" internal-host = "qa.com" internal-port = 1740 ambience { systemId: "System" bindAddress: "0.0.0.0" bindPort: ${internal-port} https { enabled = true keystore = "https/server-keystore.p12" keystore-type = "PKCS12" keystore-password = "changeit" keystore-alias = "server" key-password = "changeit" client-auth = "require" truststore = "https/truststore.pkcs12" truststore-type = "PKCS12" truststore-password = "changeit" } }
Configure SimpleSSO with Local Extension (Optional)
- If using SimpleSSO with a local extension, modify the
application.conffile to change:from: token = ${sso-internal-server-baseurl}"/simple-sso/token" userinfo = ${sso-internal-server-baseurl}"/simple-sso/userinfo" to: token = "local" userinfo = "local"Skip this step if the local extension is not required.
Store Certificate in Secrets Module
- Add the certificate and private key to the Secrets module for secure management:
- Certificate name:
server-keystore.Certificate(use content of certificate file) - Private key name:
server-keystore.PrivateKey(use content of private key file)This enables secure storage and access to credentials within Ambience.
Start the Server
-
Start Ambience with the following run-server script or equivalent:
#!/bin/sh cd .. ## Define the path to your p12 files KEYSTORE_PATH="etc/https/server-keystore.p12" TRUSTSTORE_PATH="etc/https/truststore.pkcs12" PASS="changeit" OPTIONS="-Dvisualvm.display.name=Ambience \ -Djava.awt.headless=true \ -Dlogback.configurationFile=etc/logback.xml \ -Djavax.net.ssl.trustStore=$TRUSTSTORE_PATH \ -Djavax.net.ssl.trustStorePassword=$PASS \ -Djavax.net.ssl.trustStoreType=PKCS12 \ -Djavax.net.ssl.keyStore=$KEYSTORE_PATH \ -Djavax.net.ssl.keyStorePassword=$PASS" exec java $OPTIONS -jar elx-stub.jar ambience.module.Launcher -
Access Ambience via
https://qa.com:1740in your browser.
Setup Federated SSO
The following steps allows you to setup the Federated SSO to accept all users from Ambience and LDAP users.
-
In the application.conf file in the “bin” folder, edit the following lines:
ambience.modules.simple-sso.enabled = false ambience.modules.ldap-sso.enabled = false ambience.modules.federated-sso.enabled = true -
Add the following lines in the application.conf file:
elixir.federated-sso { order = ["a","b"] choices = { a { "type": "identity" "regex": ".*" } b { "type": "ldap" "regex": ".*" cxtFactory = "com.sun.ldap.LdapCtxFactory" host = "10.0.10.198" port = 389 protocol = "default" method = "simple" #users = "ou=amb_users,DC=elixir,DC=com,DC=sg" users = ["ou=<amb-user>", "ou=<bbc-user>"] uidAttribute = "sAMAccountName" mailAttribute = "userPrincipalName" connectTimeout = 10 seconds readTimeout = 10 seconds bind { user = "CN=Administrator,CN=Users,DC=elixir,DC=com,DC=sg" password = "{enc:elx-2.0}<password>=" } #groups { # enabled = true # root = "OU=amb_groups,DC=elixir,DC=com,DC=sg" # filter = "member=CN=${username},OU=amb_users,DC=elixir,DC=com,DC=sg" # gidAttribute = "sAMAccountName" #} groups: [{ enabled = true root = "OU=amb_groups,DC=elixir,DC=com,DC=sg" filter = "member=CN=${username},OU=amb_users,DC=elixir,DC=com,DC=sg" gidAttribute = "sAMAccountName" },{ enabled = true root = "OU=bbc_groups,DC=elixir,DC=com,DC=sg" filter = "member=CN=${username},OU=bbc_users,DC=elixir,DC=com,DC=sg" gidAttribute = "sAMAccountNAme" }] } elixir.sso.client.groups.matcher: "ambience.sso.client.DefaultGroupsNameMatcher" ambience.ldap-sso { paging { enabled: true size: 500 } } } } -
Restart the server. Login any Ambience user (for example, “admin” and “test”) and any LDAP user. All users are able to login.
-
Those lines in bold uses “.*”, which allows all users to be used.
-
To filter users, for example, allowing only users that contains “a”, edit the lines as such:
choices = { a { "type": "identity" "regex": ".a." } b { "type": "ldap" "regex": ".*" ... } } -
Restart the server. Login the same Ambience user (“admin” and “test”) again. This time, only “admin” is able to login. As for LDAP users, any user can login.