Configuration
Configuration
OpenL Studio keeps every setting in a single property namespace. The same setting can be changed in two ways:
- in the Administration area of the running application;
- in an
application.propertiesfile, before or between restarts.
This page explains where configuration is read from, how the two ways interact, and which property backs each field of the Administration area. What each setting actually means is described once, in Using Administration Tools — this page links to it instead of repeating it.
[!Note] Earlier versions of OpenL Studio configured the first launch through an Installation Wizard. The wizard has been removed. Prepare a new instance with an
application.propertiesfile, then refine the settings in the Administration area.
The following topics are included in this chapter:
- Where Settings Come From
- The Home Directory
- Property Reference by Administration Section
- Settings With No UI Field
- Configuration Examples
- Encrypting Passwords
- Cluster Mode Configuration
- Related Documentation
Where Settings Come From
Configuration Sources
Sources are listed from the highest priority to the lowest. A value found in a higher source wins.
- Servlet context initialization parameters, for example,
<context-param>inweb.xml. - JNDI attributes under
java:comp/env. - Java system properties, for example,
-Dopenl.home=/srv/openl. - Operating system environment variables.
- Settings saved in the Administration area.
application.propertiesfiles.- Built-in defaults shipped with the application.
[!Note] Java system properties and environment variables have a higher priority than the Administration area. A setting defined there is reapplied on every startup, and the corresponding field in the UI becomes read-only. Use these sources for values that must not be changed at runtime, such as credentials injected by a container.
Settings saved in the Administration area are not written back to application.properties. They are stored
separately, in ${openl.home.shared}/<application-name>.properties — for example, webstudio.properties — so an
application.properties file keeps only the values an administrator wrote by hand.
The two files are reset independently:
- Restore Defaults and Restart clears the values saved in the Administration area from
${openl.home.shared}/<application-name>.propertiesand restarts the instance. It never modifiesapplication.properties. - Deleting
application.propertiesdiscards only the values written there by hand. The instance then falls back to the settings saved in the Administration area and to the built-in defaults.
Environment Variables
An environment variable is recognized either as the exact property name or in upper case with dots and dashes replaced by underscores. A shell rejects a variable name that contains a dot, so export the upper-case form:
export OPENL_HOME=/srv/openl # sets openl.home
export USER_MODE=multi # sets user.mode
The exact property name still works where the environment can carry such a name, for example when it is passed by
env or set by a container runtime.
File Locations
An application.properties file is searched in the following locations, from the lowest priority to the highest:
classpath:andclasspath:config/- the working directory and its
conf/andconfig/subdirectories - the user home directory
A file in the user home directory therefore overrides a file in the working directory. Files for an active Spring
profile, such as application-prod.properties, override all non-profile files.
To search other locations or file names, redefine openl.config.location and openl.config.name. Both must be passed
as a Java system property or an environment variable, because they are resolved before any file is read.
The Generated Property Reference
A running instance publishes every known property with its effective default value at
/webstudio/application.properties, for example, http://localhost:8080/webstudio/application.properties. Most
properties also carry a description. Use it as the authoritative list for the installed version — it also includes
properties contributed by optional modules that this page does not cover.
The Home Directory
An instance keeps its data in the directory named by openl.home, which defaults to ${user.home}/.openl. On the
first launch the directory is created and populated automatically. Point it at a dedicated location rather than a
system drive:
openl.home = /srv/openl
Data that always belongs to this instance alone:
cache/— compiled projects. Safe to delete; it is rebuilt on demand.repositories/— local repository data and clones of remote repositories.users-db/— the embedded H2 user database used by the defaultdb.url.
Data that a cluster shares, written under openl.home.shared instead:
user-workspace/— local copies of the projects opened by users, together with their project history.locks/— locks held on projects and settings.repositories/settings/— settings saved in the Administration area and the project index,openl-projects.yaml.<application-name>.properties— the values saved in the Administration area, for example,webstudio.properties.notification.txt— the message broadcast from Managing Notifications.
openl.home.shared defaults to openl.home, so on a standalone instance both groups sit in the same directory. See
Cluster Mode Configuration.
Property Reference by Administration Section
System
Described in Managing System Settings.
| Section | Field | Property |
|---|---|---|
| Core | Dispatching Validation | dispatching.validation |
| Core | Verify on Edit | compile.auto |
| Testing | Thread Number for Tests | test.run.thread.count |
| Projects | Maximum count of saved changes per user | project.history.count |
| Projects | Detect projects by Excel files | project.detect-by-excel-files |
| Other | Update table properties | update.system.properties |
| Other | Date Format | data.format.date |
| Other | Time Format | data.format.time |
| Database Configuration | Database URL | db.url |
| Database Configuration | Login | db.user |
| Database Configuration | Password | db.password |
| Database Configuration | Maximum Pool Size | db.maximumPoolSize |
The following related properties have no field in the UI:
openl.home— working directory of the instance. The default value is${user.home}/.openl.openl.home.shared— directory shared between instances of a cluster. See Cluster Mode Configuration.user.workspace.home— directory that stores local copies of the projects opened by users.data.format.datetime— composed ofdata.format.dateanddata.format.time.admin.notification-file— file that stores the message sent from Managing Notifications.
Security
Described in Managing Security Settings.
The authentication mode is selected by user.mode:
| UI mode | user.mode value |
|---|---|
| Single-User | single |
| Multi-User | multi |
| Active Directory / LDAP | ad |
| SSO: SAML | saml |
| SSO: OIDC (OAuth2) | oauth2 |
Single-User
Applies when user.mode is single. See Configuring Single-User Mode.
| Field | Property |
|---|---|
| Username | security.single.username |
security.single.email |
|
| First Name | security.single.first-name |
| Last Name | security.single.last-name |
| Display Name | security.single.display-name |
Initial Users
Applies to all modes except single. See Configuring Initial Users.
| Field | Property |
|---|---|
| Administrators | security.administrators |
| Default Group | security.default-group |
| Permit creating and deleting projects | security.allow-project-create-delete |
| Allow Managers to bypass protected branches | security.allow-bypass-protected-branches |
Active Directory / LDAP
See Configuring Active Directory / LDAP Mode.
| Field | Property |
|---|---|
| Domain | security.ad.domain |
| Server URL | security.ad.server-url |
| User Filter | security.ad.search-filter |
| Group Filter | security.ad.group-filter |
SSO: SAML
See Configuring SSO: SAML Mode.
| Field | Property |
|---|---|
| Entity ID | security.saml.entity-id |
| Server Metadata URL | security.saml.saml-server-metadata-url |
| Remote Server Certificate | security.saml.server-certificate |
| Attribute for Username | security.saml.attribute.username |
| Attribute for First Name | security.saml.attribute.first-name |
| Attribute for Last Name | security.saml.attribute.last-name |
| Attribute for Display Name | security.saml.attribute.display-name |
| Attribute for Email | security.saml.attribute.email |
| Attribute for Groups | security.saml.attribute.groups |
The security.saml.forceAuthN property additionally controls whether the identity provider must force a user to
reauthenticate. All SAML attribute names are case-sensitive.
SSO: OIDC (OAuth2)
See Configuring SSO: OIDC (OAuth2) Mode.
| Field | Property |
|---|---|
| Client ID | security.oauth2.client-id |
| Client Secret | security.oauth2.client-secret |
| Issuer URI | security.oauth2.issuer-uri |
| Scope | security.oauth2.scope |
| Attribute for Username | security.oauth2.attribute.username |
| Attribute for First Name | security.oauth2.attribute.first-name |
| Attribute for Last Name | security.oauth2.attribute.last-name |
| Attribute for Display Name | security.oauth2.attribute.display-name |
| Attribute for Email | security.oauth2.attribute.email |
| Attribute for Groups | security.oauth2.attribute.groups |
All OAuth2 claim names are case-sensitive.
Repositories
Described in Managing Repository Settings.
Each repository has an identifier that is used as a property prefix:
design-repository-configs— comma-separated identifiers of the repositories on the Design Repositories tab.production-repository-configs— comma-separated identifiers of the repositories on the Deployment Repositories tab.
Settings of a repository are then defined as repository.<id>.*. Identifiers are arbitrary; design and production
are the conventional defaults.
The Type field is set by repository.<id>.$ref, which points at the block of defaults for that type:
| Type | repository.<id>.$ref value |
|---|---|
| Git | repo-git |
| Database JDBC | repo-jdbc |
| Database JNDI | repo-jndi |
| AWS S3 | repo-aws-s3 |
| Azure Blob Storage | repo-azure-blob |
A $ref sets up inheritance: any repository.<id>.<suffix> left undefined falls back to <ref>.<suffix>. Defining
repository.design.$ref = repo-git and then only repository.design.uri is enough — the remaining Git settings come
from the repo-git.* defaults. The same mechanism lets repo-git.* and repo-default.* set values shared by every
repository of a kind.
Settings Common to All Types
| Field | Property suffix |
|---|---|
| Name | .name |
| Path | .base.path |
| Deployment branch | .deploy-from-branch |
The Deployment branch field applies to deployment repositories only: an empty value means Any branch, and
MAIN_BRANCH means Main branch only.
Git
See Managing Git Repository Settings.
| Field | Property suffix |
|---|---|
| URL | .uri |
| Login | .login |
| Password | .password |
| Branch | .branch |
| Protected branches | .protected-branches |
| Changes check interval | .listener-timer-period |
| Connection timeout | .connection-timeout |
| Default branch name | .new-branch.pattern |
| Branch name pattern | .new-branch.regex |
| Invalid branch name message hint | .new-branch.regex-error |
Retry behavior after a failed authentication is controlled by .failed-authentication-seconds and
.max-authentication-attempts. The location of cloned remote repositories is controlled by
repo-git.local-repositories-folder, which has no field in the UI.
Database JDBC and Database JNDI
| Field | Property suffix |
|---|---|
| URL | .uri |
| Login | .login |
| Password | .password |
For Database JNDI, the URL is the datasource name in the JNDI context, such as java:comp/env/jdbc/DB.
The Secure connection check box has no property of its own. It is derived from Login: the check box appears
selected whenever a login is defined, and clearing it erases the stored .login and .password.
Despite its name the check box selects database authentication, not transport security. With a login the repository
opens its connections through the credentialed call — getConnection(uri, login, password) for Database JDBC and
getConnection(login, password) on the datasource for Database JNDI — and without one through the plain call that
takes no credentials. Encrypting the connection itself is configured elsewhere: in the JDBC URL through a
driver-specific parameter such as sslmode for PostgreSQL, in the driver, or in the JNDI datasource definition.
AWS S3
| Field | Property suffix |
|---|---|
| Service endpoint | .service-endpoint |
| Bucket name | .bucket-name |
| Region name | .region-name |
| Access key | .access-key |
| Secret key | .secret-key |
| Listener period | .listener-timer-period |
| SSE algorithm | .sse-algorithm |
Azure Blob Storage
| Field | Property suffix |
|---|---|
| URL | .uri |
| Listener timer period (sec) | .listener-timer-period |
The credentials of the storage account have no fields in the UI, so a repository that authenticates with a shared key
is configured in application.properties. See
Azure Blob Storage Credentials.
Commit Comments
Applies to Git design repositories. See Customizing Git Commit Comments.
| Field | Property suffix |
|---|---|
| Customize comments | .comment-template.use-custom-comments |
| User message pattern | .comment-template.comment-validation-pattern |
| Invalid user message hint | .comment-template.invalid-comment-message |
| Save project | .comment-template.user-message.default.save |
| Create project | .comment-template.user-message.default.create |
| Copy project | .comment-template.user-message.default.copied-from |
| Restore from old version | .comment-template.user-message.default.restored-from |
A Git repository stores the resulting comment directly as the commit message; there is no separate message template to configure.
Email Server
Described in Managing Email Server Configuration.
| Field | Property |
|---|---|
| URL | mail.url |
| Username | mail.username |
| Password | mail.password |
Email address verification is active while these three properties hold valid values.
Settings With No UI Field
These are set in application.properties only.
Azure Blob Storage Credentials
An Azure Blob Storage repository authenticates with the access key of a storage account. Both settings take the
repository identifier as a prefix, like every other repository.<id>.* setting:
.account-name— name of the storage account..account-key— access key of that account. Store it encrypted, as described in Encrypting Passwords.
The key is used only when the account name has a value. With both left empty, the repository connects with whatever authorization the URL itself carries, such as an appended shared access signature, and anonymously when the URL carries none:
production-repository-configs = production
repository.production.name = Deployment
repository.production.$ref = repo-azure-blob
repository.production.uri = https://openlrules.blob.core.windows.net/deploy
repository.production.account-name = openlrules
repository.production.account-key = ENC(yZaBcDeFgHiJkLmNoPqR==)
repository.production.listener-timer-period = 10
Cross-Origin Requests
Needed when a browser application served from another origin calls the OpenL Studio REST API. No value for
cors.allowed.origins means the API cannot be called cross-origin at all.
| Property | Description |
|---|---|
cors.allowed.origins |
Comma-separated allowed origins. An asterisk allows any origin. |
cors.allowed.methods |
Comma-separated allowed HTTP methods. |
cors.allowed.headers |
Comma-separated allowed request headers. |
cors.preflight.maxage |
Seconds a browser may cache a pre-flight response. |
cors.allowed.origins = https://apps.example.com
cors.allowed.methods = GET,OPTIONS,HEAD,PUT,POST
cors.allowed.headers = Content-Type,Accept,api_key,Authorization
cors.preflight.maxage = 7200
Password Hashing
In Multi-User mode, webstudio.bcrypt.strength sets the bcrypt cost applied to stored passwords. Permitted values are
4 to 31, and the default is 10. Each increment doubles the hashing work, so raise it in small steps and measure login
time.
Migration Attribution
When an upgrade requires OpenL Studio to change project files in a repository, the commits are attributed to this identity:
migration.user.name = Studio Migration
migration.user.email = openltablets@eisgroup.com
Set them to a recognizable service identity so that such commits are distinguishable from users’ commits in the repository history.
UI Extension
webstudio.javascript.url loads an external JavaScript file together with OpenL Studio, which is the extension point
for integrating an external tool:
webstudio.javascript.url = https://example.com/extension.js
Configuration Examples
Single-User Development Setup
A local instance with no login and a Git repository in the file system:
openl.home = /srv/openl
user.mode = single
security.single.username = developer
security.single.email = developer@example.com
security.single.display-name = Local Developer
design-repository-configs = design
repository.design.name = Design
repository.design.$ref = repo-git
repository.design.uri = ${openl.home}/repositories/design
Team Setup with a Remote Git Repository
Database-backed accounts, an administrator, a read-only baseline group, and a remote Git design repository:
user.mode = multi
db.url = jdbc:postgresql://db.example.com:5432/openl_studio
db.user = openl
db.password = ENC(9J0k1LmNoPqRsTuVwXyZ==)
security.administrators = jsmith
security.default-group = Viewers
design-repository-configs = design
repository.design.name = Design
repository.design.$ref = repo-git
repository.design.uri = https://git.example.com/rules/design.git
repository.design.login = openl-service
repository.design.password = ENC(aBcDeFgHiJkLmNoPqRsT==)
repository.design.branch = main
repository.design.protected-branches = main, release/*
repository.design.base.path = rules/
repository.design.connection-timeout = 60
repository.design.listener-timer-period = 10
Deployment Repository in AWS S3
production-repository-configs = production
repository.production.name = Deployment
repository.production.$ref = repo-aws-s3
repository.production.bucket-name = openl-rules-prod
repository.production.region-name = eu-central-1
repository.production.access-key = AKIAIOSFODNN7EXAMPLE
repository.production.secret-key = ENC(uVwXyZaBcDeFgHiJkLmN==)
repository.production.base.path = deploy/
repository.production.deploy-from-branch = MAIN_BRANCH
Leave the access and secret keys empty to let the AWS SDK resolve credentials from the environment, an instance profile, or another standard location.
Two Design Repositories
Identifiers are arbitrary, so several repositories of different types can coexist:
design-repository-configs = design, archive
repository.design.name = Design
repository.design.$ref = repo-git
repository.design.uri = https://git.example.com/rules/design.git
repository.archive.name = Archive
repository.archive.$ref = repo-jdbc
repository.archive.uri = jdbc:postgresql://db.example.com:5432/openl_archive
repository.archive.login = openl
repository.archive.password = ENC(kLmNoPqRsTuVwXyZaBcD==)
Active Directory Authentication
user.mode = ad
security.ad.domain = example.com
security.ad.server-url = ldaps://ad.example.com:3269
security.ad.search-filter = (&(objectClass=user)(userPrincipalName={0}))
security.ad.group-filter = (&(objectClass=group)(member:1.2.840.113556.1.4.1941:={2}))
security.administrators = jsmith
security.default-group = Viewers
A login sends the user’s password to the server named by security.ad.server-url, so use the ldaps:// scheme — over
plain ldap:// the password crosses the network unencrypted. The ports differ as well: 3269 for the encrypted global
catalog against 3268 for the plain one, or 636 against 389 for a single domain controller.
An ldaps:// connection is only as good as the certificate check behind it, and that check is the JVM’s: the
certificate of the domain controller, or the CA that issued it, has to be present in the truststore of the JVM that
runs OpenL Studio. Without it every login fails with PKIX path building failed. Import the certificate with
keytool -import -trustcacerts, or point the instance at a prepared truststore through javax.net.ssl.trustStore.
OIDC Authentication
user.mode = oauth2
security.oauth2.client-id = openl-studio
security.oauth2.client-secret = ENC(oPqRsTuVwXyZaBcDeFgH==)
security.oauth2.issuer-uri = https://login.example.com/realms/openl
security.oauth2.scope = openid,profile,email
security.oauth2.attribute.username = preferred_username
security.oauth2.attribute.groups = groups
security.administrators = jsmith
Encrypting Passwords
Any property value, not only a password, can be stored encrypted. Define a master password in secret.key and wrap the
encrypted value in ENC(...):
secret.key = MyMasterPassword
db.password = ENC(AP7hs0n88JJMcFlV/7VQTg==)
The value inside ENC(...) is Base64, so it cannot be invented — the example above is the password MyDbPassword
encrypted with the secret.key shown next to it. Produce your own value as described at the end of this section.
Keep secret.key out of application.properties in a shared environment — pass it as a Java system property or an
environment variable instead. Quote the value if it contains spaces or shell metacharacters, so that
-Dsecret.key=... reaches the application intact.
secret.key also protects the passwords that the Administration area saves. When a repository, database, or mail
password is entered in the UI, it is stored as ENC(...) in the settings file, encrypted with the current
secret.key.
[!Note] Define
secret.keybefore creating any connection that stores a password. Passwords saved whilesecret.keywas blank are stored as plain text, and passwords saved under a differentsecret.keydecode to an empty value once the key changes — the affected connections then fail to authenticate and their passwords have to be entered again.
To produce an encrypted value on Linux, substituting the secret.key value for MyMasterPassword:
echo -n "plain password" \
| openssl aes-128-cbc \
-K $(echo -n "MyMasterPassword" | sha1sum | awk '{ print substr($1, 1, 32) }') \
-e \
-iv 00000000000000000000000000000000 \
-base64 \
| awk '{ print "ENC("$1")" }'
The value passed to -K is the first 32 characters of the SHA-1 hash of secret.key. On macOS, use shasum instead
of sha1sum. The encoding cipher is configurable through secret.cipher.
Cluster Mode Configuration
Several OpenL Studio instances can share a workload. Each instance keeps its own openl.home for local data and
reads shared state from openl.home.shared, which must resolve to the same mounted directory on every instance:
openl.home = /srv/openl
openl.home.shared = /mnt/openl-shared
openl.home.shared defaults to openl.home, which is why a standalone instance needs no extra configuration.
Configure it before the first launch. Setting it on an instance that already holds data leaves that data behind in the old location and requires moving it manually.
What Moves to the Shared Directory
- Administration settings — every instance reads the same
<application-name>.properties, so a change applied in one instance’s Administration area takes effect everywhere. The passwords in that file are stored asENC(...), so every instance needs the samesecret.key: an instance configured with a different key reads such a password as an empty value. Changing the key therefore means changing it on all instances together and re-entering the affected passwords afterwards, which saves them encrypted with the new key. - User workspace and project history — users see the same open projects and history on whichever instance serves them.
- Locks — an instance sees projects locked by users on other instances.
- Project index and the broadcast notification.
What Stays Local
The compiled-projects cache and the repository clones stay under openl.home on each instance.
[!Note] The defaults for the user database (
db.url) and for repositories also point insideopenl.home, not insideopenl.home.shared. Settingopenl.home.sharedalone therefore leaves every instance with its own users and its own project storage. A cluster must additionally pointdb.urlat an external database and configure the design and deployment repositories to remote storage such as Git, a database, AWS S3, or Azure Blob Storage.
Put a load balancer in front of the instances and enable sticky sessions.
Related Documentation
- Using Administration Tools — what each setting means
- Quick Start Installation — first installation steps
- Rule Services — configuring Rule Services
- Integration — connecting OpenL Studio with Rule Services
- Troubleshooting — common installation issues