Configure the WildFly Distribution
This page describes the settings of the Helm chart cibseven-ee (version 0.0.2) for the WildFly distribution (image.distribution: wildfly). The general settings, such as database, Secrets, TLS and exposure, are described in Configure the Helm Chart.
How WildFly Is Configured
WildFly does not read the Spring Boot properties rendered from application.*. Settings such as application.camunda.bpm.* (history level, authorization, administrator, generic properties) have no effect here. Only application.spring.datasource.* is used, for the database. WildFly and the process engine are configured in /camunda/standalone/configuration/standalone.xml. The chart offers two ways to work with this file:
- Chart-managed (default): the chart keeps the
standalone.xmlof the image and applies its settings at startup as WildFly YAML configuration layers, without changing the file: datasource, HTTPS listener, engine properties, production profile and your own layers. Upgrades of the image keep working without merging an XML file again, and the file may be read-only. - Your own complete standalone.xml: full control over every WildFly and engine setting. The chart does not change the file, see Your Own Complete standalone.xml.
A complete example is part of the chart package: values-example-wildfly.yaml, layered on top of values-example.yaml, and values-production-wildfly.yaml as a starting point for production:
helm install cibseven cibseven-ee/cibseven-ee --version 0.0.2 -n cibseven \
-f values-example.yaml -f values-example-wildfly.yaml -f values-production-wildfly.yaml
values-production-wildfly.yaml takes the database password and the JWT secret from existing Secrets, terminates TLS in the pod, exposes only /webapp (Ingress or OpenShift Route), adds a NetworkPolicy that admits only the ingress controller or router, and sets resources. Replace every <placeholder> before you install.
Production Profile
The production profile wildfly.production.enabled: true (default) applies the settings of the Security Instructions that the production configuration of CIB seven Run (production.yml) applies, as far as they concern WildFly. Each item can be switched off on its own:
| Setting | Effect | Switch off |
|---|---|---|
Engine property enablePasswordPolicy=true |
New passwords need at least 10 characters with upper case, lower case, digit and special character, and must not contain the user data, see Password Policy. This also applies to the first administrator. | wildfly.production.engineProperties.enablePasswordPolicy: null |
Engine property deserializationTypeValidationEnabled=true |
Object variables are only deserialized for allowed types, see Variable Values from Untrusted Sources. Allow your own classes with deserializationAllowedPackages or deserializationAllowedClasses under wildfly.production.engineProperties. |
wildfly.production.engineProperties.deserializationTypeValidationEnabled: null |
| HSTS | Strict-Transport-Security: max-age=31536000; includeSubDomains on HTTPS requests: with TLS in the pod, or with TLS at the ingress controller or router (X-Forwarded-Proto: https). Not on plain HTTP. The value can be changed with wildfly.production.hsts.value. |
wildfly.production.hsts.enabled: false |
| Session cookie | Session cookies are Secure and HttpOnly by default. The webclient (/webapp) works with tokens and sets no session cookie; the applications under /camunda configure their own cookie (HttpOnly). |
wildfly.production.sessionCookie.secure: false, wildfly.production.sessionCookie.httpOnly: false |
| Management interface | The WildFly management interface (port 9990) listens on 127.0.0.1 only. jboss-cli.sh inside the container still works. |
wildfly.production.managementLoopback: false |
| REST API authentication | /engine-rest requires the token of the webclient or HTTP Basic credentials, see REST API Authentication. |
wildfly.restAuthentication: pseudo |
The standalone.xml of the image already enables authorization (authorizationEnabled=true), the cron type QUARTZ with the legacy syntax and the namespace flags. The engine properties of the profile are merged with wildfly.engine.properties into one complete map, see Engine Properties.
For example, to allow the deserialization of your own classes:
wildfly:
production:
engineProperties:
# comma-separated packages or classes that may be deserialized from variables
deserializationAllowedPackages: "com.example.model"
With your own standalone.xml, the production profile is not applied, see Your Own Complete standalone.xml.
REST API Authentication
wildfly.restAuthentication controls the authentication of the REST API /engine-rest:
composite(default with the production profile; the same asauthentication: compositein theproduction.ymlof CIB seven Run): a request needs either the login token of the webclient (Authorization: Bearer …) or HTTP Basic credentials of an engine user. Requests without credentials get401. TheContext-User-IDheader alone is not accepted. See Composite Authentication.pseudo(default of the image, and of the chart without the production profile): no authentication. Keep the REST API internal in this case.
The webclient keeps working unchanged: it sends the token of the logged-in user, and the REST API checks it with the same JWT secret (global.authentication.jwtSecret or the environment variable CIBSEVEN_WEBCLIENT_AUTHENTICATION_JWTSECRET). The applications under /camunda use their own API and are not affected.
Your own REST clients, for example other applications or external task workers, must send HTTP Basic credentials of a technical user. Authorization is enabled, so grant this user the authorizations it needs.
curl -u <user>:<password> \
https://<release>-cibseven-ee.<namespace>.svc:8443/engine-rest/engine/default/process-definition/count
- A few endpoints answer without credentials by design, for example
GET /engine-rest/engine,/engine-rest/configurationand the creation of the first user while no user exists. Keep/engine-restinternal anyway: Ingress only for/webapp, plus a NetworkPolicy. - Wrong passwords lock the user for a few seconds (login throttling).
- Each request without an
Authorizationheader logs the warningNo authHeader provided!. - The chart applies
compositeat startup: it deploys the engine-rest WAR exploded, with aWEB-INF/web.xmlgenerated from the WAR’s ownweb.xml, so it follows image upgrades.standalone.xmlis not changed. This also works with your own (read-only)standalone.xmlif you setwildfly.restAuthentication: compositeexplicitly.
Your Own Configuration with YAML Layers
Settings that the chart does not cover are added as WildFly YAML configuration layers (standalone.sh --yaml). wildfly.configLayers is a map of names to YAML documents that start with wildfly-configuration:. The chart applies its own layers first (10-cib-production.yml, 20-chart.yml), then yours in the order of their names, then the files listed in wildfly.configLayerFiles. Later layers win. standalone.xml is not changed, so layers also work with a read-only file and with your own standalone.xml.
The following example raises a log level and adds the LDAP Identity Provider Plugin and the Administrator Authorization Plugin. The manager password comes from an existing Secret:
wildfly:
configLayers:
50-logging: |
wildfly-configuration:
subsystem:
logging:
logger:
org.cibseven:
level: DEBUG
60-identity: |
wildfly-configuration:
subsystem:
camunda-bpm-platform:
process-engines:
default:
plugins: !list-add
- class: org.cibseven.bpm.identity.impl.ldap.plugin.LdapIdentityProviderPlugin
properties:
serverUrl: ldaps://ldap.example.org/
managerDn: cn=svc-cibseven,dc=example,dc=org
managerPassword: ${env.LDAP_MANAGER_PASSWORD}
baseDn: dc=example,dc=org
- class: org.cibseven.bpm.engine.impl.plugin.AdministratorAuthorizationPlugin
properties:
administratorUserName: <user id of the LDAP administrator>
externalEnv:
LDAP_MANAGER_PASSWORD:
secretKeyRef:
name: ldap-manager
key: password
# CA of the LDAPS server
certificates:
truststore:
enabled: true
secretName: ldaps-ca
secretKey: ca.pem
Add the user and group search settings of your directory as further properties of the LDAP plugin, see Configuration Properties of the LDAP Plugin. Do not add empty properties: they become “undefined”. AdministratorAuthorizationPlugin takes one user name; add one plugin per administrator.
Rules for layers:
- Lists such as
pluginsare replaced as a whole unless you use!list-add.!undefineremoves an attribute. Attributes of the chart’s layers can be overridden, for example the value of the HSTS header. - Passwords: use
${env.NAME}and provide the variable withexternalEnvorsecrets.env. A layer that contains secrets itself can be mounted from an existing Secret withvolumes(see Secrets) or withsecrets.files, and listed inwildfly.configLayerFiles. - Templates: the chart evaluates templates in values. Write a literal
{{as{\{. - Names of layers consist of letters, digits,
.,_and-. - YAML layers cannot add deployments, deployment overlays, extensions or paths. Use your own
standalone.xmlfor those. - An invalid layer or an unknown resource stops the container. The startup log lists the active layers (
cibseven-ee chart: WildFly configuration layers …).
Engine Properties
Set properties of the process engine default with wildfly.engine.properties, not in a layer. Change or add single keys; remove one with null. The defaults are the properties of the standalone.xml of the image:
wildfly:
engine:
properties:
historyCleanupBatchWindowStartTime: "02:00"
A layer replaces the whole properties map. One key there would drop all other properties, including authorizationEnabled. That is why the chart renders the complete map (properties of the image, production profile, your keys) in its layer 20-chart.yml, and stops the installation with an error if a layer in wildfly.configLayers sets process-engines.default.properties. Files in wildfly.configLayerFiles are not checked.
Your Own Complete standalone.xml
For full control over every WildFly and engine setting (datasources, engine properties, plugins, job executor, LDAP identity provider and so on), mount your own complete standalone.xml, for example with secrets.files:
secrets:
files:
standalone.xml:
path: /camunda/standalone/configuration/standalone.xml
value: |-
<?xml version="1.0" encoding="UTF-8"?>
...
With plain Helm the file can also be passed with --set-file 'secrets.files.standalone\.xml.value=./standalone.xml'; path still has to be set in a values file.
-
The chart detects the key
standalone.xmlinsecrets.filesorconfigmaps.files. If you mount the file in another way, for example withvolumesfrom an existing Secret, setwildfly.customStandaloneXml: true. -
The chart then sets
SKIP_DB_CONFIG: "true"and still providesDB_URL,DB_USERNAMEandDB_PASSWORD. It renders none of its own layers (datasource, HTTPS listener, engine properties, production profile): configure them in the file. Proxy forwarding, yourwildfly.configLayersand an explicitly setwildfly.restAuthentication: compositestill apply. Without it,wildfly.restAuthenticationdefaults topseudo. -
Start from the
standalone.xmlof the image you deploy. The file differs between image versions, so check it again whenever CIB seven or WildFly is upgraded:docker create --name cibseven-tmp artifacts.cibseven.org/docker-ee/cibseven:wildfly-2.2.4-ee docker cp cibseven-tmp:/camunda/standalone/configuration/standalone.xml . docker rm cibseven-tmp -
For PostgreSQL, typically only the
ProcessEnginedatasource changes: set<driver>postgresql</driver>, the connection URL and the credentials. -
Keep credentials out of the file with WildFly expressions, for example
<connection-url>${env.DB_URL}</connection-url>and<security user-name="${env.DB_USERNAME}" password="${env.DB_PASSWORD}"/>, and provide them throughconfigmaps.env,secrets.envorexternalEnv. -
Write a literal
{{in the file as{\{.
The settings that the chart would otherwise apply look like this in standalone.xml (with certificates.keystore enabled):
<!-- subsystem undertow, server default-server -->
<http-listener name="default" socket-binding="http" redirect-socket="https" enable-http2="true" proxy-address-forwarding="true"/>
<https-listener name="https" socket-binding="https" ssl-context="applicationSSC" enable-http2="true" proxy-address-forwarding="true"/>
<!-- subsystem elytron, tls -->
<key-store name="applicationKS">
<credential-reference clear-text="${env.KEYSTORE_PASSWORD}"/>
<implementation type="PKCS12"/>
<file path="/camunda/tls/keystore.p12"/>
</key-store>
<key-manager name="applicationKM" key-store="applicationKS">
<credential-reference clear-text="${env.KEYSTORE_PASSWORD}"/>
</key-manager>
<server-ssl-context name="applicationSSC" cipher-suite-names="TLS_AES_256_GCM_SHA384:TLS_AES_128_GCM_SHA256:TLS_CHACHA20_POLY1305_SHA256" protocols="TLSv1.3 TLSv1.2" key-manager="applicationKM"/>
The equivalents of the production profile:
<!-- subsystem urn:org.cibseven.bpm.jboss:1.1, process-engine "default", <properties> -->
<property name="enablePasswordPolicy">true</property>
<property name="deserializationTypeValidationEnabled">true</property>
<!-- subsystem urn:jboss:domain:undertow -->
<host name="default-host" alias="localhost">
...
<filter-ref name="cibseven-hsts" predicate="equals(%{SCHEME}, 'https')"/>
</host>
<servlet-container name="default">
...
<session-cookie http-only="true" secure="true"/>
</servlet-container>
<filters>
<response-header name="cibseven-hsts" header-name="Strict-Transport-Security" header-value="max-age=31536000; includeSubDomains"/>
</filters>
<!-- interfaces -->
<interface name="management">
<inet-address value="127.0.0.1"/>
</interface>
LDAP and additional administrators are plugins of the process engine (subsystem urn:org.cibseven.bpm.jboss:1.1, inside <plugins>, after the default plugins), see LDAP in the configuration of the JBoss EAP/WildFly distribution. Use certificates.truststore for the CA of an LDAPS server.
Example Application and First Administrator
wildfly.deployExamples: false (default) removes the invoice example application of the image. Without it, no demo users exist. With true and without LDAP, the example creates demo users, including demo/demo with administrator rights; do not use this in production.
Without LDAP, create the first administrator once while no user exists:
kubectl -n cibseven port-forward svc/cibseven-cibseven-ee 8080:8080
# open http://localhost:8080/camunda/app/admin/default/setup/ and create the user
The user becomes a member of camunda-admin and can log in at /webapp/. The setup page is refused as soon as a user exists. See also Initial User Setup.
With LDAP, grant administrator rights to a user of your directory with the Administrator Authorization Plugin, see Your Own Configuration with YAML Layers.
Behind an Ingress Controller or Router
wildfly.proxyAddressForwarding: true (default) makes WildFly honour the headers X-Forwarded-Proto, -Host, -Port and -For. Without it, WildFly redirects /webapp to http://…/webapp/ when TLS ends in front of it. The chart sets this with WildFly environment overrides (WILDFLY_OVERRIDING_ENV_VARS), which also apply to your own standalone.xml.
Proxy forwarding trusts the X-Forwarded-* headers of every client that reaches the pod. Restrict ports 8080 and 8443 to your ingress controller or router with a NetworkPolicy.
Limitations
readOnlyRootFilesystemis not supported yet.- The image runs as UID 1000. On OpenShift, use a Security Context Constraint that allows this UID, for example
nonroot-v2oranyuid, see OpenShift. - The metrics port 9464 is only active with
OTEL_AGENT_ENABLED=true(inconfigmaps.env). - Apart from
application.spring.datasource.*, settings underapplication.*do not configure the WildFly engine. - Chart version
0.0.2is tested with CIB seven2.2.4-ee.