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.xml of 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 as authentication: composite in the production.yml of 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 get 401. The Context-User-ID header 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/configuration and the creation of the first user while no user exists. Keep /engine-rest internal anyway: Ingress only for /webapp, plus a NetworkPolicy.
  • Wrong passwords lock the user for a few seconds (login throttling).
  • Each request without an Authorization header logs the warning No authHeader provided!.
  • The chart applies composite at startup: it deploys the engine-rest WAR exploded, with a WEB-INF/web.xml generated from the WAR’s own web.xml, so it follows image upgrades. standalone.xml is not changed. This also works with your own (read-only) standalone.xml if you set wildfly.restAuthentication: composite explicitly.

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 plugins are replaced as a whole unless you use !list-add. !undefine removes 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 with externalEnv or secrets.env. A layer that contains secrets itself can be mounted from an existing Secret with volumes (see Secrets) or with secrets.files, and listed in wildfly.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.xml for 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.xml in secrets.files or configmaps.files. If you mount the file in another way, for example with volumes from an existing Secret, set wildfly.customStandaloneXml: true.

  • The chart then sets SKIP_DB_CONFIG: "true" and still provides DB_URL, DB_USERNAME and DB_PASSWORD. It renders none of its own layers (datasource, HTTPS listener, engine properties, production profile): configure them in the file. Proxy forwarding, your wildfly.configLayers and an explicitly set wildfly.restAuthentication: composite still apply. Without it, wildfly.restAuthentication defaults to pseudo.

  • Start from the standalone.xml of 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 ProcessEngine datasource 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 through configmaps.env, secrets.env or externalEnv.

  • 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

  • readOnlyRootFilesystem is not supported yet.
  • The image runs as UID 1000. On OpenShift, use a Security Context Constraint that allows this UID, for example nonroot-v2 or anyuid, see OpenShift.
  • The metrics port 9464 is only active with OTEL_AGENT_ENABLED=true (in configmaps.env).
  • Apart from application.spring.datasource.*, settings under application.* do not configure the WildFly engine.
  • Chart version 0.0.2 is tested with CIB seven 2.2.4-ee.

On this Page: